Skip to content

Conversation

@milov-dmitriy
Copy link
Collaborator

@milov-dmitriy milov-dmitriy commented Jan 23, 2026

Исправлено переименование принципалов пользователя и компьютера.

Теперь: При создании компьютера: в таблице атрибуты создается запись sAMAccountName.
Из-за того что: При изменении имени принципала прошлые значения krbprincipalname (или как-то так) не хранятся в базе (в таблице Attributes) - и для обхода этого было сделано "кеширование" на уровне одного ModifyRequest по некоторым условиям.

Для юзера : синхронизированы изменения значений свойств sAMAccountName, UserPrincipalName и имени одного принципала.
Для компьютера : синхронизированы изменения значений свойств sAMAccountName и имени двух принципалов.

Задача: 1186

@milov-dmitriy milov-dmitriy self-assigned this Jan 23, 2026
@milov-dmitriy milov-dmitriy added python Pull requests that update Python code ldap labels Jan 23, 2026
Copilot AI review requested due to automatic review settings January 23, 2026 16:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR synchronizes principal names with sAMAccountName changes for both user and computer entities in LDAP modify operations. When sAMAccountName is modified, the corresponding Kerberos principals are automatically renamed to maintain consistency.

Changes:

  • Added Kerberos principal renaming logic when sAMAccountName or userPrincipalName attributes are modified
  • Implemented caching of old sAMAccountName values during delete operations to enable subsequent rename operations
  • Added comprehensive test coverage for user and computer principal name synchronization

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
app/ldap_protocol/ldap_requests/modify.py Core logic for synchronizing principal names with sAMAccountName/userPrincipalName modifications and caching old values
app/ldap_protocol/ldap_requests/add.py Added sAMAccountName attribute creation for computers; refactored to use sam_account_name instead of get_upn_prefix()
app/ldap_protocol/ldap_requests/extended.py Updated to use sam_account_name instead of deprecated get_upn_prefix() method
app/ldap_protocol/ldap_requests/delete.py Updated to use sam_account_name instead of deprecated get_upn_prefix() method
app/ldap_protocol/ldap_requests/bind.py Updated to use sam_account_name instead of deprecated get_upn_prefix() method
app/ldap_protocol/auth/auth_manager.py Updated to use sam_account_name instead of deprecated get_upn_prefix() method
app/extra/scripts/uac_sync.py Updated to use sam_account_name instead of deprecated get_upn_prefix() method
app/extra/scripts/principal_block_user_sync.py Updated to use sam_account_name instead of deprecated get_upn_prefix() method
app/entities.py Removed deprecated get_upn_prefix() method from User class
tests/test_api/test_main/test_router/test_modify.py Added comprehensive tests for user and computer principal name modification
tests/test_api/test_main/test_router/test_add.py Added test for computer creation with sAMAccountName and assertion for sAMAccountName presence
tests/test_api/test_main/conftest.py Added fixture for creating test computers
interface Updated subproject commit reference

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@milov-dmitriy milov-dmitriy requested a review from Copilot January 26, 2026 09:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@Naksen Naksen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Опиши пожалуйста подробнее:

  1. Для чего необходимо это "кеширование" атрибута
  2. Как именно в твоем представлении оно должно работать

and_(
qa(Attribute.name) == change.modification.type,
func.lower(qa(Attribute.name))
== change.modification.type.lower(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

С чем связано применение здесь .lower() ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

остатки от полета фантазии. отменил
но изначально задумывалось для кейса когда не все значения колонки name таблицы Attributes хранятся в нижнем регистре

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не, это нужно. если нам приходит ModifyRequest: REPLACE: и сохранять старое значение не надо, то не для всех атрибутов это работает корректно, например это работало некорректно для атрибута krbprincipalname (в общий чат скинул пример)

await session.execute(
update(User)
.filter_by(directory=directory)
.values(samaccountname=new_samaccountname),
Copy link
Collaborator

@Naksen Naksen Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а почему если приходит изменение на userprincipalname, то меняется только samaccountname ( и то же самое наоборот) ? и кажется, что можно объединить логику для этих атрибутов

Copy link
Collaborator Author

@milov-dmitriy milov-dmitriy Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

всё дело в строках 959-963 на текущей ветке
при изменении свойства Х - свойство Х поменяет значение, но для этих двух атрибутов нужно менять не только этот атрибут но еще и атрибут, "связанный" с ним, т.е.:

  1. изменяется samaccName - меняем userprincipalname и потом samaccName
  2. изменяется userprincipalname - меняем samaccName и потом userprincipalname

Copy link
Collaborator Author

@milov-dmitriy milov-dmitriy Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

по поводу объединения логик. сначала я так и сделал. но не надо. мне очень не понравилась такая реализация.
с разбиением на две разные ветки гораздо лучше выглядит
если хочешь можем вместе попробовать объединить логику, но мой предыдущий вариант мне не понравилась. все становится более "макаронным" чем есть

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p.s.

  1. для юзера дергаем rename принципала 1 раз
  2. для компьютера дергаем rename принципала 2 раза

@pytest.mark.usefixtures("setup_session")
@pytest.mark.usefixtures("session")
async def test_api_correct_modify(http_client: AsyncClient) -> None:
async def test_api_correct_modify_user(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

этот тест представляет так скажем обычную модификацию атрибута пользователя. Логика обработки sAMAccountName отличается и более комплексная, на мой взгляд лучше вынести её проверку в отдельный тест, чем усложнять лишними проверками уже существующий. Предлагаю стремиться в новых тестах к тому, чтобы проверять только что-то одно.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

согласен, лучше разбить, разбил

Copy link
Collaborator Author

@milov-dmitriy milov-dmitriy Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

итого 3 теста вышло:

  1. для юзера на изменение sAMAccountName
  2. для юзера на изменение userPrincipalName
  3. для компа на изменение sAMAccountName

@milov-dmitriy
Copy link
Collaborator Author

Опиши пожалуйста подробнее:

  1. Для чего необходимо это "кеширование" атрибута
  2. Как именно в твоем представлении оно должно работать

1.1. sAMAccountName у директории юзера хранится в таблице User, мы можем легко получить старое значение, поработать с ним, и заменить на новое значение
1.2. sAMAccountName у директории компьютер хранится в таблице attributes, при ModifyRequest с типом Replace сначала происходит _delete, затем _add, в методе _add нам нужно знать старое значение атрибута sAMAccountName, для этого я сделал сохранение старого значения в словарь

  1. кеширование запоминает старое значение строки из таблицы Attributes для того, чтобы иметь возможность в других протектед методах получить его [старое значнеие]

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@milov-dmitriy
Copy link
Collaborator Author

p.s. я еще переделал get_name() с метода на проперти и имя поменял. стало получше

and directory.entity_type
and directory.entity_type.name == EntityTypeNames.COMPUTER
):
samaccountname_old_val = self._old_vals.get(change.modification.type) # noqa: E501 # fmt: skip
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а если для компьютера придет Modify с add на samaccountname здесь разве не вернется None ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вообще это не корректный запрос в контексте работы с samaccountname
я подумаю

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ну оно не должно упасть в этом случае. Можно зарейзить ModifyForbiddenError думаю

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сделал. тест написал

else:
new_value = value # type: ignore

if change.l_type == "userprincipalname":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может обработку обновления userprincipalname и samaccountname вынести в отдельные методы ? Например:

_add_user_userprincipalname(self, ...)
_add_user_samaccountname(self, ...)
_add_computer_samaccountname(self, ...)

как сделано например с атрибутами группы:

Image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

сыглы, давай да

Copy link
Collaborator

@Naksen Naksen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А так, с l_type стало лучше на мой взгляд

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

elif change.l_type == "samaccountname":
await self._modify_user_samaccountname(
directory,
directory.user,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А зачем передавать и directory и directory.user ? Вроде в directory.user лежит directory_id, то есть можно передать только user, проверь

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

отрефачил)

@milov-dmitriy milov-dmitriy requested a review from Naksen January 27, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ldap python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants