I am trying to implement shared CASL on front end and on the backend side (nestjs). I have multiple use cases:
- Admin can read All Posts
- Admin can update All Posts
- Admin can delete All posts
- Admin can View/read the Change Status Button
- Admin can View/read the Add Comment Button
- User1 can read his own post
- User1 can update his own post
- User1 can delete his own post
- User1 can View/read the Change Status Button on posts created by himself
- User1 can View/read the Add comment Button on posts created by himself
First, I tried to use use-case based permissions for example I created my ability using this:
Admin:
can('read', 'Post');
can('update', 'Post');
can('delete', 'Post');
can('read', 'Change Status');
can('read', 'Add Comment');
User1
can('read', 'Post', { createdBy: userId });
can('update', 'Post', { createdBy: userId });
can('delete', 'Post', { createdBy: userId });
can('read', 'Change Status', { createdBy: userId });
can('read', 'Add Comment', { createdBy: userId });
But, I feel that this is not scalable what If I made a typo while checking for permissions? For example, If I check permission using ability.can(read, 'add comments') then it will give me that User is not authorized. Also, If I change the name of my comment module to note then I have to change each and every permission. So, I left this option and then I tried to implement it using Entities. For Example. I created my ability using this (Here Post and Comment is an entity):
Admin:
can('read', 'Post');
can('update', 'Post');
can('delete', 'Post');
can('read', 'Comment');
User1
can('read', 'Post', { createdBy: userId });
can('update', 'Post', { createdBy: userId });
can('delete', 'Post', { createdBy: userId });
can('read', 'Comment', { createdBy: userId });
But, I am not sure about this method. In this method, I have multiple Issues
- How can I add checks on the front end so that User1 Can see the
Change StatusandAdd Commentbuttons only on his own Posts? - On the backend, If there is any endpoint that is not using any entity
then how to Check for permissions for that endpoint for example, I
have an endpoint to retrieve some constants but only the
adminis allowed to read those constants. - On the backend, If I am using joins in my query and User1 does not have permission to view the joined table then how to handle this?
- On the backend, If I am changing multiple entities inside 1 endpoint then I have to give permission for each entity to User1. That makes this Vulnerable.
I want to check If I am going in the right direction. Also, Is there any better solution for this?
Any help would be appreciated.
Thanks