Как создать пользователя, который может создавать другого пользователя, но не предоставлять разрешения (только предоставлять предварительно определенные групповые разрешения) в django?
Я хочу иметь возможность создать пользователя (в openwisp2, который основан на django), который, в свою очередь, может создать другого пользователя, но не сможет предоставить индивидуальные разрешения для этого пользователя. Для этого нового пользователя должно быть разрешено только предоставление только предварительно определенных групповых разрешений.
Когда я дал пользователю разрешение на добавление пользователя, я увидел, что этот пользователь по умолчанию получает опцию "добавления разрешения" (хотя я не предоставил этому пользователю разрешения "добавления разрешения"). Я заметил, что у этого нового пользователя была привилегия создать суперпользователя, а это было довольно удивительно
1 ответ
К сожалению, с OpenWISP 2 невозможно достичь того, чего вы хотите, из-за того, как работает система пользователей и разрешений django по умолчанию.
Как только пользователь получит разрешение на добавление и изменение сведений о пользователях, он также сможет добавить / удалить флаг суперпользователя для другого пользователя. Поэтому это разрешение должно предоставляться только доверенным пользователям.
Чтобы достичь желаемого, вам нужно изменить класс UserAdmin модуля openwisp-users.
Я пробовал эти изменения, которые, кажется, работают довольно хорошо:
class UserAdmin(BaseUserAdmin, BaseAdmin):
# ... omitting existing code for brevity ...
def get_readonly_fields(self, request, obj=None):
# retrieve readonly fields
fields = super(UserAdmin, self).get_readonly_fields(request, obj)
# do not allow operators to set the is_superuser flag
if not request.user.is_superuser:
fields += fields[:] + ['is_superuser'] # copy to avoid modifying reference
return fields
def has_change_permission(self, request, obj=None):
# do not allow operators to edit details of superusers
# returns 403 if trying to access the change form of a superuser
if obj and obj.is_superuser and not request.user.is_superuser:
return False
return super(UserAdmin, self).has_change_permission(request, obj)
def get_queryset(self, request):
qs = super(UserAdmin, self).get_queryset(request)
# hide superusers from operators (they can't edit their details)
if not request.user.is_superuser:
qs = qs.filter(is_superuser=False)
return qs
Эти изменения реализуют следующие 3 вещи:
- сделать поле is_superuser доступным только для не суперпользователей (или операторов)
- скрыть суперпользователей не суперпользователям в списке пользователей
- явно запретить замену деталей суперпользователей не суперпользователями (операторы)
Эти изменения также могут быть интегрированы в openwisp2. Наслаждайтесь и попробуйте внести свой вклад, если можете (например: откройте вопрос или запрос на получение ответа в openwisp-users)!
PS: я включил эту функцию (плюс тесты и улучшения) в модуль openwisp-users.