Reputation: 43
I'm currently working on a project where a user can have many roles, and each role has assigned one or many permissions. Permissions describe the actions that a user can apply to ressources. For example let's consider that I have three ressources that I can interact with using my API : users, books, payments.
I'd like to have all users able to update their personal informations like phone number... etc. This led me to give update permission on user's ressource for all users. But the problem is that I want them to be able to updates their own profiles only. Furthermore, some users have admin permissions and can change other users permissions, therefor they have another kind of update permission on user's resource.
So my question is : what's the best way to design the permission table. Below you can find my schema design. Thank you for your answers in advance.
User(firstName string, lastName string, roles Role[])
Role(name string, description string, permissions Permission[])
Permission(name string, effect 'Allow' | 'Deny', resource string, action string)
Upvotes: 0
Views: 550
Reputation: 26129
Well I am not entirely sure what you meant by resource and action. If you meant URI template and HTTP method, then ok. Otherwise you might need a different solution or somehow add parameters to your design if you want to allow or deny individual resources per id.
If we are talking about a REST API, which I assume, then you can do something like PATCH /api/v1/current-user/profile {...}
for updating your profile and PATCH /api/v1/users/{user-id}/profile {...}
to update somebody else's profile. If you meant controller classes and their methods, then you can do the same with two different controllers, something like CurrentUser.partialUpdate(params)
and User.partialUpdate(params)
.
As of updating user permissions, I wonder how to do it, because you can update only role permissions and give or take away roles for the users in your model.
Another thing I don't understand that why do you need the allow|deny flags. If roles collide because users can have multiple roles or permissions collide, because you can both allow and deny the same thing, then how do you resolve it without a hierarchy? And if you don't have a hierarchy, then this flag is completely useless and just deny all and allow what is added to the role.
As of the one user multiple roles approach it is not a great idea, at least in places where people take security seriously a single account or at least a single session can have only a single role. Since this would make a lot of repetition I would solve this on a role level and make composite roles or support role inheritance. So for example the Administrator role would be the composite of the OwnProfileEditor and ProfileEditor sub-roles, which I would rather call Features or Capabilities or PermissionGroups rather than Roles.
Usually RBAC is not that flexible, so people tend to add per User Permissions to override Role Permissions. I would not do it, because you will end up with a mess if you follow that approach.
Upvotes: 0