Fix: Don't modify CN via save(), use modify_dn only
AD forbids modifying RDN (CN) through modify_s - must use rename. - Removed LdapUser.save() override that synced cn→displayName (this caused cn to be in modlist → NOT_ALLOWED_ON_RDN error) - user_service now sets displayName explicitly instead of cn - CN is only changed via conn.modify_dn() after save() - Flow: set displayName + other attrs → save() → modify_dn(cn)
This commit is contained in:
parent
7b7e071df1
commit
afd66662ce
@ -264,21 +264,6 @@ class LdapUser(LdapSyncStateMixin, ModifyDnMixin, LdapModel):
|
||||
class Meta:
|
||||
managed = False # Django не управляет схемой LDAP
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""Переопределяем save для автосинхронизации displayName с cn.
|
||||
|
||||
Active Directory обычно синхронизирует displayName с cn,
|
||||
но при обновлении атрибутов через ldapdb это нужно делать вручную.
|
||||
"""
|
||||
# Синхронизируем displayName с cn если cn установлен
|
||||
if self.cn and not self.display_name:
|
||||
self.display_name = self.cn
|
||||
elif self.cn and self.display_name != self.cn:
|
||||
# Если cn изменился, обновляем displayName
|
||||
self.display_name = self.cn
|
||||
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.display_name} ({self.sam_account_name})"
|
||||
|
||||
|
||||
@ -768,10 +768,11 @@ class UserService(BaseService):
|
||||
|
||||
new_cn = " ".join(parts) if parts else get_ldap_str(ldap_user.sam_account_name)
|
||||
|
||||
# Устанавливаем новый cn в объект ДО save()
|
||||
# чтобы LdapUser.save() автоматически обновил displayName
|
||||
# НЕ ставим cn до save() — AD запрещает modify CN через modify_s,
|
||||
# только через rename (modify_dn).
|
||||
# Вместо этого ставим displayName вручную.
|
||||
if new_cn != old_cn:
|
||||
ldap_user.cn = new_cn
|
||||
ldap_user.display_name = new_cn
|
||||
orm_dirty = True
|
||||
|
||||
# 5) Аватар
|
||||
@ -784,10 +785,9 @@ class UserService(BaseService):
|
||||
avatar_saved = True
|
||||
|
||||
if orm_dirty:
|
||||
# save() автоматически синхронизирует displayName с cn (см. LdapUser.save())
|
||||
ldap_user.save()
|
||||
|
||||
# Переименование DN если cn изменился
|
||||
# Переименование DN если cn изменился (через modify_dn, не modify_s)
|
||||
if new_cn and new_cn != old_cn:
|
||||
# Извлекаем текущий контейнер (всё после первой запятой)
|
||||
parts = dn.split(",", 1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user