Example #1
0
 def get_admin_role(self, instance, name, slug, ou=None, operation=ADMIN_OP,
                    update_name=False, update_slug=False, permissions=(),
                    self_administered=False):
     '''Get or create the role of manager's of this object instance'''
     kwargs = {}
     if ou or getattr(instance, 'ou', None):
         ou = kwargs['ou'] = ou or instance.ou
     else:
         kwargs['ou__isnull'] = True
     # find an operation matching the template
     op = get_operation(operation)
     Permission = rbac_utils.get_permission_model()
     perm, created = Permission.objects.get_or_create(
         operation=op,
         target_ct=ContentType.objects.get_for_model(instance),
         target_id=instance.pk,
         **kwargs)
     admin_role = self.get_mirror_role(perm, name, slug, ou=ou,
                                       update_name=update_name,
                                       update_slug=update_slug)
     permissions = set(permissions)
     permissions.add(perm)
     if self_administered:
         self_perm = admin_role.add_self_administration()
         permissions.add(self_perm)
     if set(admin_role.permissions.all()) != permissions:
         for permission in permissions:
             admin_role.permissions.through.objects.get_or_create(role=admin_role,
                                                                  permission=permission)
     return admin_role
Example #2
0
 def has_self_administration(self, op=CHANGE_OP):
     Permission = rbac_utils.get_permission_model()
     admin_op = rbac_utils.get_operation(op)
     self_perm, created = Permission.objects.get_or_create(
         operation=admin_op,
         target_ct=ContentType.objects.get_for_model(self),
         target_id=self.pk)
     return self.permissions.filter(pk=self_perm.pk).exists()
Example #3
0
def get_search_ou_perm(ou=None):
    if ou:
        Permission = rbac_utils.get_permission_model()
        view_ou_perm, created = Permission.objects.get_or_create(
            operation=rbac_utils.get_operation(SEARCH_OP),
            target_ct=ContentType.objects.get_for_model(ou),
            target_id=ou.pk,
            ou__isnull=True)
    else:
        OU = rbac_utils.get_ou_model()
        Permission = rbac_utils.get_permission_model()
        view_ou_perm, created = Permission.objects.get_or_create(
            operation=rbac_utils.get_operation(SEARCH_OP),
            target_ct=ContentType.objects.get_for_model(ContentType),
            target_id=ContentType.objects.get_for_model(OU).pk,
            ou__isnull=True)
    return view_ou_perm
Example #4
0
 def add_self_administration(self, op=CHANGE_OP):
     'Add permission to role so that it is self-administered'
     Permission = rbac_utils.get_permission_model()
     admin_op = rbac_utils.get_operation(op)
     self_perm, created = Permission.objects.get_or_create(
         operation=admin_op,
         target_ct=ContentType.objects.get_for_model(self),
         target_id=self.pk)
     self.permissions.add(self_perm)
     return self_perm
Example #5
0
def get_view_user_perm(ou=None):
    User = get_user_model()
    Permission = rbac_utils.get_permission_model()
    view_user_perm, created = Permission.objects.get_or_create(
        operation=rbac_utils.get_operation(VIEW_OP),
        target_ct=ContentType.objects.get_for_model(ContentType),
        target_id=ContentType.objects.get_for_model(User).pk,
        ou__isnull=ou is None,
        ou=ou)
    return view_user_perm
Example #6
0
 def add_self_administration(self, op=CHANGE_OP):
     'Add permission to role so that it is self-administered'
     Permission = rbac_utils.get_permission_model()
     admin_op = rbac_utils.get_operation(op)
     self_perm, created = Permission.objects.get_or_create(
         operation=admin_op,
         target_ct=ContentType.objects.get_for_model(self),
         target_id=self.pk)
     self.permissions.through.objects.get_or_create(role=self, permission=self_perm)
     return self_perm
Example #7
0
    def handle(self, *args, **options):
        from django_rbac.utils import get_permission_model, get_role_model

        Permission = get_permission_model()
        count = Permission.objects.cleanup()
        if count:
            print 'Deleted %d permissions.' % count

        Role = get_role_model()

        count = 0
        count = Role.objects.cleanup()
        if count:
            print 'Deleted %d roles.' % count
Example #8
0
def update_ous_admin_roles():
    '''Create general admin roles linked to all organizational units,
       they give general administrative rights to all mamanged content types
       scoped to the given organizational unit.
    '''
    Role = get_role_model()
    Permission = get_permission_model()
    OU = get_ou_model()
    ou_all = OU.objects.all()
    if len(ou_all) < 2:
        # If there is no ou or less than two, only generate global management
        # roles
        return
    for ou in ou_all:
        update_ou_admin_roles(ou)
Example #9
0
 def form_valid(self, form):
     if self.can_change:
         operation = form.cleaned_data["operation"]
         ou = form.cleaned_data["ou"]
         target = form.cleaned_data["target"]
         action = form.cleaned_data["action"]
         if action == "add":
             Permission = get_permission_model()
             perm, created = Permission.objects.get_or_create(
                 operation=operation, ou=ou, target_ct=ContentType.objects.get_for_model(target), target_id=target.pk
             )
             self.object.permissions.add(perm)
     else:
         messages.warning(self.request, _("You are not authorized"))
     return super(RolePermissionsView, self).form_valid(form)
Example #10
0
 def get_queryset(self):
     qs = super(RolesMixin, self).get_queryset()
     qs = qs.select_related("ou")
     Permission = get_permission_model()
     permission_ct = ContentType.objects.get_for_model(Permission)
     ct_ct = ContentType.objects.get_for_model(ContentType)
     ou_ct = ContentType.objects.get_for_model(get_ou_model())
     permission_qs = Permission.objects.filter(target_ct_id__in=[ct_ct.id, ou_ct.id]).values_list("id", flat=True)
     # only non role-admin roles, they are accessed through the
     # RoleManager views
     if not self.admin_roles:
         qs = qs.filter(
             Q(admin_scope_ct__isnull=True) | Q(admin_scope_ct=permission_ct, admin_scope_id__in=permission_qs)
         )
     if not self.service_roles:
         qs = qs.filter(service__isnull=True)
     return qs
Example #11
0
class ChoosePermissionForm(CssClass, forms.Form):
    operation = forms.ModelChoiceField(required=False,
                                       label=_('Operation'),
                                       queryset=Operation.objects)
    ou = forms.ModelChoiceField(label=_('Organizational unit'),
                                queryset=get_ou_model().objects,
                                required=False)
    target = forms.ModelChoiceField(label=_('Target object'),
                                    required=False,
                                    queryset=ContentType.objects)
    action = forms.CharField(initial='add',
                             required=False,
                             widget=forms.HiddenInput)
    permission = forms.ModelChoiceField(
        queryset=get_permission_model().objects,
        required=False,
        widget=forms.HiddenInput)
Example #12
0
def update_ous_admin_roles():
    '''Create general admin roles linked to all organizational units,
       they give general administrative rights to all mamanged content types
       scoped to the given organizational unit.
    '''
    Role = get_role_model()
    Permission = get_permission_model()
    OU = get_ou_model()
    ou_all = OU.objects.all()
    if len(ou_all) < 2:
        # If there is no ou or less than two, only generate global management
        # roles
        Role.objects.filter(slug__startswith='_a2', ou__isnull=False).delete()
        Role.objects.filter(slug__startswith='_a2-managers-of-').delete()
        Permission.objects.filter(roles__isnull=True).delete()
        return
    for ou in ou_all:
        update_ou_admin_roles(ou)
Example #13
0
 def get_queryset(self):
     qs = super(RolesMixin, self).get_queryset()
     qs = qs.select_related('ou')
     Permission = get_permission_model()
     permission_ct = ContentType.objects.get_for_model(Permission)
     ct_ct = ContentType.objects.get_for_model(ContentType)
     ou_ct = ContentType.objects.get_for_model(get_ou_model())
     permission_qs = Permission.objects.filter(target_ct_id__in=[ct_ct.id, ou_ct.id]) \
         .values_list('id', flat=True)
     # only non role-admin roles, they are accessed through the
     # RoleManager views
     if not self.admin_roles:
         qs = qs.filter(
             Q(admin_scope_ct__isnull=True)
             | Q(admin_scope_ct=permission_ct,
                 admin_scope_id__in=permission_qs))
     if not self.service_roles:
         qs = qs.filter(service__isnull=True)
     return qs
Example #14
0
def test_massive_role_parenting(db):

    User = get_user_model()
    Role = utils.get_role_model()
    RoleParenting = utils.get_role_parenting_model()
    Permission = utils.get_permission_model()
    user = User.objects.create(username='******')
    roles = []
    # Try a depth=10 tree of roles
    for i in range(0, SIZE):
        name = 'role%s' % i
        roles.append(Role(pk=i + 1, name=name, slug=name))
    Role.objects.bulk_create(roles)
    relations = []
    for i in range(0, SIZE):
        if not i:
            continue
        relations.append(
            RoleParenting(parent=roles[i], child=roles[(i - 1) / SPAN]))
    RoleParenting.objects.bulk_create(relations)
    RoleParenting.objects.update_transitive_closure()
    operation, created = models.Operation.objects.get_or_create(
        slug='admin', defaults={'name': 'Administration'})
    perm, created = Permission.objects.get_or_create(
        operation=operation,
        target_ct=ContentType.objects.get_for_model(ContentType),
        target_id=ContentType.objects.get_for_model(User).id)
    roles[0].members.add(user)
    Role.objects.get(pk=roles[-1].pk).permissions.add(perm)
    b = time.time()
    for i in range(1000):
        assert models.Operation.objects.has_perm(user, 'admin', User)
    t = time.time() - b
    assert float(t) / 1000 < 0.008
    b = time.time()
    for i in range(1000):
        assert (list(Role.objects.for_user(user).order_by('pk')) == list(
            Role.objects.order_by('pk')))
    t = time.time() - b
    assert float(t) / 1000 < 0.1
    b = time.time()
Example #15
0
 def form_valid(self, form):
     if self.can_change:
         operation = form.cleaned_data.get('operation')
         ou = form.cleaned_data.get('ou')
         target = form.cleaned_data.get('target')
         action = form.cleaned_data.get('action')
         Permission = get_permission_model()
         if action == 'add' and operation and target:
             perm, created = Permission.objects \
                 .get_or_create(operation=operation, ou=ou,
                                target_ct=ContentType.objects.get_for_model(
                                    target),
                                target_id=target.pk)
             self.object.permissions.add(perm)
             hooks.call_hooks('event',
                              name='manager-add-permission',
                              user=self.request.user,
                              role=self.object,
                              permission=perm)
         elif action == 'remove':
             try:
                 permission_id = int(self.request.POST.get(
                     'permission', ''))
                 perm = Permission.objects.get(id=permission_id)
             except (ValueError, Permission.DoesNotExist):
                 pass
             else:
                 if self.object.permissions.filter(
                         id=permission_id).exists():
                     self.object.permissions.remove(perm)
                     hooks.call_hooks('event',
                                      name='manager-remove-permission',
                                      user=self.request.user,
                                      role=self.object,
                                      permission=perm)
     else:
         messages.warning(self.request, _('You are not authorized'))
     return super(RolePermissionsView, self).form_valid(form)
Example #16
0
    def permissions(self):
        """ Update permissions (delete everything then create)
        """
        created, deleted = [], []
        for perm in self._obj.permissions.all():
            perm.delete()
            deleted.append(perm)
        self._obj.permissions.clear()
        if self._permissions:
            for perm in self._permissions:
                op = Operation.objects.get_by_natural_key_json(
                    perm['operation'])
                ou = get_ou_model().objects.get_by_natural_key_json(
                    perm['ou']) if perm['ou'] else None
                ct = ContentType.objects.get_by_natural_key_json(
                    perm['target_ct'])
                target = ct.model_class().objects.get_by_natural_key_json(
                    perm['target'])
                perm = get_permission_model().objects.create(
                    operation=op, ou=ou, target_ct=ct, target_id=target.pk)
                self._obj.permissions.add(perm)
                created.append(perm)

        return created, deleted
Example #17
0
 class Meta:
     model = get_permission_model()
     attrs = {'class': 'main', 'id': 'role-table'}
     fields = ('operation', 'scope', 'target')
     empty_text = _('None')
Example #18
0
from django.test import TestCase
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError

from django_rbac.utils import get_permission_model, get_role_model

Permission = get_permission_model()
Role = get_role_model()
User = get_user_model()


class A2RBACTestCase(TestCase):
    def test_update_rbac(self):
        # 3 content types managers and 1 global manager
        self.assertEquals(Role.objects.count(), 4)
        # 3 content type global permissions, 4 role administration permissions
        # and 1 user view permission (for the role administrator)
        self.assertEquals(Permission.objects.count(), 9)

    def test_delete_role(self):
        rcount = Role.objects.count()
        pcount = Permission.objects.count()
        new_role = Role.objects.create(name='Coucou')
        admin_role = new_role.get_admin_role()

        # There should two more roles, the role and its admin counterpart
        self.assertEquals(Role.objects.count(), rcount+2)

        # There should be two more permissions the admin permission on the role
        # and the admin permission on the admin role
Example #19
0
def test_rbac_backend(db):
    Permission = utils.get_permission_model()
    User = get_user_model()
    OU = utils.get_ou_model()
    ou1 = OU.objects.create(name=u'ou1', slug=u'ou1')
    ou2 = OU.objects.create(name=u'ou2', slug=u'ou2')
    user1 = User.objects.create(username='******')
    Role = utils.get_role_model()
    ct_ct = ContentType.objects.get_for_model(ContentType)
    role_ct = ContentType.objects.get_for_model(Role)
    change_op = models.Operation.objects.get(slug='change')
    view_op = models.Operation.objects.get(slug='view')
    delete_op = models.Operation.objects.get(slug='delete')
    add_op = models.Operation.objects.get(slug='add')
    admin_op = models.Operation.objects.get(slug='admin')
    perm1 = Permission.objects.create(operation=change_op,
                                      target_ct=ct_ct,
                                      target_id=role_ct.pk)
    perm2 = Permission.objects.create(operation=view_op,
                                      target_ct=ct_ct,
                                      target_id=role_ct.pk)
    role1 = Role.objects.create(name='role1')
    role2 = Role.objects.create(name='role2', ou=ou1)
    role1.permissions.add(perm1)
    role2.permissions.add(perm2)
    role1.add_child(role2)
    role2.members.add(user1)
    perm3 = Permission.objects.create(operation=delete_op,
                                      target_ct=role_ct,
                                      target_id=role1.pk)
    perm4 = Permission.objects.create(operation=add_op,
                                      ou=ou1,
                                      target_ct=ct_ct,
                                      target_id=role_ct.pk)
    role1.permissions.add(perm3)
    role1.permissions.add(perm4)

    rbac_backend = backends.DjangoRBACBackend()
    ctx = CaptureQueriesContext(connection)
    with ctx:
        assert rbac_backend.get_all_permissions(user1) == set([
            'django_rbac.change_role', 'django_rbac.search_role',
            'django_rbac.view_role'
        ])
        assert rbac_backend.get_all_permissions(user1, obj=role1) == set([
            'django_rbac.delete_role', 'django_rbac.change_role',
            'django_rbac.search_role', 'django_rbac.view_role'
        ])
        assert rbac_backend.get_all_permissions(user1, obj=role2) == set([
            'django_rbac.change_role', 'django_rbac.view_role',
            'django_rbac.search_role', 'django_rbac.add_role'
        ])
        assert not rbac_backend.has_perm(
            user1, 'django_rbac.delete_role', obj=role2)
        assert rbac_backend.has_perm(user1,
                                     'django_rbac.delete_role',
                                     obj=role1)
        assert rbac_backend.has_perms(user1, [
            'django_rbac.delete_role', 'django_rbac.change_role',
            'django_rbac.view_role'
        ],
                                      obj=role1)
        assert rbac_backend.has_module_perms(user1, 'django_rbac')
        assert not rbac_backend.has_module_perms(user1, 'contenttypes')
    assert len(ctx.captured_queries) == 1
    assert (set(
        rbac_backend.filter_by_perm(user1, 'django_rbac.add_role',
                                    Role.objects.all())) == set([role2]))
    assert (set(
        rbac_backend.filter_by_perm(user1, 'django_rbac.delete_role',
                                    Role.objects.all())) == set([role1]))
    assert set(
        rbac_backend.filter_by_perm(
            user1, ['django_rbac.delete_role', 'django_rbac.add_role'],
            Role.objects.all())) == set([role1, role2])
    assert (set(
        rbac_backend.filter_by_perm(user1, 'django_rbac.view_role',
                                    Role.objects.all())) == set([role1,
                                                                 role2]))
    assert (set(
        rbac_backend.filter_by_perm(user1, 'django_rbac.change_role',
                                    Role.objects.all())) == set([role1,
                                                                 role2]))

    # Test admin op as a generalization of other ops
    user2 = User.objects.create(username='******')
    role3 = Role.objects.create(name='role3')
    role3.members.add(user2)
    perm5 = Permission.objects.create(operation=admin_op,
                                      target_ct=ct_ct,
                                      target_id=role_ct.pk)
    role3.permissions.add(perm5)
    assert rbac_backend.get_all_permissions(user2) == set([
        'django_rbac.add_role', 'django_rbac.change_role',
        'django_rbac.search_role', 'django_rbac.admin_role',
        'django_rbac.view_role', 'django_rbac.delete_role'
    ])

    # test ous_with_perm
    assert set(rbac_backend.ous_with_perm(
        user1, 'django_rbac.add_role')) == set([ou1])
    assert set(rbac_backend.ous_with_perm(
        user1, 'django_rbac.view_role')) == set([ou1, ou2])
    assert set(rbac_backend.ous_with_perm(
        user1, 'django_rbac.delete_role')) == set([])
Example #20
0
from django.test import TestCase
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError

from django_rbac.utils import get_permission_model, get_role_model

Permission = get_permission_model()
Role = get_role_model()
User = get_user_model()


class CustomUserTestCase(TestCase):
    def test_roles_and_parents(self):
        rchild1 = Role.objects.create(name='role-child1')
        rparent1 = Role.objects.create(name='role-parent1')
        rparent2 = Role.objects.create(name='role-parent2')
        rchild2 = Role.objects.create(name='role-child2')
        rparent1.add_child(rchild1)
        rparent1.add_child(rchild2)
        rparent2.add_child(rchild1)
        rparent2.add_child(rchild2)

        user1 = User.objects.create(username='******')
        user1.roles.add(rchild1)
        self.assertEqual(set([r.id for r in user1.roles_and_parents()]),
                         set([rchild1.id, rparent1.id, rparent2.id]))
        for r in user1.roles_and_parents():
            if r.id == rchild1.id:
                self.assertEqual(r.member, [user1])
            else: