Использование обеих групп и индивидуальных разрешений - PullRequest
3 голосов
/ 22 июня 2019

В Django я создал систему с различными groups пользователями. Используя django.auth, я также создал permission groups, и я связал соответствующие разрешения приложений для каждой группы.

Это прекрасно работает для доступа на основе ролей, но теперь у меня есть требование, где мне также нужна возможность удалять отдельные разрешения у определенного пользователя в группе. Это означает, что мне нужны групповые разрешения, но в то же время эти групповые разрешения могут быть не назначены отдельным пользователям.

При использовании групп Django это, по-видимому, невозможно сделать напрямую, поскольку права доступа абстрагируются от отдельных пользователей.

Как мне это сделать?

Я нахожусь в процессе изменения всех прав доступа для отдельных пользователей, но это кажется немного утомительным для клиентов, поскольку им приходится вручную устанавливать разрешения для каждого нового пользователя, я надеюсь, что кто-то знает о лучшем способе.

1 Ответ

0 голосов
/ 25 июня 2019

Для решения этой проблемы требовалось только поле ManyToMany в моей модели User для хранения отозванных разрешений и пользовательской внутренней аутентификации.

Пользователь:

revoked_permissions = models.ManyToManyField(Permission, blank=True)

Бэкэнд аутентификации:

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import Permission


class UsersAuthenticationBackend(ModelBackend):
    def _get_revoked_perms(self, user_obj):
        if user_obj.is_superuser or user_obj.is_admin:
            revoked_perms = Permission.objects.none()
        elif hasattr(user_obj, 'revoked_permissions'):
            revoked_perms = getattr(user_obj, 'revoked_permissions').values_list('content_type__app_label', 'codename')
        else:
            revoked_perms = Permission.objects.none()

        revoked_perms = ["{}.{}".format(perm[0], perm[1]) for perm in revoked_perms]
        return revoked_perms

    def has_perm(self, user_obj, perm, obj=None):
        if not user_obj.is_active:
            return False

        revoked_perms = self._get_revoked_perms(user_obj)
        all_perms = self.get_all_permissions(user_obj)
        allowed_perms = [p for p in all_perms if not p in revoked_perms]

        return perm in allowed_perms

    def has_module_perms(self, user_obj, app_label):
        if not user_obj.is_active:
            return False

        revoked_perms = self._get_revoked_perms(user_obj)
        all_perms = self.get_all_permissions(user_obj)
        allowed_perms = [p for p in all_perms if not p in revoked_perms]

        for perm in allowed_perms:
            if perm[:perm.index('.')] == app_label:
                return True
        return False

Settings.py:

AUTHENTICATION_BACKENDS = [
    "apps.users.backends.UsersAuthenticationBackend"
]

Теперь я могу устанавливать общие разрешения для групп, а также индивидуально отзывать разрешения для определенных пользователей.

...