diff --git a/backend/employees/ldap/admin.py b/backend/employees/ldap/admin.py index 6f62622d..983238af 100644 --- a/backend/employees/ldap/admin.py +++ b/backend/employees/ldap/admin.py @@ -13,6 +13,7 @@ from django.db.models import OuterRef, Exists from employees.models import Employee, LdapSyncState from .orm_models import LdapUser, LdapGroup, LdapOrganizationalUnit +from .utils.ldap_utils import get_ldap_str class LdapSyncStateInline(admin.TabularInline): @@ -335,10 +336,11 @@ class LdapUserAdmin(admin.ModelAdmin): emp = Employee.objects.get(pk=int(ldap_user.employee_number)) # Обновляем Django из LDAP - emp.first_name = ldap_user.given_name or emp.first_name - emp.last_name = ldap_user.sn or emp.last_name - emp.email = ldap_user.mail or emp.email - emp.phone_number = ldap_user.telephone_number or ldap_user.mobile or emp.phone_number + emp.first_name = get_ldap_str(ldap_user.given_name) or emp.first_name + emp.last_name = get_ldap_str(ldap_user.sn) or emp.last_name + emp.email = get_ldap_str(ldap_user.mail) or emp.email + ldap_phone = get_ldap_str(ldap_user.telephone_number or ldap_user.mobile) + emp.phone_number = ldap_phone or emp.phone_number emp.save() # Обновляем LdapSyncState @@ -444,16 +446,19 @@ class LdapUserAdmin(admin.ModelAdmin): user_diffs = [] # Сравниваем поля - if ldap_user.given_name != emp.first_name: - user_diffs.append(f"Имя: LDAP='{ldap_user.given_name}' vs Django='{emp.first_name}'") + ldap_first = get_ldap_str(ldap_user.given_name) + if ldap_first != emp.first_name: + user_diffs.append(f"Имя: LDAP='{ldap_first}' vs Django='{emp.first_name}'") - if ldap_user.sn != emp.last_name: - user_diffs.append(f"Фамилия: LDAP='{ldap_user.sn}' vs Django='{emp.last_name}'") + ldap_last = get_ldap_str(ldap_user.sn) + if ldap_last != emp.last_name: + user_diffs.append(f"Фамилия: LDAP='{ldap_last}' vs Django='{emp.last_name}'") - if ldap_user.mail != emp.email: - user_diffs.append(f"Email: LDAP='{ldap_user.mail}' vs Django='{emp.email}'") + ldap_email = get_ldap_str(ldap_user.mail) + if ldap_email != emp.email: + user_diffs.append(f"Email: LDAP='{ldap_email}' vs Django='{emp.email}'") - ldap_phone = ldap_user.telephone_number or ldap_user.mobile + ldap_phone = get_ldap_str(ldap_user.telephone_number or ldap_user.mobile) if ldap_phone and ldap_phone != emp.phone_number: user_diffs.append(f"Телефон: LDAP='{ldap_phone}' vs Django='{emp.phone_number}'") diff --git a/backend/employees/ldap/services/user_service.py b/backend/employees/ldap/services/user_service.py index 30211e26..92d9c469 100644 --- a/backend/employees/ldap/services/user_service.py +++ b/backend/employees/ldap/services/user_service.py @@ -32,7 +32,7 @@ from ..infrastructure.connections import _ldap from ..repositories.ldap_repository import ( ensure_container_exists, ) -from ..utils.ldap_utils import cn_candidates +from ..utils.ldap_utils import cn_candidates, get_ldap_str from ..utils.text_utils import esc_rdn from .base_service import BaseService from .constants import ( @@ -47,27 +47,6 @@ from .user_mapper_service import UserMapperService logger = logging.getLogger(__name__) -def _get_ldap_str(value: Any) -> str: - """Безопасно извлекает строковое значение из LDAP поля. - - LDAP поля могут возвращаться как: - - строка (str) - - список строк (list) - - None - - Args: - value: Значение LDAP поля - - Returns: - str: Первый элемент (если список) или само значение (если строка), или пустая строка - """ - if value is None: - return "" - if isinstance(value, list): - return value[0] if value else "" - return str(value) - - class UserService(BaseService): """Сервис для управления пользователями в LDAP и Django. @@ -779,8 +758,8 @@ class UserService(BaseService): if "first_name" in model_changes or "last_name" in model_changes: # Формируем новый cn из имени и фамилии parts = [] - given_name_str = _get_ldap_str(ldap_user.given_name).strip() - sn_str = _get_ldap_str(ldap_user.sn).strip() + given_name_str = get_ldap_str(ldap_user.given_name).strip() + sn_str = get_ldap_str(ldap_user.sn).strip() if given_name_str: parts.append(given_name_str) diff --git a/backend/employees/ldap/utils/ldap_utils.py b/backend/employees/ldap/utils/ldap_utils.py index 90bc932b..30dd98ce 100644 --- a/backend/employees/ldap/utils/ldap_utils.py +++ b/backend/employees/ldap/utils/ldap_utils.py @@ -25,6 +25,28 @@ def _first(val: Any) -> Any: return val +def get_ldap_str(value: Any) -> str: + """Безопасно извлекает строковое значение из LDAP поля. + + LDAP поля могут возвращаться как: + - строка (str) + - список строк (list) + - None + + Args: + value: Значение LDAP поля + + Returns: + str: Первый элемент (если список) или само значение (если строка), + или пустая строка + """ + if value is None: + return "" + if isinstance(value, list): + return value[0] if value else "" + return str(value) + + def _uac_is_active(uac_value: Any) -> bool: """Определяет активность учётной записи по userAccountControl.