Skip to content

rules manager for dynamic permissions with ACL like declarations

Notifications You must be signed in to change notification settings

anthony-tresontani/rules

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rules

Flexible rules library for Django

Install

Install:

pip install django-rules

Add rules to INSTALLED_APPS and run python manage.py syncdb to create the appropriate database tables.

Use

Some projects require complex and abstract business logic like:

User A is allowed to buy product XYZ if attribute B of User A equals 58

You need then low level granularity rules. Some solutions exist adding permission to the object itself in the DB. But sometimes, we may want to get permissions for an object which is not in DB.

That's why rules!

In rules, you create a set of assumptions like your customer do. For example:

Anonymous users can't see products of type A

Customer can see standard products

Sales representatives can see VIP products

Admin can see everything

to translate that in python code, you have to define:

a group
Anonymous, Customer, Sales rep, Admin are all groups. They are dynamically assigned to users because they validate a condition. Something like you are anonymous if you are not authenticated. You can belong to multiple groups.
a predicate
Any products, standard products, VIP products, everything are all predicates. A predicate is a method to caracterise something. How do you know than a product is of type B: product_type=="B". To be efficient, there is many way to implement your predicate. As of now, three are supported. apply_qs for a queryset, apply_obj for an object, apply_sqs for a search_queryset coming from Haystack.
a rule
The link between the group and the predicate through an action. Action may be: 'see products' in our example. Action are only strings

Here is what a rule looks file:

Rule.objects.create_rule(groups_in="anonymous", cant_do="see_products", predicate="A_products")

translating:

Anonymous users can't see products of type A

You have then to explain to 'rules' what anynomous and A_products means by subclassing Group and Predicate.

class Anonymous(Group):

name="anonymous" @classmethod def belong(cls, obj):

return isinstance(obj, User) and obj.is_authenticated()

then the Predicate.

class Any(Predicate):

name="A_products" @classmethod def apply_qs(cls, qs):

return {"product_type":"A"}

then, to check for it, just do:

list_of_products = ApplyRule(on=Product.objects.all(), action="see_products", for_=anonymous_user).check()

And you will get a queryset with the list of product validating your rules. Let say you have 3 products, 1 of type A , 1 of type B and 1 of type C.

You get:

list_of_products = [ productB, productC ]

Now, if you add a new rule for C product:

Anonymous users can't see products of type C

you will get:

list_of_products = [ productB ]

View decorator

You may want to decorate a view. There is an helper to do that simply. For example:

from rules.base import get_view_decorator

can_see_products = get_view_decorator("see_products")

@can_see_products def get(self, *args, **kwargs):

...

Contribute

Install for contributing:

git clone git://github.com/anthony-tresontani/rules.git
mkvirtualenv rules
cd rules
python setup.py develop
pip install -r requirements.txt

Run tests:

./run_tests.py

Understand

Automatic group creation

Any object is automatically assigned a group by default containing the all objects of the same model. For ex, any Product instead will belong to the group group_product_model.

About

rules manager for dynamic permissions with ACL like declarations

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages