Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access Control System #5

Open
belst opened this issue Oct 14, 2017 · 6 comments
Open

Access Control System #5

belst opened this issue Oct 14, 2017 · 6 comments

Comments

@belst
Copy link
Owner

belst commented Oct 14, 2017

Ideas for an access control system based on RBAC:

Relationships:

User n<--->m Role n<--->m Permission

Maybe User n<--->m Permission aswell?

Role:
Name
Description
Level

Permission:
Name
Description

If they are not database based, every Role or Permission should be its own type, so they can be used as Request Guards. (They should probably be anyway, even if they are database based.)

Database has the advantage that it is possible to create a very dynamic and customizable system where u can add and remove permissions/roles any time. But you lose the nice static typing and Guard system from Rocket.

Unfortunately we cannot use Enums here, because Enum variants cannot be used as a Guard.

For level checks, something like typelevel integers would be nice. eg (or until they are available: https://github.com/paholg/typenum):

#[get("/private")]
fn get_private(_level: Level<GE<7>>) // level must be Greater or Equal to 7
{
  // return private data
}
@alko89
Copy link

alko89 commented Oct 15, 2017

I had to read about this Guard system and rankings in Rocket. I didn't know much about it. I just started coding withouth the actuall knowledge of the framework.

Do you have any more resources to read? The Rocket guide is kind of vague.
Anyway. I personally would like to have permisions in the database.

When I started my project I thought I could make it work like Pyramid. But it seems that would not be the best option due to the way Rocket works.

Pyramids only has Users and Roles with different permissions. Its not level based (something that a manager can access, can be unaccessable for admin), you just check if the user is in role. The level based system seems more Unix-like.

@belst
Copy link
Owner Author

belst commented Oct 15, 2017

with RBAC you can have both. You can either ask if a user is in a group, if a user has a specific permission or if a user has a certain level.

So if you ask if the User is a Moderator, and Administrator might not be able to access it. but if you for example say, Moderator is level 7 and Administrator is level 10 and you ask for level >= 7 both Administrator and Moderator can access it.

This is just one possible implementation and does not allow for sibling Groups/forks in the group hierarchy.

For a full RBAC implementation a tree of groups would be needed i think. So you can do stuff like this:

           +-->Administrator<--+
           +                   +
Frontend Moderator           Editor
           ^                   ^
           +                   +
Community Moderator          Author

where you can have separate subtrees of groups .

This is not specific to Rocket.

Rocket would just allow to specify the required permissions/roles/levels as route parameters via Guards.

@alko89
Copy link

alko89 commented Oct 15, 2017

But if I understand, these permissions won't work using a database. Is there a way around this?

Worst case, can these permissions be loaded from the database at compile time, to be able to work with Guards?

@belst
Copy link
Owner Author

belst commented Oct 15, 2017

You need some way to specify if a user has a specific permission. So something needs to be in the database. For example List of groups the user is a member of.

But the groups and Permissions itself would not need to be in the database. It wouldnt even make sense to have them in the database because you can only change them at compile time.

edit: if I find some time I'll implement a prototype today.

edit: small permission/group models (no integration into Rocket whatsoever atm, no level stuff either):

https://play.rust-lang.org/?gist=e25a6d594812bc95c41bffd93622041b

@alko89
Copy link

alko89 commented Oct 15, 2017

So we have to add a column to the user to store user groups and a static object in the code itself with defined groups.

You would use typelevel integers for that? I'll have to serch the web for what that is 😄

@veotax
Copy link

veotax commented Apr 17, 2020

You can use: https://github.com/casbin/casbin-rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants