Esempio n. 1
0
 def clean(self):
     try:
         get_roleclass(self.role_class)
     except RoleNotFound:
         raise ValidationError({
             'role_class':
             'This string representation does not exist as a Role class.'
         })
Esempio n. 2
0
def has_permission(user, permission, obj=None):
    """
    Return True if the "user" has the "permission".
    """
    perm_obj = string_to_permission(permission)
    if obj:
        stack = list()
        stack.append(obj)
        while stack:
            # Getting the dictionary of permissions
            # from the cache.
            current_obj = stack.pop(0)
            roles_list = get_from_cache(user, current_obj)
            for role_s, perm_list in roles_list:

                # Check for permissions.
                for perm_tuple in perm_list:
                    if perm_tuple[0] == perm_obj.id:
                        return perm_tuple[1]

                # Now, we are in inherit mode.
                # We need to check if the Role
                # allows the inherit.
                return inherit_check(get_roleclass(role_s), permission)

            # Try to look even further
            # for possible parent fields.
            parents_list = get_parents(current_obj)
            for parent in parents_list:
                stack.append(parent)

    # If nothing was found or the obj was
    # not provided, try now for roles with
    # "models" = ALL_MODELS.
    roles_list = get_from_cache(user)
    for role_s, perm_list in roles_list:

        # Check for permissions.
        for perm_tuple in perm_list:
            if perm_tuple[0] == perm_obj.id:
                return perm_tuple[1]

        # Now, we are in inherit mode.
        # We need to check if the Role
        # allows the inherit.
        return inherit_check(get_roleclass(role_s), permission)

    # If all fails and the user does not have
    # a role class with "ALL_MODELS", we finnaly
    # deny the permission.
    return False
Esempio n. 3
0
 def __str__(self):
     role = get_roleclass(self.role_class)
     output = '{user} is {role}'.format(user=self.user,
                                        role=role.get_verbose_name())
     if self.obj:
         output += ' of {obj}'.format(obj=self.obj)
     return output
def assign_permission(user, role_class, permission, access, obj=None):
    """
    Assign a specific permission value
    to a given UserRole instance.
    The values used in this method overrides
    any configuration of "allow/deny" or
    "inherit_allow/inherit_deny".
    """
    role = get_roleclass(role_class)
    perm = string_to_permission(permission)
    query = UserRole.objects.filter(user=user,
                                    role_class=role.get_class_name())
    if obj:
        ct_obj = ContentType.objects.get_for_model(obj)
        query = query.filter(content_type=ct_obj.id, object_id=obj.id)

    if not query:
        raise InvalidPermissionAssignment('No Role instance was affected.')

    for role_obj in query:
        perm_obj, created = RolePermission.objects.get_or_create(  # pylint: disable=W0612
            role=role_obj, permission=perm)
        perm_obj.access = bool(access)
        perm_obj.save()

        # Cleaning the cache system.
        delete_from_cache(user, role_obj.obj)
def remove_all(role_class=None, obj=None):
    """
    Remove all roles of the project.

    If "role_class" is provided,
    only the roles of "role_class"
    will be affected.

    If "obj" is provided, only
    users for that object will
    lose the role.
    """
    query = UserRole.objects.all()
    role = None

    if role_class:
        # Filtering by role class.
        role = get_roleclass(role_class)
        query = UserRole.objects.filter(role_class=role.get_class_name())

    if obj:
        # Filtering by object.
        ct_obj = ContentType.objects.get_for_model(obj)
        query = query.filter(content_type=ct_obj.id, object_id=obj.id)

    # Check if object belongs
    # to the role class.
    check_my_model(role, obj)

    # Cleaning the cache system.
    for role_obj in query:
        delete_from_cache(role_obj.user, role_obj.obj)

        # Cleaning the database.
        role_obj.delete()
def remove_roles(users_list, role_class=None, obj=None):
    """
    Delete all RolePermission objects in the database
    referencing the followling role_class to the
    user.
    If "obj" is provided, only the instances refencing
    this object will be deleted.
    """
    query = UserRole.objects.filter(user__in=users_list)
    role = None

    if role_class:
        # Filtering by role class.
        role = get_roleclass(role_class)
        query = query.filter(role_class=role.get_class_name())

    if obj:
        # Filtering by object.
        ct_obj = ContentType.objects.get_for_model(obj)
        query = query.filter(content_type=ct_obj.id, object_id=obj.id)

    # Check if object belongs
    # to the role class.
    check_my_model(role, obj)

    # Cleaning the cache system.
    for user in users_list:
        delete_from_cache(user, obj)

    # Cleaning the database.
    query.delete()
Esempio n. 7
0
def has_role(user, role_class=None, obj=None):
    """
    Check if the "user" has any role
    attached to him.

    If "role_class" is provided, only
    this role class will be counted.

    If "obj" is provided, the search is
    refined to look only at that object.
    """

    query = UserRole.objects.filter(user=user)
    role = None

    if role_class:
        # Filtering by role class.
        role = get_roleclass(role_class)
        query = query.filter(role_class=role.get_class_name(), user=user)

    if obj:
        # Filtering by object.
        ct_obj = ContentType.objects.get_for_model(obj)
        query = query.filter(content_type=ct_obj.id, object_id=obj.id)

    # Check if object belongs
    # to the role class.
    check_my_model(role, obj)

    return query.count() > 0
Esempio n. 8
0
def get_objects(user, role_class=None, model=None):
    """
    Return the list of objects attached
    to a given user.

    If "role_class" is provided, only the objects
    which as registered in that role class will
    be returned.

    If "model" is provided, only the objects
    of that model will be returned.
    """
    query = UserRole.objects.filter(user=user)
    role = None

    if role_class:
        # Filtering by role class.
        role = get_roleclass(role_class)
        query = query.filter(role_class=role.get_class_name())

    if model:
        # Filtering by model.
        ct_obj = ContentType.objects.get_for_model(model)
        query = query.filter(content_type=ct_obj.id)

    # Check if object belongs
    # to the role class.
    check_my_model(role, model)

    # TODO
    result = set(ur_obj.obj for ur_obj in query)
    # TODO
    return list(result)
Esempio n. 9
0
def get_users(role_class=None, obj=None):
    """
    If "role_class" and "obj" is provided,
    returns a QuerySet of users who has
    this role class attached to the
    object.

    If only "role_class" is provided, returns
    a QuerySet of users who has this role
    class attached to any object.

    If neither "role_class" or "obj" are provided,
    returns all users of the project.
    """
    role = None
    kwargs = {}

    if role_class:
        # All users who have "role_class" attached to any object.
        role = get_roleclass(role_class)
        kwargs['roles__role_class'] = role.get_class_name()

    if obj:
        # All users who have any role attached to the object.
        ct_obj = ContentType.objects.get_for_model(obj)
        kwargs['roles__content_type'] = ct_obj.id
        kwargs['roles__object_id'] = obj.id

    # Check if object belongs
    # to the role class.
    check_my_model(role, obj)

    # Return as a distinct QuerySet.
    return get_user_model().objects.filter(**kwargs).distinct()
    def test_exceptions(self):
        """ test all exceptions on utils module """
        with self.assertRaises(RoleNotFound):
            get_roleclass(12345)

        with self.assertRaises(RoleNotFound):
            get_roleclass('I am not a role.')

        self.assertEqual(get_model('I am not a model.'), None)

        self.assertEqual(get_parents(FakeModel1), [])

        with self.assertRaises(ParentNotFound):
            get_parents(FakeModel2)

        with self.assertRaises(ImproperlyConfigured):
            is_unique_together(FakeModel3)
def assign_roles(users_list, role_class, obj=None):
    """
    Create a RolePermission object in the database
    referencing the followling role_class to the
    user.
    """
    users_set = set(users_list)
    role = get_roleclass(role_class)
    name = role.get_verbose_name()

    # Check if object belongs
    # to the role class.
    check_my_model(role, obj)

    # If no object is provided but the role needs specific models.
    if not obj and role.models != ALL_MODELS:
        raise InvalidRoleAssignment(
            'The role "%s" must be assigned with a object.' % name)

    # If a object is provided but the role does not needs a object.
    if obj and role.models == ALL_MODELS:
        raise InvalidRoleAssignment(
            'The role "%s" must not be assigned with a object.' % name)

    # Check if the model accepts multiple roles
    # attached using the same User instance.
    if obj and is_unique_together(obj):
        for user in users_set:
            has_user = get_roles(user=user, obj=obj)
            if has_user:
                raise InvalidRoleAssignment(
                    'The user "%s" already has a role attached '
                    'to the object "%s".' % (user, obj))

    if role.unique is True:
        # If the role is marked as unique but multiple users are provided.
        if len(users_list) > 1:
            raise InvalidRoleAssignment(
                'Multiple users were provided using "%s", '
                'but it is marked as unique.' % name)

        # If the role is marked as unique but already has an user attached.
        has_user = get_users(role_class=role, obj=obj)
        if has_user:
            raise InvalidRoleAssignment(
                'The object "%s" already has a "%s" attached '
                'and it is marked as unique.' % (obj, name))

    for user in users_set:
        ur_instance = UserRole(role_class=role.get_class_name(), user=user)
        if obj:
            ur_instance.obj = obj
        ur_instance.save()

        # Cleaning the cache system.
        delete_from_cache(user, obj)
Esempio n. 12
0
def get_user(role_class=None, obj=None):
    """
    Get the User instance attached to the object.
    Only one UserRole must exists and this relation
    must be unique=True.

    Returns None if there is no user attached
    to the object.
    """
    query = UserRole.objects.select_related('user').all()
    role = None

    if role_class:
        # All users who have "role_class" attached to any object.
        role = get_roleclass(role_class)
        query = query.filter(role_class=role.get_class_name())

    if obj:
        # All users who have any role attached to the object.
        ct_obj = ContentType.objects.get_for_model(obj)
        query = query.filter(content_type=ct_obj.id, object_id=obj.id)

    # Check if object belongs
    # to the role class.
    check_my_model(role, obj)

    # Looking for a role class using unique=True
    selected = list()
    for ur_obj in query:
        role = get_roleclass(ur_obj.role_class)
        if role.unique is True:
            selected.append(ur_obj.user)

    users_set = set(selected)
    if len(users_set) > 1:
        raise NotAllowed('Multiple unique roles was found using '
                         'the function get_user.  Use get_users '
                         'instead.')
    if len(users_set) == 1:
        return selected[0]
    return None
Esempio n. 13
0
def get_roles(user, obj=None):
    """
    Return a list of role classes
    that is attached to "user".

    If "obj" is provided, the object
    must be attached as well.
    """
    query = UserRole.objects.filter(user=user)
    if obj:
        ct_obj = ContentType.objects.get_for_model(obj)
        query = query.filter(content_type=ct_obj.id, object_id=obj.id)

    # Transform the string representations
    # into role classes and return as list.
    return [get_roleclass(ur_obj.role_class) for ur_obj in query]
Esempio n. 14
0
def get_permissions_from_roles(roles, clean=False):
    """
    roles: list or QuerySet of UserRole objects
    For given role(s), return a list of all allowed permissions. If clean=True,
    return the permissions without the Django app prefix.
    """
    role_classes = [get_roleclass(ur.role_class) for ur in roles]
    permissions_lists = [r.allow for r in role_classes]

    # Flatten permissions list
    all_permissions = list(
        set([item for sublist in permissions_lists for item in sublist]))

    if clean:
        # Remove the app prefix from all permissions
        all_permissions_clean = [s.split('.')[1] for s in all_permissions]
        return (all_permissions_clean)
    else:
        return (all_permissions)
Esempio n. 15
0
 def role(self):
     return get_roleclass(self.role_class)