Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions app/alembic/versions/c5a9b3f2e8d7_add_contact_object_class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"""Add Contact objectClass and mailRecipient to LDAP schema.

Revision ID: c5a9b3f2e8d7
Revises: 8164b4a9e1f1, f1abf7ef2443
Create Date: 2026-01-19 12:00:00.000000

"""

from alembic import op
from dishka import AsyncContainer, Scope
from sqlalchemy import delete
from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession

from entities import EntityType
from enums import EntityTypeNames
from ldap_protocol.ldap_schema.dto import EntityTypeDTO
from ldap_protocol.ldap_schema.entity_type_use_case import EntityTypeUseCase
from ldap_protocol.utils.queries import get_base_directories
from repo.pg.tables import queryable_attr as qa

# revision identifiers, used by Alembic.
revision = "c5a9b3f2e8d7"
down_revision = "71e642808369"
branch_labels: None | str = None
depends_on: None | str = None


def upgrade(container: AsyncContainer) -> None:
"""Add Contact objectClass and mailRecipient to LDAP schema."""

async def _create_entity_type(
connection: AsyncConnection, # noqa: ARG001
) -> None:
"""Create Contact Entity Type."""
async with container(scope=Scope.REQUEST) as cnt:
session = await cnt.get(AsyncSession)
entity_type_use_case = await cnt.get(EntityTypeUseCase)

if not await get_base_directories(session):
return

await entity_type_use_case.create(
EntityTypeDTO(
name=EntityTypeNames.CONTACT,
object_class_names=[
"top",
"person",
"organizationalPerson",
"contact",
"mailRecipient",
],
is_system=True,
),
)

await session.commit()

op.run_async(_create_entity_type)


def downgrade(container: AsyncContainer) -> None:
"""Remove Contact objectClass and mailRecipient from LDAP schema."""

async def _delete_entity_type(
connection: AsyncConnection, # noqa: ARG001
) -> None:
"""Delete Contact Entity Type."""
async with container(scope=Scope.REQUEST) as cnt:
session = await cnt.get(AsyncSession)

if not await get_base_directories(session):
return

await session.execute(
delete(EntityType).where(
qa(EntityType.name) == EntityTypeNames.CONTACT,
),
)

await session.commit()

op.run_async(_delete_entity_type)
10 changes: 10 additions & 0 deletions app/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,16 @@ class EntityTypeData(TypedDict):
"inetOrgPerson",
],
),
EntityTypeData(
name=EntityTypeNames.CONTACT,
object_class_names=[
"top",
"person",
"organizationalPerson",
"contact",
"mailRecipient",
],
),
EntityTypeData(
name=EntityTypeNames.KRB_CONTAINER,
object_class_names=["krbContainer"],
Expand Down
1 change: 1 addition & 0 deletions app/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class EntityTypeNames(StrEnum):
ORGANIZATIONAL_UNIT = "Organizational Unit"
GROUP = "Group"
USER = "User"
CONTACT = "Contact"
KRB_CONTAINER = "KRB Container"
KRB_PRINCIPAL = "KRB Principal"
KRB_REALM_CONTAINER = "KRB Realm Container"
Expand Down
2 changes: 1 addition & 1 deletion interface
7 changes: 5 additions & 2 deletions tests/test_api/test_ldap_schema/test_object_class_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


@pytest.mark.asyncio
async def test_get_one_extended_object_class(
async def test_get_extended_object_classes(
http_client: AsyncClient,
) -> None:
"""Test getting a single extended object class."""
Expand All @@ -26,7 +26,10 @@ async def test_get_one_extended_object_class(
assert response.status_code == status.HTTP_200_OK
data = response.json()
assert isinstance(data, dict)
assert data.get("entity_type_names") == [EntityTypeNames.USER]
assert set(data.get("entity_type_names")) == { # type: ignore
EntityTypeNames.CONTACT,
EntityTypeNames.USER,
}
Comment on lines +29 to +32
Copy link
Collaborator

Choose a reason for hiding this comment

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

название теста тогда поменяй, уже не test_get_one



@pytest.mark.parametrize(
Expand Down