From 11e071441133f235c88c0b2509baba56f01f8c58 Mon Sep 17 00:00:00 2001 From: lizerk Date: Fri, 20 Mar 2026 00:55:56 +0300 Subject: [PATCH] Fix: Override build_rdn() to fix ldapdb 1.5.1 bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ldapdb's build_rdn() checks field.primary_key AND field.db_column, but the 'dn' field has primary_key=True and db_column=None, while 'cn'/'ou' fields have db_column set but primary_key=False. No field satisfies both conditions → save() always raises 'Could not build Distinguished Name'. Fix: ModifyDnMixin.build_rdn() extracts RDN from existing DN for loaded objects, and builds from rdn_attributes for new ones. --- backend/employees/ldap/mixins.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/backend/employees/ldap/mixins.py b/backend/employees/ldap/mixins.py index d2727721..8e41a4df 100644 --- a/backend/employees/ldap/mixins.py +++ b/backend/employees/ldap/mixins.py @@ -40,6 +40,29 @@ class ModifyDnMixin: # Сохраняем оригинальный base_dn для отслеживания изменений self._original_base_dn = getattr(self, 'base_dn', None) + def build_rdn(self): + """Build RDN — исправление бага ldapdb 1.5.1. + + ldapdb's build_rdn() проверяет field.primary_key AND field.db_column, + но поле 'dn' имеет primary_key=True и db_column=None, + а 'cn'/'ou' — наоборот. Ни одно поле не подходит → всегда Exception. + + Исправление: для существующих объектов извлекаем RDN из текущего DN, + для новых — строим из rdn_attributes. + """ + # Существующий объект — извлекаем RDN из DN (сохраняет регистр CN/OU) + if self.dn and ',' in self.dn: + return self.dn.split(',', 1)[0] + + # Новый объект — строим из rdn_attributes + rdn_attrs = getattr(self, 'rdn_attributes', []) + for field in self._meta.fields: + if field.db_column and field.db_column in rdn_attrs: + value = getattr(self, field.name) + if value: + return "%s=%s" % (field.db_column, value) + raise Exception("Could not build Distinguished Name") + def save(self, *args, **kwargs): """Переопределённый save с поддержкой modify_dn при изменении base_dn.