Как создать пользователя, который может создавать другого пользователя, но не предоставлять разрешения (только предоставлять предварительно определенные групповые разрешения) в 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.

Другие вопросы по тегам