diff --git a/backend/employees/ldap/orm_models.py b/backend/employees/ldap/orm_models.py index 7f0ef88c..60967b25 100644 --- a/backend/employees/ldap/orm_models.py +++ b/backend/employees/ldap/orm_models.py @@ -175,8 +175,8 @@ class LdapUser(LdapModel): object_classes = ['top', 'person', 'organizationalPerson', 'user'] # Основные атрибуты - cn = CharField(db_column='cn', primary_key=True) - distinguished_name = CharField(db_column='distinguishedName') + # dn наследуется от ldapdb.models.Model как primary_key (Distinguished Name) + cn = CharField(db_column='cn') # Идентификация object_guid = CharField(db_column='objectGUID') @@ -247,8 +247,8 @@ class LdapGroup(LdapModel): object_classes = ['top', 'group'] # Основные атрибуты - cn = CharField(db_column='cn', primary_key=True) - distinguished_name = CharField(db_column='distinguishedName') + # dn наследуется от ldapdb.models.Model как primary_key (Distinguished Name) + cn = CharField(db_column='cn') # Идентификация object_guid = CharField(db_column='objectGUID') @@ -301,8 +301,8 @@ class LdapOrganizationalUnit(LdapModel): object_classes = ['top', 'organizationalUnit'] # Основные атрибуты - ou = CharField(db_column='ou', primary_key=True) - distinguished_name = CharField(db_column='distinguishedName') + # dn наследуется от ldapdb.models.Model как primary_key (Distinguished Name) + ou = CharField(db_column='ou') # Идентификация object_guid = CharField(db_column='objectGUID') diff --git a/backend/employees/ldap/services/group_service.py b/backend/employees/ldap/services/group_service.py index 374ca704..a92b178e 100644 --- a/backend/employees/ldap/services/group_service.py +++ b/backend/employees/ldap/services/group_service.py @@ -218,12 +218,16 @@ class GroupService: def find_dn( self, conn: Connection, cn: str, bases: Optional[List[str]] = None ) -> Optional[str]: - """Ищет DN группы по CN (ORM).""" - try: - group = LdapGroup.objects.get(cn=cn) + """Ищет DN группы по CN (ORM). + + Warning: Если есть несколько групп с одинаковым CN, + вернёт первую найденную. + """ + # .filter().first() вместо .get() т.к. cn больше не primary_key + group = LdapGroup.objects.filter(cn=cn).first() + if group: return group.dn - except LdapGroup.DoesNotExist: - return None + return None def groups_with_member(self, conn: Connection, member_dn: str) -> Set[str]: """Находит все группы, в которых состоит DN (ORM через memberOf).""" @@ -329,12 +333,16 @@ class GroupService: def find_dn_wrapped( self, cn: str, bases: Optional[list[str]] = None ) -> Optional[str]: - """Ищет DN группы по CN (ORM).""" - try: - group = LdapGroup.objects.get(cn=cn) + """Ищет DN группы по CN (ORM). + + Warning: Если есть несколько групп с одинаковым CN, + вернёт первую найденную. + """ + # .filter().first() вместо .get() т.к. cn больше не primary_key + group = LdapGroup.objects.filter(cn=cn).first() + if group: return group.dn - except LdapGroup.DoesNotExist: - return None + return None def create_wrapped( self, diff --git a/backend/employees/ldap/utils/group_utils_orm.py b/backend/employees/ldap/utils/group_utils_orm.py index 8594cc72..9c501af8 100644 --- a/backend/employees/ldap/utils/group_utils_orm.py +++ b/backend/employees/ldap/utils/group_utils_orm.py @@ -55,16 +55,20 @@ def group_remove_member_orm(group_dn: str, member_dn: str) -> None: def resolve_group_dns_by_cn_orm(cns: set[str]) -> dict[str, str]: - """Ищет DN групп по их CN через ORM.""" + """Ищет DN групп по их CN через ORM. + + Warning: Если есть несколько групп с одинаковым CN в разных OU, + вернёт первую найденную (может быть неправильной). + Рекомендуется использовать DN напрямую вместо CN. + """ if not cns: return {} found: dict[str, str] = {} for cn in sorted(cns): - try: - group = LdapGroup.objects.get(cn=cn) + # .filter().first() вместо .get() т.к. cn больше не primary_key + group = LdapGroup.objects.filter(cn=cn).first() + if group: found[cn] = group.dn - except LdapGroup.DoesNotExist: - continue return found