Commits

Hector Garcia committed 1e995d4

Initial import

Comments (0)

Files changed (4)

docs/TODO

Empty file added.

rbac/__init__.py

Empty file added.
+from django.db import models
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
+
+
+class RBACPermissionManager(models.Manager):
+
+    def create_permission(self, owner, object, operation, roles):
+        owner_ct = ContentType.objects.get_for_model(owner)
+        object_ct = ContentType.objects.get_for_model(object)
+        permission = RBACPermission.objects.create(owner_ct=owner_ct, owner_id=owner.id,
+            object_ct=object_ct, object_id=object.id, operation=operation)
+        for role in roles:
+            permission.roles.add(role)
+        return permission
+
+
+class RBACGenericPermissionManager(models.Manager):
+
+    def create_permission(self, owner, model, operation, roles):
+        owner_ct = ContentType.objects.get_for_model(owner)
+        model_ct = ContentType.objects.get_for_model(model)
+        permission = RBACGenericPermission.objects.create(owner_ct=owner_ct, owner_id=owner.id,
+            content_type=model_ct, operation=operation)
+        for role in roles:
+            permission.roles.add(role)
+        return permission
+
+
+class RBACOperation(models.Model):
+    name = models.CharField(max_length=30, unique=True)
+    desc = models.CharField(max_length=150, blank=True)
+
+    def __unicode__(self):
+        return '%s' % self.name
+
+
+class RBACRole(models.Model):
+    name = models.CharField(max_length=30, unique=True)
+    desc = models.CharField(max_length=150, blank=True)
+
+    def __unicode__(self):
+        return '%s' % self.name
+
+
+class RBACPermission(models.Model):
+    owner_ct = models.ForeignKey(ContentType, related_name='permission_owner')
+    owner_id = models.PositiveIntegerField()
+    object_ct = models.ForeignKey(ContentType, related_name='permission_object')
+    object_id = models.PositiveIntegerField()
+    operation = models.ForeignKey(RBACOperation)
+    roles = models.ManyToManyField(RBACRole, related_name='permissions')
+
+    owner = generic.GenericForeignKey('owner_ct', 'owner_id')
+    object = generic.GenericForeignKey('object_ct', 'object_id')
+
+    objects = RBACPermissionManager()
+
+    class Meta:
+        unique_together = ('owner_ct', 'owner_id', 'object_ct', 'object_id', 'operation')
+   
+    def __unicode__(self):
+        return '%s | %s | %s' % (self.owner, self.object, self.operation)
+
+
+class RBACGenericPermission(models.Model):
+    owner_ct = models.ForeignKey(ContentType, related_name='generic_permission_owner')
+    owner_id = models.PositiveIntegerField()
+    content_type = models.ForeignKey(ContentType, related_name='generic_permission_model')
+    operation = models.ForeignKey(RBACOperation)
+    roles = models.ManyToManyField(RBACRole, related_name='generic_permissions')
+
+    owner = generic.GenericForeignKey('owner_ct', 'owner_id')
+
+    objects = RBACGenericPermissionManager()
+
+    class Meta:
+        unique_together = ('owner_ct', 'owner_id', 'content_type', 'operation')
+    
+    def __unicode__(self):
+        return '%s | %s | %s' % (self.owner, self.content_type, self.operation)
+
+from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import ObjectDoesNotExist
+
+from rbac.models import RBACOperation
+from rbac.models import RBACPermission, RBACGenericPermission
+
+
+def get_permission(owner, model, operation, generic):
+    owner_ct = ContentType.objects.get_for_model(owner)
+    model_ct = ContentType.objects.get_for_model(model)
+    # TODO: remove generic param, if model is an instance then do an
+    # RBACPermission search, if it is a Model class do a RBACGenericPermission instead
+    if generic:
+        permission = RBACGenericPermission.objects.get(owner_ct=owner_ct,
+            owner_id=owner.id, content_type=model_ct, operation=operation)
+    else:
+        permission = RBACPermission.objects.get(owner_ct=owner_ct, owner_id=owner.id,
+            object_ct=model_ct, object_id=model.id, operation=operation)
+    return permission
+
+def rbac_permission(roles, owner, model, operation_str, generic=True):
+    # TODO: change order of params to match manager methods
+    # TODO: remove generic param
+    operation = RBACOperation.objects.get(name=operation_str)
+    try:
+        permission = get_permission(owner, model, operation, generic)
+    # If permission does not exist, authorization is not allowed
+    except ObjectDoesNotExist:
+        return False
+    else:
+        for role in permission.roles.all():
+            if role in roles:
+                return True
+        return False