I have following table structure:
Entity
---------------------
id | name
Users
---------------------
id | name | password
UserGroups
---------------------
id | parent_id | name
Users_UserGroups
---------------------
user_id | user_group_id
Roles
---------------------
id | parent_id | name
Users_Roles
--------------------
user_id | role_id
And main objective is create Entity row level access restrictions with following conditions:
1) User creates Entity – he can see it (he is owner)
2) User group members can see it too (but if defined else – not see – it will be user private). So record can be user or group private, or public – all can see record. For example user is in sales team A and there are records what can see all group members, but there can be one or more records what can see only user – maybe potential client.
3) For example user A is in role salesman and this role is child of parent role sales managers. Then user who is sales manager role can see user A entities. Hierarchy structure of roles. Boss can see what is doing his direct employees 🙂
4) There will be profile table too, where profile can be added to role and if needed, to user too.
Main question is how to relate users/groups/roles/profiles to entity? And how to define permissions? My idea was to create column ‘user_id’ into Entity. When query Entity record, find user, after see in which role, group, profile is user and so on. But I think that it is too complex, maybe there can be much easier way, without many additional tables. I would be grateful for advice 🙂
The standard pattern is to define Principal as anything you can assign permissions to. Then user, user group and role are all examples of principal. One way to implement is to have a principal table with principal_id as it’s primary key, and then relate the user table to it via user_id, role table via role_id and group table via user_group_id.
Then you’d have an entity_owner_principal_id column on entity, and an entity_permissions table with entity_id, principal_id. You might add columns such as “read”, “delete”, “update” to this table, or have something more flexible.
You might also want to consider whether there is any real difference between group and role, they’re both ways of grouping users, and you appear to have hierarchy in both too.