Разрешить пользователям без прав суперадминистратора сбрасывать пароль для другого пользователя в админке django

Я работаю над сторонним приложением, работающим под управлением django 2.2.12.

У меня есть администратор с тремя типами пользователей: «суперадмин», «персонал» и «другие».

Когда я вхожу в систему как «суперадмин», когда я перехожу к списку пользователей и нажимаю на пользователя, я могу редактировать их и сбрасывать их пароль.

Однако, когда я пытаюсь сделать то же самое в качестве «штатного» пользователя, я вижу данные пользователя, но не могу ничего редактировать, и нет возможности сбросить пароль. Если я попытаюсь получить доступ к URL-адресу вручную (/admin/accounts/user/[USER_ID]/password/), я получу сообщение об ошибке «403 Forbidden».

Я заметил, что если я переопределяю метод has_perm в пользовательской модели, он позволяет «штатному» пользователю редактировать пользовательские данные. Однако я хотел бы разрешить только изменение пароля (если пользователь не является суперадминистратором или штатным пользователем), не позволяя «штатным» пользователям редактировать других пользователей.

def has_perm(self, perm, obj=None):
    return True

У меня сложилось впечатление, что это связано с системой разрешений Django, но я перечитал документы по адресу https://docs.djangoproject.com/en/2.2/topics/auth/default/ и еще не мог понять это.

Спасибо


person ThiagoAlves    schedule 21.04.2020    source источник
comment
Я думаю, вам понадобится пакет Проверьте этот ответ   -  person Shubham Yadav    schedule 21.04.2020
comment
@ShubhamYadav Спасибо. Посмотрю Можно ли программно разрешить штатным пользователям редактировать Users, но скрыть все его свойства, кроме пароля? Я считаю, что этот обходной путь решит проблему.   -  person ThiagoAlves    schedule 21.04.2020


Ответы (1)


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

В основном я перегружаю метод has_change_permission класса UserAdmin и добавляю пользовательскую логику, позволяющую изменять пароль в особом случае (url-адрес заканчивается на «/password», и у пользователя есть правильные разрешения.

    def can_edit_password(self, logged_user, chosen_user=None):
        if logged_user and logged_user.is_superuser:
            return True

        logged_user_has_change_pass_perm = (
            logged_user and
            logged_user.is_authenticated and
            logged_user.has_perm("accounts.change_student_password")
        )
        return logged_user_has_change_pass_perm

    def can_show_change_password_form(self, path, logged_user, chosen_user=None):
        is_changing_password = path.endswith('/password/')
        return is_changing_password and self.can_edit_password(logged_user, chosen_user)

    def has_change_permission(self, request, user=None):
        if self.can_show_change_password_form(path=request.path, logged_user=request.user, chosen_user=user):
            return True
        return super(UserAdmin, self).has_change_permission(request, user)
person ThiagoAlves    schedule 22.04.2020