Django Admin, как скрыть изменение пароля?

Некоторые пользователи моего приложения Django приходят с сервера LDAP. Эти пользователи не должны иметь возможность изменить свой пароль django-admin. Лучше всего, если у них его вообще не будет.

Поэтому я подклассифицировал django_auth_ldap.backend.LDAPBackend следующим образом:

from django_auth_ldap.backend import LDAPBackend
from django.contrib.auth import get_user_model

class CustomLDAPBackend(LDAPBackend)  

    def authenticate_ldap_user(self, ldap_user, password):
          
        user = ldap_user.authenticate(password)     
       
        print("BEFORE set_unusable_password(): ", user.has_usable_password())
        user.set_unusable_password()
        user.save()

        print("AFTER set_unusable_password(): ", user.has_usable_password())

        return user
    

В user.set_unusable_password() я пытаюсь скрыть пароль, потому что я читал это в нескольких местах (здесь в SO, а также в docs). Но все, чего я могу добиться, это отсутствие пароля: enter image description here

Более того, если я вхожу в систему несколько раз, результат print("BEFORE set_unusable_password(): ", user.has_usable_password()) всегда True, несмотря на вызов user.set_unusable_password() и сохранение пользователя. Как будто каждый раз создается новый объект пользователя.

Этот вопрос не решает мою проблему, потому что user.set_unusable_password(), очевидно, не скрывает область смены пароля.

Что я упускаю? Как я могу скрыть область "изменить пароль"?

Ниже приведена относящаяся к LDAP часть файла settings.py:

import ldap
from django_auth_ldap.config import LDAPSearch, LDAPGroupQuery,GroupOfNamesType,PosixGroupType


AUTH_LDAP_SERVER_URI = 'ldap://localhost'
AUTH_LDAP_BIND_DN = 'cn=admin,dc=example,dc=com'
AUTH_LDAP_BIND_PASSWORD = 'secret'
AUTH_LDAP_USER_SEARCH = LDAPSearch('dc=example,dc=com',ldap.SCOPE_SUBTREE, '(uid=%(user)s)')
AUTH_LDAP_GROUP_SEARCH = LDAPSearch('dc=example,dc=com',ldap.SCOPE_SUBTREE, '(objectClass=top)')
AUTH_LDAP_GROUP_TYPE = PosixGroupType(name_attr="cn")
AUTH_LDAP_MIRROR_GROUPS = True

    # Populate the Django user from the LDAP directory.
AUTH_LDAP_REQUIRE_GROUP = "cn=enabled,ou=groups,dc=example,dc=com"

AUTH_LDAP_USER_ATTR_MAP = {
        "first_name": "givenName",
        "last_name": "sn",
        "email": "mail",
        "username": "uid",
        "password": "userPassword",
}
AUTH_LDAP_PROFILE_ATTR_MAP = {
        "home_directory": "homeDirectory"
}
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
        "is_active": "cn=active,ou=groups,dc=example,dc=com",
        "is_staff": "cn=staff,ou=groups,dc=example,dc=com",
        "is_superuser": "cn=superuser,ou=groups,dc=example,dc=com"
}
    
AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_CACHE_TIMEOUT = 3600
    
AUTH_LDAP_FIND_GROUP_PERMS = True
    
    # Keep ModelBackend around for per-user permissions and maybe a local
    # superuser.
AUTHENTICATION_BACKENDS = (           
        'django.contrib.auth.backends.ModelBackend',
        'ldappro.backend_ldap.CustomLDAPBackend',       
)

Я наконец-то нашел решение. Переопределение 'LDAPBackend' действительно необходимо, но недостаточно. Оно удаляет 'Changes Password', отмеченный только красным цветом (правый верхний угол): enter image description here

Другая область "Изменить пароль" (отмечена синим цветом, на рисунке ниже) остается нетронутой:

enter image description here

Чтобы избавиться от "синей" области, нам нужно переопределить шаблон следующим образом:

{% extends "admin/change_form.html" %}
{% load i18n %}

{% block field_sets %}
{% for fieldset in adminform %}

  {% if forloop.first and user.has_usable_password %}
    {% include "admin/includes/fieldset.html" %}
  {% endif %}
 
  {% if not forloop.first %}
     {% include "admin/includes/fieldset.html" %}
  {% endif %}

{% endfor %}
{% endblock %}

Этот переопределяющий шаблон html должен называться change_form.html и должен быть размещен как показано ниже (красный круг):

enter image description here

Вернуться на верх