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

How do you map predicates to objects and/or users? #173

Open
realnot opened this issue Dec 16, 2022 · 1 comment
Open

How do you map predicates to objects and/or users? #173

realnot opened this issue Dec 16, 2022 · 1 comment

Comments

@realnot
Copy link

realnot commented Dec 16, 2022

I'm trying to build this permission mapping

Users Permissions Object
Bob Can edit book Lord of the rings
Bob Can edit book Harry Potter
Bob Can read book Lord of the rings
Bob Can read book Harry Potter
Tim Can edit book Lord of the rings
Tim Can edit book Harry Potter
Tim Can read book Lord of the rings
Tim Can read book Harry Potter

But from the documentation I don't see how "Bob and Tim can edit Lord of the rings". Bob is not in any group and is not the owner of the book. Basically what is missing is a table to map Users, Permissions, Objects.

Predicates can be created from any callable that accepts anything from zero to two positional arguments

All examples show a predicate with user and object as arguments, but not a "permission". How do you test against above matrix? One way would be create a table like:

Users Permissions Content Type Object ID
1 (Bob) 1 (Can edit book) 1 (books) 1 (Lord of the Rings)
1 (Bob) 1 (Can edit book) 1 (books) 2 (Harry Potter)
1 (Bob) 2 (Can read book) 1 (books) 1 (Lord of the Rings)
1 (Bob) 2 (Can read book) 1 (books) 2 (Harry Potter)
1 (Bob) 3 (Can drive cars) 2 (cars) 1 (Ferrari SF90)
1 (Bob) 3 (Can drive cars) 2 (cars) 2 (Fiat 500)
1 (Bob) 4 (Can fix cars) 2 (cars) 1 (Ferrari)
1 (Bob) 4 (Can fix cars) 2 (cars) 2 (Fiat 500)
2 (Tim) 1 (Can edit book) 1 (books) 1 (Lord of the Rings)
2 (Tim) 1 (Can edit book) 1 (books) 2 (Harry Potter)
2 (Tim) 2 (Can read book) 1 (books) 1 (Lord of the Rings)
2 (Tim) 2 (Can read book) 1 (books) 2 (Harry Potter)
2 (Tim) 3 (Can drive cars) 2 (cars) 1 (Ferrari SF90)
2 (Tim) 3 (Can drive cars) 2 (cars) 2 (Fiat 500)
2 (Tim) 4 (Can fix cars) 2 (cars) 1 (Ferrari)
2 (Tim) 4 (Can fix cars) 2 (cars) 2 (Fiat 500)

And from the view you have:

  1. required permissions
  2. user from request
  3. current object_id (from get_object) which take you to step 4
  4. get content_type with object_id

Now you have to test that all permissions you retrieve from the table are in required permission defined by view. Is the right approach or there's another way?

@realnot realnot changed the title How do you map preicates to objects and/or users? How do you map predicates to objects and/or users? Dec 16, 2022
@suspiciousRaccoon
Copy link

I would probably change it so you have all 4 CRUD methods on the same row with a BooleanField for each:

class BookPermission(RulesModel):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    book = models.ForeignKey(Book, on_delete=models.CASCADE)

    can_add = models.BooleanField(default=False)
    can_view = models.BooleanField(default=False)
    can_change = models.BooleanField(default=False)
    can_delete = models.BooleanField(default=False)

It's unrelated to django-rules but I would also recommend avoiding object_id + content_type. You can do this in django with GenericForeignKeys but you should leave them as a last resort. This article talks about the alternatives,

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

2 participants