Django-guardian: Глобальные разрешения против разрешений на объекты

Созданный на 22 дек. 2015  ·  16Комментарии  ·  Источник: django-guardian/django-guardian

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

API change Enhancement

Все 16 Комментарий

Да этому!

permission_required_or_403 имеет параметр accept_global_perms, но в представлении нет возможности сделать то же самое с get_obj_perms

Я предлагаю тег get_obj_perms_with_global, который включает глобальные перма.

Я не знаю, начали ли вы уже этот путь, но я начну разрабатывать патч, чтобы сделать это; если ты уже начал, не стесняйся меня останавливать :)

PS Я думаю, что есть аргумент, что поведение по умолчанию должно включать глобальные разрешения, мне кажется, что когда вы спрашиваете «может ли пользователь X сделать Y для объекта Z», что подразумевает проверку всех пользователей / объектов, групп / объектов , пользовательские / глобальные, групповые / глобальные разрешения. Но это может быть просто из-за того, как я его использую.

Сказав все это, довольно просто проверить глобальные разрешения отдельно ... Хммм.

Пестициды: у Guardian достаточно проблем, свидетельствующих о том, насколько это запутанно. Мы получаем это каждые шесть месяцев ... если request.user.has_access ('foo', obj) должен быть истинным, если у них есть глобальные разрешения, но нет разрешений на уровне объекта. Выписывать чек дважды - противно.

Что должно произойти, чтобы это изменить?

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

Старая проблема, но я пока не вижу запроса на перенос. Есть новости по этому поводу? Я сталкиваюсь с таким же поведением, которое, на мой взгляд, не очень предсказуемо. Огромное спасибо!

Я добавил несколько комментариев к # 49, так как в нем было больше понимания вопроса о том, нужно ли и как откатиться к глобальным переменным при сбое уровня объекта. Я не уверен, вызывают ли закрытые проблемы уведомление, поэтому я добавляю это сюда.

В зависимости от принимаемых дизайнерских решений я намереваюсь поработать над некоторыми из этих вопросов.

Я буду рад помочь с этими проблемами.

327 кажется мне исправленным.

`` ''
brandon = Person.objects.get (first_name = 'BRANDON')
brandon.is_superuser
Ложь

school = School.objects.get (pk = 1)

get_users_with_perms (школа, attach_perms = True, with_superusers = False, with_group_users = False)
{}

assign_perm ('add_school', брендон, школа)

get_users_with_perms (школа, attach_perms = True, with_superusers = False, with_group_users = False)
{: ['add_school']}

mehmet = Person.objects.get (first_name = 'Мехмет')
mehmet.is_superuser
Правда

get_users_with_perms (школа, attach_perms = True, with_superusers = True, with_group_users = False)
{: [],: ['add_school', 'change_school', 'delete_school']}

assign_perm ('add_school', мехмет, школа)

get_users_with_perms (школа, attach_perms = True, with_superusers = True, with_group_users = False)
{: [],: ['add_school', 'change_school', 'delete_school']}

get_users_with_perms (школа, attach_perms = True, with_superusers = False, with_group_users = False)
{: ['add_school'],: ['add_school']}

На # 155:

Требуется добавить следующие две строки в get_obj_perms_field_choices (self) :

        if self.exclude_default:
            choices = list(set(choices).intersection(self.obj._meta.permissions))

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

Но, изучая это, я заметил, что необходимо разделение разрешений на объект и модель:

    def save_obj_perms(self):
        """
        Saves selected object permissions by creating new ones and removing
        those which were not selected but already exists.

        Should be called *after* form is validated.
        """
        perms = self.cleaned_data[self.get_obj_perms_field_name()]
        model_perms = [c[0] for c in self.get_obj_perms_field_choices()]

        to_remove = set(model_perms) - set(perms)
        for perm in to_remove:
            remove_perm(perm, self.user, self.obj)

        for perm in perms:
            assign_perm(perm, self.user, self.obj)

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

Я думаю, что глобальный параметр, такой как GUARDIAN_FALLBACK_TO_MODEL=False и аргумент для применимых методов, таких как fallback_to_model=False необходимы для правильного определения разрешений объектов и разрешений модели. Значение по умолчанию False обеспечивает обратную совместимость. Если значение параметра global или аргумента равно True, должен произойти откат.

+1 для GUARDIAN_FALLBACK_TO_MODEL.

Согласно обсуждению # 49, я думаю, что этот параметр также может хорошо работать, чтобы контролировать, был ли ObjectPermissionBackend явным или нет.

Я создал запрос на перенос (№ 546). Это позволяет функциям проверки в опции core.py откатиться к разрешениям уровня модели (или включить их). Другие модули также нуждаются в проверке. Я планирую просматривать их по мере использования. Если кто-то захочет вмешаться, добро пожаловать.

Кажется, № 327 больше не существует. # 332 исправляется запросом на перенос выше, если он принят. Осталась только одна побочная проблема, связанная с № 155 (упомянутым выше). Если бы об этом тоже позаботились (или вынесли в отдельный вопрос), я думаю, этот вопрос можно было бы закрыть.

Глобальные разрешения по-прежнему не соблюдаются для разрешений на уровне объекта, если они установлены, я ошибаюсь?

u = User.objects.get(id=1)
c = Client.objects.get(id=1)
assign_perm('core.change_client', u)
u = User.objects.get(id=1)  # reloading user for perm refresh
u.has_perm('core.change_client')  # True
u.has_perm('core.change_client', c)  # False
u.has_perm('change_client', c)  # False
get_perms(u, c)  # []

И что делает установка GUARDIAN_GLOBAL_PERMISSIONS_CARRY_OVER или FALLBACK_TO_MODEL ? Ни то, ни другое не задокументировано.

Разве не было бы достаточно добавить это к core.py ?

get_user_perms:126 который, кажется, является центром проверки всех прав пользователей; альтернативно запускается с использованием логического флага

def get_user_perms(self, obj):
    # ....
    user_global_perms = Permission.objects.filter(content_type=ctype)\
                                        .filter(user=self.user)\
                                        .values_list('codename', flat=True)
    user_object_perms = user_perms_qs.values_list("codename", flat=True)
    user_perms = list(chain(user_global_perms, user_object_perms))
    return user_perms
Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

David-OConnor picture David-OConnor  ·  6Комментарии

BenDevelopment picture BenDevelopment  ·  5Комментарии

g-as picture g-as  ·  10Комментарии

lukaszb picture lukaszb  ·  14Комментарии

ad-m picture ad-m  ·  13Комментарии