MySQL database schema for user and group access control - mysql

I've been trying to find a solution to this problem for a couple of days now and I just can't seem to come up with something that works. The problem is the following:
I am currently developing a statistics tool that shows some graphs and data for several applications. The access to this data obviously needs to be restricted, as User A owns applications "One" and "Two" and must not see "Three" or "Four".
Now, each user can be member of multiple groups and inherit permissions from this group, but also can have individual permissions. These permissions have to be set for each application. Access to a set of data of one application is granted if:
The user himself has the permission to access this piece of data of this application
Any one of the groups the user is member of has the permission to access this piece of data of this application
The goal is to have a table that stores the actual permissions each user currently has for every application, computed from the group memberships and individual permissions and have that information be consistent at all times due to the relations to other tables.
I don't know if this helps to find a solution, but here's the SQL to get the currently active permissions of the user with id 1:
(
SELECT u.perm_id AS perm, u.user_id AS uid, u.app_id AS app
FROM daUsers_has_daPermissions AS u
WHERE u.user_id = 1
)
UNION
(
SELECT g.perm_id AS perm, u.user_id AS uid, g.app_id AS app
FROM daUsers_has_daPermissions AS u, daUsergroup_has_daPermissions AS g, daUsergroup_has_daUsers AS g_has_u
WHERE u.user_id = 1
AND u.user_id = g_has_u.user_id
AND g.group_id = g_has_u.group_id
);
This is what I want to store in an extra table (just for all users).

Sounds to me you should use a view. You already have the query, use the query to create a view.

Related

Creating a Whatsapp like model in Rails Framework.

Background: I am new to Rails and I have gone through Michael Hartl Ruby on Rails tutorial.
I have read Agile Web Development with Rails 5.
So for practice I was trying to design WhatsApp like framework and got stuck while creating User and Group model.
Problem: I have tried different user and group model relationship and each one is failing for some reason.I have tried few paths so I will enlist them below.I don't need code, just a correct database relationship between User,Admin,Group,Participants.Also we should be able to add relationship through UI.
We have two tables User and Group.Admin belongs_to Group.Group has_many Admins. Group has_many partcipants. Participant belongs_to group.Participant is a new table having user_id and group_id.
We have three tables User,Group and Admin_Participant.Admin_Participant table contains admin_of column and participant_of column and one user_id column.admin_of and participant_of will contain group_ids.
Similar to first but we have a different table for admin which contains user_id , group_id, boolean table for is_admin.
Group is reference to User and admin column is boolean.Participant is added to User table and is also a boolean.
One more Thing As soon as a user creates group he is assigned to be admin of that group.Remember the restrictions of participants.
3 tables ( and their models ) should suffice.
User
has many participants
has many groups through participants
Group
attribute: created_by ( user id )
has many participants
has many users through participant
Participant
belongs to group
belongs to user
attribute admin
The above should work provided that an admin is also a participant.
If there are admins who are not participants, then a extra column for 'participating', or 'non-participant' is required.
There is no need for an admin table unless the admin has other attributes.
In case you haven't, it's good to go through the guide
So this might be too far down the rabbit hole but I see only 2 tables, User and Groups. A user can be a admin and/or participant. The relationship between user and group would probably be has_or_belongs_to_many as a user can belong to many groups and a group can have many users. Further, to accomplish the user/admin/participant distinction, I might even subclass it with STI(single table inheritance) instead of using booleans to determine if someone is an admin or not.
as you specified you need a relationship model not code.
i think i can help.
you might have to reshape your whole database, but if i were you, i would do it like ...
User - name , user_id , mob_no , groups (before someone need to log in , my app would send em the code through which they can verify that they are the owner of that mob no. //we would not discuss that in detail/// )
######## has_many: groups
group - name , users , admin(boolean) (i made a different column for admin, the users column stores the user_id of the user , when someone creates a group he automatically becomes the admin , so admin column becomes true for that user id.. and later that admin can make other admin as well...[if you have problem implementing this i would suggest opening up michael hartl's book and read how he made an example user an admin and that admin could delete other users , that will help])
########## belongs_to: user
i do not understand how you would implement the admin of a group to add users to group,
so in this case i would like to suggest the following -
$ if the user has followed another user he can add that user to the group...
$ or a facebook like system " where user gets users invite to the group ,and later its upon him to decide whether he want to join or not.
% pls comment and lemme know if this helps. and any other suggestion.

SSRS - Users Table

I have done some digging but am unable to find out specific information about the Users table that is created in the ReportServer database?
Firstly I wanted to check what was the point of entry for users going into this table? In our table it looks like virtually ALL our domain logins exist in this table... Which leads me to the next question... Are these actually linked to the domain accounts at all (I presume not). I just want to make sure that if a domain account is disabled that any subscriptions 'Owned' by that user will not fail on the next run attempt.
Any help on this relatively dark area is greatly appreciated.
Regards
Chris
Before answering let me remind you that the SSRS database is not officially documented, so the following answers are only be based on my experience of the product so they can be wrong / incomplete.
what was the point of entry for users going into this table?
The GetUserIDBySid and GetUserIDByName stored procedures, called by the GetUserID stored procedure.
The GetPrincipalID stored procedure, called by the UpdatePolicyPrincipal stored procedure.
The name can be confusing, because in fact these SPs are not only getting the User ID.
If the user does not exist in the database, they insert it.
Now an additional question should come up:
When are these SPs executed?
The obvious answer is "when SSRS needs to get the User ID".
This can be, for example, when:
Creating a policy for that specific user
The user execute a report
The user schedules a subscription
If the user is part of a group that has access to a report and has never done any action needing to get his User ID, he should not be present in the Users table.
Are these actually linked to the domain accounts at all
No, if you delete the account from your AD it will stay in the Users table.
The information that you can use if you need to link them for whatever reason are:
The User Login: UserName
The Security ID: Sid
Bonus question/answer:
What information does the Users table contains?
UserID: A generated GUID (NEWID())
Sid: The Security ID, if you need to find the Security ID from the User Login, you can use the SUSER_SID function
UserType: The UserType
AuthType: The LoginType
UserName: The NT User / Group login
Here is an excerpt from an article:
Users: This table contains details about access details for users of the report server including those users running the reports and those users publishing the reports.
SSRS keeps its own table of users and groups associated with its security, so even if the user account has been deleted from your Active Directory system, it will be available for you to reference inside the ReportServer database
This query below will show you to which report each user has access to:
SELECT u.UserName, r.RoleName, c.Path, c.Name
FROM dbo.Users as u
INNER JOIN dbo.PolicyUserRole as pr ON u.UserID=pr.UserID
INNER JOIN dbo.Roles as r on pr.RoleID = r.RoleID
INNER JOIN dbo.Catalog as c on pr.PolicyID = c.PolicyID
ORDER BY u.UserName

sql - normalize user table with it groups but both can login

Hi currently i have 3 tables:
users
|id|name|email|password|last_login|created_at|
user_groups
|user_id|group_id
groups
|group_id|name|email|password|last_login|created_at|
Group can login so it when i can view statistics for specific all it users, that's why i put email and password too.
the problem is users and groups got almost everything same. 1 group can contain many users.
Is there anyway to make this more normalize and user still have their specific groups?
I would just use the user authentication to detect whether the user belongs to any group or not. That way you don't need all these extra fields for the group.
If you only want one specific user to be able to look at the group statistics you could add an admin_id to the user_groups table (which would relate to a user id)

How to change custom fields sql query on redmine

I use zapier to send sms to users when a new issue is created on Redmine.
I want to make it easy for users and sophisticated.
To do so; I've created a custom field on USER section which is named MOBILE. In Custom Fields menu, the user writes his/her phone number in this field.
I also created a custom field on ISSUES section. This custom field brings user list to ISSUES. User list custom field as you know is default redmine feature in ISSUES section for redmine 2.4.x.
So here is my question; I want user list custom field feature to bring user MOBILE numbers which I've created field on users accounts page. Current query brings name and surname and user to.
I checked apps-models-custom_field.rb however no luck. I couldn't find a solution.
I think inner join with custom_values table could solve my problem but I do not know how to do it, actually I don't know which file contains this queries for custom field user list.
Default user list feature of custom fields prints User firstname and lastname on ISSUES page also it just brings user id on the xml api.
So all I want to do is get user custom field content with their user id on the xml.
I hope I've made myself clear.
What are your suggestions?
You won't be able to find SQL queries in Redmine code as Redmine uses Rails' ActiveRecond framework to build SQL queries dynamically.
As I understand the query, you are looking for, should look like:
SELECT
login, firstname, lastname, value
FROM
users
LEFT JOIN
custom_values ON custom_values.customized_id = users.id
AND customized_type = 'Principal'
WHERE
custom_field_id = (SELECT id FROM custom_fields
WHERE type = 'UserCustomField'
AND name = 'MOBILE')
AND value IS NOT NULL
AND value != ''
Hope, this helps.

How to assign data only to users who have a specific role?

If I have data which I only want to assign to users who have an admin role, how would I represent this in the db schema? i.e. I have a users table, roles table, user_roles table and this particular user is linked to an admin role. How would I then be able to specify information only for admin users?
EDIT4: So if I understand, you have the users table, role table and an association linking users to roles.
One idea would be to put the value in the role table, then basically you'll have multiple role for multiple admin levels.
Or you can create other fields in the association table, to parametrize the association, but that would impact all other association. (or ou can have : X is in group B with option1=1, option2=42, option3=NULL and treat options fields differently depending on the group)
Other idea, but I would have made it completely differently:
you treat groups as users, with a special field call isGroup [True/False]. Then you create the groupAssociation table which stores which user belongs to which group.
Example :
USER
--Id-- --IsGroup--
A False
B False
C True
D True
GROUPASSOCIATION
--uid-- --BelongsTo--
A C
B D
C D
Note that you can cascade saying that C is included in D.
Then you create a privilege table and associate groups or user to certain privileges.
PRIVILEGE
--Id-- --Name--
1 Access Area 1
2 Access Area 2
3 Modify user
4 Edit on StackOverflow
PRIVILEGEASSOCIATION
--uid-- --pid--
A 4
C 2
D 1
C 3
So user A would have all privileges (one direct, two from C group, one for D group since C is included in D) and B would have only one (from group D)
Would it be better in your case?
EDIT3: Given your last comment, this in not valid anymore
The GRANT command will help you sort out your problem.
You can see it right there : GRANT
As an example :
GRANT SELECT ON db2.invoice TO 'jeffrey'#'localhost';
You can do it for a column only, for all table, or all database as well
EDIT: Oh well, let me check for groups. I forgot that part.
EDIT2: I didn't see anything about group permission tuning in MySQL : this said it's not possible but it's quite old. But I came accros this other SO question and they are using PHP to manage the groups.
I think the OP is trying to set a field in the database where the user_role is equal to admin role. If this is the case then you would need to do something like:
UPDATE field FROM users LEFT JOIN user_role ON user.id = userrole.userid
WHERE userrole.role = 'adminrole'
Now this would depend entirely on your schema, could you please post so we can give you a more accurate SQL command?
EDIT: ok reading the question again just confuses me. Please post your exact schema.
EDIT2:
With your example, it would make sense to store the extra field in the users table, since, an address is related to a user. You would only want to set this field if the users_role is equal to admin_user. This way you would also help if you needed to expand in the future. If not, you could also define another table called admin_addresses. This would only be specified for admin users and could look like: Admin_address_table (userID,address).
To enforce this logic (either way) you could use e.g. a stored procedure. Pass the data to a stored procedure and it would update the address field if the user_role was equal to admin_user. Alternmatively you could use application logic when updating your data.
It is really up to you which way to go. You have a better idea of what may happen in the future and what exact information needs to be stored. Hope this helps.