Commits

Hector Garcia committed 436e46d

Fixed incomplete code migration in models. Completed docs. Added fixture to example project.

Comments (0)

Files changed (5)

 Usage
 =====
 
-Remember! You have to run Django ``syncdb`` commad to create all the tables and everything else on the SQLite database::
+Usage in views
+==============
+
+The ``example`` folder is a Django project with a ``myapp`` app that
+contains a ``views.py``. Inspect this file to see how you can
+integrate django-rbac in your views.
+
+If you want to try out the example project, you first have to run Django
+``syncdb`` commad to create all the tables and everything else on
+the SQLite database::
 
     python manage.py syncdb
 
-Usage in views
-==============
+After that, load the fixture that comes in the ``myapp/fixtures`` folder::
 
-The ``example`` folder is a Django project with a ``myapp`` app that contains a ``views.py``. Inspect this file to see how you can integrate django-rbac in your views. Run your development server and access the view at /myapp/ to test. Play around changing the code to see how it works.
+    ./manage.py loaddata myapp/fixtures/initial_data.json
+
+Finally, run your development server and access the view at /myapp/ with
+your browser to test. Play around changing the code to see how it works. 
 
 Usage in shell
 ==============
+
 ::
-    # This use case is about defining a role-based access control system for users
-    # who want to restrict group memberships and profile info access.
-    >>> from rbac.models import RBACPermission, RBACRole
-    # Create an operation to define who sees/displays what:
+
+    # This use case is about defining a RBAC system for users  who want to
+    # restrict display of their group memberships and profile info access.
+    >>> from rbac.models import RBACRole, RBACOperation
+    >>> from rbac.models import RBACPermission, RBACGenericPermission
+    # Create an operation to define display of objects:
     >>> operation = RBACOperation.objects.create(name='display')
     # Create some roles:
     >>> RBACRole.objects.create(name='friend')
     >>> owner.groups.add(group2)
     # Create generic permission: hector (owner) allows his friends, coworkers
     # and family (roles) to display (operation) his groups (django Group model)
-    >>> from rbac.models import RBACGenericPermission
     >>> roles = RBACRole.objects.all()
     >>> RBACGenericPermission.objects.create_permission(owner, Group, operation, roles)
     <RBACGenericPermission: hector | group | display>
-    # To check if a user in a given role context is authorized to perform the operation
-    # 'display', we use the rbac_permission function from utils:
-    >>> from rbac.utils import rbac_permission
-    >>> rbac_permission(owner, Group, 'display', roles)
+    # Check if a user with given roles is authorized to perform the
+    # operation 'display':
+    >>> RBACGenericPermission.objects.get_permission(owner, Group, operation, roles)
     True
     # Create a new role and verivy that we are not allowed if trying to access
     # with only this role in the role list:
     >>> RBACRole.objects.create(name='classmate')
     <RBACRole: classmate>
     # Note below that, although we get only one role object, still we need to pass
-    # it inside a queryset list. Also, the second parameter must be a model class
+    # it inside a queryset list.
     >>> roles = RBACRole.objects.filter(name='classmate')
-    >>> rbac_permission(owner, Group, 'display', roles)
+    >>> RBACGenericPermission.objects.get_permission(owner, Group, operation, roles)
     False
     # As an example of a per-object permission, we will restrict which roles
     # are allowed to display the owner's user details.
-    >>> from rbac.models import RBACPermission
-    # If no permission exists for a given scenario, rbac_permission returns False,
-    # following the django-rbac golden rule: if a permission doesn't exist, the operation is denied.
-    # Also note that we are passing a model instance 
-    >>> rbac_permission(owner, owner, 'display', roles)
+    # If no permission exists for any of the given roles, the manager method
+    # returns False, according to the django-rbac golden rule:
+    # if a permission doesn't exist, the operation is denied.
+    # Also note that we are passing a model instance this time (owner, which is
+    # a User model instance)
+    >>> RBACPermission.objects.get_permission(owner, owner, operation, roles)
     False
-    # Create permission: hector (owner) allows only his friends (roles) to display (operation)
-    # his user info (again, owner -- a django User model instance)
+    # Create permission: hector (owner) allows only his friends (roles) to
+    # display (operation) his user info (django User model instance)
     >>> roles = RBACRole.objects.filter(name='friend')
     >>> RBACPermission.objects.create_permission(owner, owner, operation, roles)
     <RBACPermission: hector | hector | display>
-    >>> rbac_permission(owner, owner, 'display', roles)
+    >>> RBACPermission.objects.get_permission(owner, owner, operation, roles)
     True

example/myapp/fixtures/initial_data.json

+[{"pk": 4, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_message", "name": "Can add message", "content_type": 4}}, {"pk": 1, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_message", "name": "Can change message", "content_type": 4}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_message", "name": "Can delete message", "content_type": 4}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_rbacgenericpermission", "name": "Can add rbac generic permission", "content_type": 11}}, {"pk": 22, "model": "auth.permission", "fields": {"codename": "add_rbacoperation", "name": "Can add rbac operation", "content_type": 8}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_rbacpermission", "name": "Can add rbac permission", "content_type": 10}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_rbacrole", "name": "Can add rbac role", "content_type": 9}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "change_rbacgenericpermission", "name": "Can change rbac generic permission", "content_type": 11}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "change_rbacoperation", "name": "Can change rbac operation", "content_type": 8}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_rbacpermission", "name": "Can change rbac permission", "content_type": 10}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_rbacrole", "name": "Can change rbac role", "content_type": 9}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "delete_rbacgenericpermission", "name": "Can delete rbac generic permission", "content_type": 11}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_rbacoperation", "name": "Can delete rbac operation", "content_type": 8}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_rbacpermission", "name": "Can delete rbac permission", "content_type": 10}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_rbacrole", "name": "Can delete rbac role", "content_type": 9}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 7}}, {"pk": 1, "model": "auth.group", "fields": {"name": "punks", "permissions": []}}, {"pk": 2, "model": "auth.group", "fields": {"name": "rockers", "permissions": []}}, {"pk": 1, "model": "auth.user", "fields": {"username": "nabuco", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2009-11-01 10:36:24", "groups": [1, 2], "user_permissions": [], "password": "", "email": "", "date_joined": "2009-11-01 10:36:24"}}, {"pk": 5, "model": "contenttypes.contenttype", "fields": {"model": "contenttype", "name": "content type", "app_label": "contenttypes"}}, {"pk": 2, "model": "contenttypes.contenttype", "fields": {"model": "group", "name": "group", "app_label": "auth"}}, {"pk": 4, "model": "contenttypes.contenttype", "fields": {"model": "message", "name": "message", "app_label": "auth"}}, {"pk": 1, "model": "contenttypes.contenttype", "fields": {"model": "permission", "name": "permission", "app_label": "auth"}}, {"pk": 11, "model": "contenttypes.contenttype", "fields": {"model": "rbacgenericpermission", "name": "rbac generic permission", "app_label": "rbac"}}, {"pk": 8, "model": "contenttypes.contenttype", "fields": {"model": "rbacoperation", "name": "rbac operation", "app_label": "rbac"}}, {"pk": 10, "model": "contenttypes.contenttype", "fields": {"model": "rbacpermission", "name": "rbac permission", "app_label": "rbac"}}, {"pk": 9, "model": "contenttypes.contenttype", "fields": {"model": "rbacrole", "name": "rbac role", "app_label": "rbac"}}, {"pk": 6, "model": "contenttypes.contenttype", "fields": {"model": "session", "name": "session", "app_label": "sessions"}}, {"pk": 7, "model": "contenttypes.contenttype", "fields": {"model": "site", "name": "site", "app_label": "sites"}}, {"pk": 3, "model": "contenttypes.contenttype", "fields": {"model": "user", "name": "user", "app_label": "auth"}}, {"pk": "2d8494b403b039d5783d29fb6690c76f", "model": "sessions.session", "fields": {"expire_date": "2009-11-15 10:51:24", "session_data": "gAJ9cQEuZDQ1YTEzZjVkNjJlOTRkZTJmMjRmMTRmZDgzNGY3NzM=\n"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}, {"pk": 1, "model": "rbac.rbacoperation", "fields": {"name": "display", "desc": ""}}, {"pk": 1, "model": "rbac.rbacrole", "fields": {"name": "family", "desc": ""}}, {"pk": 2, "model": "rbac.rbacrole", "fields": {"name": "friends", "desc": ""}}, {"pk": 3, "model": "rbac.rbacrole", "fields": {"name": "coworkers", "desc": ""}}, {"pk": 1, "model": "rbac.rbacpermission", "fields": {"roles": [1, 2, 3], "owner_ct": 3, "object_id": 1, "operation": 1, "object_ct": 3, "owner_id": 1}}, {"pk": 1, "model": "rbac.rbacgenericpermission", "fields": {"roles": [1, 2, 3], "operation": 1, "owner_ct": 3, "content_type": 2, "owner_id": 1}}]

example/myapp/views.py

 from django.contrib.auth.models import User, Group
 
 from rbac.models import RBACRole, RBACOperation, RBACPermission, RBACGenericPermission
-from rbac.utils import rbac_permission
 
 
 def users_are_friends(user, target_user):
 def get_user_roles(user, target_user):
     roles = []
     if users_are_friends(user, target_user):
-        roles.append(RBACRole.objects.get(name='friend'))
+        roles.append(RBACRole.objects.get(name='friends'))
     if users_are_coworkers(user, target_user):
-        roles.append(RBACRole.objects.get(name='coworker'))
+        roles.append(RBACRole.objects.get(name='coworkers'))
     return roles
 
 def my_view(request):
     """Displays info details from nabuco user"""
 
     owner, c = User.objects.get_or_create(username='nabuco')
-    # TODO: populate from fixture instead?
-    if c:
-        g1 = Group.objects.create(name='punks')
-        g2 = Group.objects.create(name='rockers')
-        owner.groups.add(g1)
-        owner.groups.add(g2)
-        RBACRole.objects.create(name='family')
-        RBACRole.objects.create(name='friends')
-        RBACRole.objects.create(name='coworkers')
+#    # TODO: populate from fixture instead?
+#    if c:
+#        g1 = Group.objects.create(name='punks')
+#        g2 = Group.objects.create(name='rockers')
+#        owner.groups.add(g1)
+#        owner.groups.add(g2)
+#        RBACRole.objects.create(name='family')
+#        RBACRole.objects.create(name='friends')
+#        RBACRole.objects.create(name='coworkers')
 
     # Owner of the object has full permissions, otherwise check RBAC
     if request.user != owner:
         # Get roles
         roles = get_user_roles(request.user, owner)
         # Get operation
-        op, c = RBACOperation.objects.get_or_create('display')
+        op, c = RBACOperation.objects.get_or_create(name='display')
 
         # Per-model permission:
         # Has user permission to display groups that nabuco belongs to?
-        if not RBACGenericPermission.objects.get_permission(owner, Group, op, roles)
+        if not RBACGenericPermission.objects.get_permission(owner, Group, op, roles):
             return HttpResponseForbidden("Sorry, you are not allowed to see nabuco groups")
 
         # Per-object permission:
         # Has user permission to see this group which nabuco belong to?
         group_inst = get_object_or_404(Group, name='punks')
-        if not RBACPermission.objects.get_permission(owner, owner, op, roles)
+        if not RBACPermission.objects.get_permission(owner, owner, op, roles):
             return HttpResponseForbidden("Sorry, you are not allowed to see this group details")
 
     return HttpResponse('Test passed!')

example/settings.py

     'django.contrib.sessions',
     'django.contrib.sites',
     'rbac',
+    'myapp',
 )
 
 try:
 from django.db import models
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes import generic
+from django.core.exceptions import ObjectDoesNotExist
 
 
 def _get_permission(queryset_model, filters, roles):
 
 class RBACPermissionManager(models.Manager):
 
-    def _get_filters(owner, model, operation):
+    def _get_filters(self, owner, model_inst, operation):
         owner_ct = ContentType.objects.get_for_model(owner)
-        model_ct = ContentType.objects.get_for_model(model)
+        model_ct = ContentType.objects.get_for_model(model_inst)
         filters = {'owner_ct': owner_ct, 'owner_id': owner.id,
-                   'model_ct': model_ct, 'model_id': model.id,
+                   'object_ct': model_ct, 'object_id': model_inst.id,
                    'operation': operation}
         return filters
 
         queryset_model = RBACPermission
         return _get_permission(queryset_model, filters, roles)
 
-    def create_permission(self, owner, object, operation, roles):
-        filters = self._get_filters(owner, model, operation)
+    def create_permission(self, owner, model_inst, operation, roles):
+        filters = self._get_filters(owner, model_inst, operation)
         permission = RBACPermission.objects.create(**filters)
         for role in roles:
             permission.roles.add(role)
 
 class RBACGenericPermissionManager(models.Manager):
 
-    def _get_filters(owner, model, operation):
+    def _get_filters(self, owner, model, operation):
         owner_ct = ContentType.objects.get_for_model(owner)
         model_ct = ContentType.objects.get_for_model(model)
         filters = {'owner_ct': owner_ct, 'owner_id': owner.id,
         queryset_model = RBACGenericPermission
         return _get_permission(queryset_model, filters, roles)
 
-    def create_permission(self, owner, object, operation, roles):
+    def create_permission(self, owner, model, operation, roles):
         filters = self._get_filters(owner, model, operation)
         permission = RBACGenericPermission.objects.create(**filters)
         for role in roles: