Кажется, есть ряд ошибок из-за того, что одни процедуры используют глобальные разрешения, а другие - только разрешения объектов. Закроем связанные ошибки и сделаем ссылку на них здесь.
Да этому!
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, так как в нем было больше понимания вопроса о том, нужно ли и как откатиться к глобальным переменным при сбое уровня объекта. Я не уверен, вызывают ли закрытые проблемы уведомление, поэтому я добавляю это сюда.
В зависимости от принимаемых дизайнерских решений я намереваюсь поработать над некоторыми из этих вопросов.
Я буду рад помочь с этими проблемами.
`` ''
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) mehmet = Person.objects.get (first_name = 'Мехмет') get_users_with_perms (школа, attach_perms = True, with_superusers = True, with_group_users = False) assign_perm ('add_school', мехмет, школа) get_users_with_perms (школа, attach_perms = True, with_superusers = True, with_group_users = False) get_users_with_perms (школа, attach_perms = True, with_superusers = False, with_group_users = False)
{
mehmet.is_superuser
Правда
{
{
{
На # 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