From ab3f23f0228c9c18ccf0a92bf995960737ec129b Mon Sep 17 00:00:00 2001 From: TheMihMih Date: Tue, 16 Dec 2025 16:16:13 +0300 Subject: [PATCH 1/2] add dishka container to migrations --- Makefile | 4 +- app/alembic/env.py | 45 +++++++++++++------ app/alembic/script.py.mako | 5 ++- .../01f3f05a5b11_add_primary_group_id.py | 30 ++++--------- .../versions/05ddc0bd562a_add_roles.py | 5 ++- .../16a9fa2c1f1e_rename_readonly_group.py | 5 ++- app/alembic/versions/196f0d327c6a_.py | 5 ++- .../275222846605_initial_ldap_schema.py | 10 +++-- .../versions/35d1542d2505_add_entity_id.py | 5 ++- .../versions/4334e2e871a4_add_sessions_ttl.py | 5 ++- .../4442d1d982a4_remove_krb_policy.py | 5 ++- .../4798b12b97aa_dedicated_servers.py | 5 ++- .../4e8772277cfe_add_web_permissions.py | 5 ++- .../56082d7ac0d4_remove_old_templates.py | 6 ++- app/alembic/versions/59e98bbd8ad8_.py | 5 ++- ...6ec_update_krbadmin_useraccountcontrol_.py | 5 ++- app/alembic/versions/692ae64e0cc5_.py | 5 ++- .../versions/6f8fe2548893_fix_read_only.py | 5 ++- .../versions/8164b4a9e1f1_add_ou_computers.py | 24 +++------- .../8c2bd40dd809_add_protocols_attr.py | 5 ++- ...93ba193c6a53_add_hash_index_on_dir_path.py | 5 ++- .../a7971f00ba4d_index_single_level.py | 5 ++- ...bc16b87d_extend_password_policy_for_api.py | 5 ++- .../ba78cef9700a_initial_entity_type.py | 24 +++------- .../bf435bbd95ff_add_rdn_attr_name.py | 5 ++- .../bv546ccd35fa_fix_krbadmin_attrs.py | 5 ++- .../c007129b7973_renew_sls_gpos_rsops.py | 6 ++- .../c4888c68e221_fix_admin_attr_and_policy.py | 5 ++- .../dafg3a4b22ab_add_preauth_princ.py | 5 ++- ...4c52a613e5_migrate_password_prop_from_E.py | 9 ++-- .../e4d6d99d32bd_add_audit_policies.py | 11 +++-- .../versions/eeaed5989eb0_group_policies.py | 6 ++- ...f1abf7ef2443_add_container_object_class.py | 5 ++- .../versions/f24ed0e49df2_add_filter_anr.py | 5 ++- .../versions/f68a134a3685_add_bypass.py | 5 ++- app/alembic/versions/fafc3d0b11ec_.py | 5 ++- .../versions/fc8b7617c60a_attr_index.py | 5 ++- app/ioc.py | 24 ++++++++++ app/ldap_protocol/session_storage/base.py | 5 --- interface | 2 +- tests/conftest.py | 40 +++++++++++++++++ 41 files changed, 230 insertions(+), 146 deletions(-) diff --git a/Makefile b/Makefile index dd78ff0c8..d529a3b2a 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ launch: ## run standalone app without tty container docker compose run sh -c "alembic upgrade head && python ." downgrade: ## re-run migration - docker exec -it multidirectory_api sh -c\ + docker compose run ldap_server sh -c\ "alembic downgrade -1; alembic upgrade head;" down: ## shutdown services @@ -71,4 +71,4 @@ migrations: ## generate migration file docker compose run ldap_server alembic revision --autogenerate migrate: ## upgrade db - docker compose run ldap_server alembic upgrade head + docker compose run ldap_server python multidirectory.py --migrate \ No newline at end of file diff --git a/app/alembic/env.py b/app/alembic/env.py index fc5acfcc7..76f68b5eb 100644 --- a/app/alembic/env.py +++ b/app/alembic/env.py @@ -4,10 +4,12 @@ from logging.config import fileConfig from alembic import context +from dishka import AsyncContainer, make_async_container from sqlalchemy import Connection, text -from sqlalchemy.ext.asyncio import create_async_engine +from sqlalchemy.ext.asyncio import AsyncConnection from config import Settings +from ioc import MainProvider, MigrationProvider from repo.pg.tables import metadata # this is the Alembic Config object, which provides @@ -22,7 +24,11 @@ target_metadata = metadata -def run_sync_migrations(connection: Connection, schema_name: str) -> None: +def run_sync_migrations( + connection: Connection, + schema_name: str, + dishka_container: AsyncContainer, +) -> None: """Run sync migrations.""" if schema_name != "public": connection.execute(text(f"SET search_path = {schema_name}, public;")) @@ -35,18 +41,20 @@ def run_sync_migrations(connection: Connection, schema_name: str) -> None: ) with context.begin_transaction(): - context.run_migrations() + context.run_migrations(container=dishka_container) -async def run_async_migrations(settings: Settings) -> None: +async def run_async_migrations( + settings: Settings, + dishka_container: AsyncContainer, +) -> None: """Run async migrations.""" - engine = create_async_engine(str(settings.POSTGRES_URI)) - - async with engine.connect() as connection: - await connection.run_sync( - run_sync_migrations, - schema_name=settings.TEST_POSTGRES_SCHEMA, - ) + connection = await dishka_container.get(AsyncConnection) + await connection.run_sync( + run_sync_migrations, + schema_name=settings.TEST_POSTGRES_SCHEMA, + dishka_container=dishka_container, + ) def run_migrations_online() -> None: @@ -60,11 +68,22 @@ def run_migrations_online() -> None: "app_settings", Settings.from_os(), ) + dishka_container = context.config.attributes.get("dishka_container", None) + if not dishka_container: + dishka_container = make_async_container( + MainProvider(), + MigrationProvider(), + context={Settings: settings}, + ) if conn is None: - asyncio.run(run_async_migrations(settings)) + asyncio.run(run_async_migrations(settings, dishka_container)) else: - run_sync_migrations(conn, schema_name=settings.TEST_POSTGRES_SCHEMA) + run_sync_migrations( + conn, + schema_name=settings.TEST_POSTGRES_SCHEMA, + dishka_container=dishka_container, + ) run_migrations_online() diff --git a/app/alembic/script.py.mako b/app/alembic/script.py.mako index cc49f4c6c..b2cdf925a 100644 --- a/app/alembic/script.py.mako +++ b/app/alembic/script.py.mako @@ -7,6 +7,7 @@ Create Date: ${create_date} """ from alembic import op import sqlalchemy as sa +from dishka import AsyncContainer ${imports if imports else ""} # revision identifiers, used by Alembic. @@ -16,11 +17,11 @@ branch_labels: None | list[str] = ${repr(branch_labels)} depends_on: None | list[str] = ${repr(depends_on)} -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" ${upgrades if upgrades else "pass"} -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" ${downgrades if downgrades else "pass"} diff --git a/app/alembic/versions/01f3f05a5b11_add_primary_group_id.py b/app/alembic/versions/01f3f05a5b11_add_primary_group_id.py index 237a558ab..04ca6d52f 100644 --- a/app/alembic/versions/01f3f05a5b11_add_primary_group_id.py +++ b/app/alembic/versions/01f3f05a5b11_add_primary_group_id.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer, Scope from sqlalchemy import delete, exists, select from sqlalchemy.exc import DBAPIError, IntegrityError from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -14,9 +15,6 @@ from entities import Attribute, Directory, EntityType, Group from ldap_protocol.ldap_schema.entity_type_dao import EntityTypeDAO -from ldap_protocol.ldap_schema.object_class_dao import ObjectClassDAO -from ldap_protocol.roles.ace_dao import AccessControlEntryDAO -from ldap_protocol.roles.role_dao import RoleDAO from ldap_protocol.roles.role_use_case import RoleUseCase from ldap_protocol.utils.queries import ( create_group, @@ -33,26 +31,19 @@ depends_on: None = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" - async def _add_domain_computers_group(connection: AsyncConnection) -> None: - session = AsyncSession(connection) - await session.begin() + async def _add_domain_computers_group(connection: AsyncConnection) -> None: # noqa: ARG001 + async with container(scope=Scope.REQUEST) as cnt: + session = await cnt.get(AsyncSession) + entity_type_dao = await cnt.get(EntityTypeDAO) + role_use_case = await cnt.get(RoleUseCase) base_dn_list = await get_base_directories(session) if not base_dn_list: return - object_class_dao = ObjectClassDAO(session) - entity_type_dao = EntityTypeDAO( - session, - object_class_dao=object_class_dao, - ) - role_dao = RoleDAO(session) - ace_dao = AccessControlEntryDAO(session) - role_use_case = RoleUseCase(role_dao, ace_dao) - try: group_dir_query = select( exists(Directory) @@ -118,7 +109,6 @@ async def _add_domain_computers_group(connection: AsyncConnection) -> None: async def _add_primary_group_id(connection: AsyncConnection) -> None: session = AsyncSession(connection) - await session.begin() base_dn_list = await get_base_directories(session) if not base_dn_list: @@ -160,12 +150,10 @@ async def _add_primary_group_id(connection: AsyncConnection) -> None: except (IntegrityError, DBAPIError): pass - await session.close() - op.run_async(_add_primary_group_id) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -174,8 +162,6 @@ async def _delete_domain_computers_group( connection: AsyncConnection, ) -> None: session = AsyncSession(connection) - await session.begin() - base_dn_list = await get_base_directories(session) if not base_dn_list: return diff --git a/app/alembic/versions/05ddc0bd562a_add_roles.py b/app/alembic/versions/05ddc0bd562a_add_roles.py index dd1205544..5a4f83a50 100644 --- a/app/alembic/versions/05ddc0bd562a_add_roles.py +++ b/app/alembic/versions/05ddc0bd562a_add_roles.py @@ -7,6 +7,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -24,7 +25,7 @@ depends_on: None = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.create_table( "Roles", @@ -184,7 +185,7 @@ async def _create_system_roles(connection: AsyncConnection) -> None: op.run_async(_create_system_roles) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.create_table( "AccessPolicies", diff --git a/app/alembic/versions/16a9fa2c1f1e_rename_readonly_group.py b/app/alembic/versions/16a9fa2c1f1e_rename_readonly_group.py index 06af9c227..0f9ba47e0 100644 --- a/app/alembic/versions/16a9fa2c1f1e_rename_readonly_group.py +++ b/app/alembic/versions/16a9fa2c1f1e_rename_readonly_group.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer from sqlalchemy import select, update from sqlalchemy.exc import DBAPIError, IntegrityError from sqlalchemy.orm import Session, selectinload @@ -21,7 +22,7 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -72,7 +73,7 @@ def upgrade() -> None: session.close() -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" bind = op.get_bind() session = Session(bind=bind) diff --git a/app/alembic/versions/196f0d327c6a_.py b/app/alembic/versions/196f0d327c6a_.py index 4faf37682..877b27be6 100644 --- a/app/alembic/versions/196f0d327c6a_.py +++ b/app/alembic/versions/196f0d327c6a_.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision = "196f0d327c6a" @@ -15,7 +16,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.drop_constraint( "AccessPolicyMemberships_policy_id_fkey", @@ -201,7 +202,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_constraint( "PolicyMemberships_policy_id_fkey", diff --git a/app/alembic/versions/275222846605_initial_ldap_schema.py b/app/alembic/versions/275222846605_initial_ldap_schema.py index 82957bf42..bbf8fe117 100644 --- a/app/alembic/versions/275222846605_initial_ldap_schema.py +++ b/app/alembic/versions/275222846605_initial_ldap_schema.py @@ -10,6 +10,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer, Scope from ldap3.protocol.schemas.ad2012R2 import ad_2012_r2_schema from sqlalchemy import delete, or_ from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -36,7 +37,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -371,8 +372,9 @@ async def _modify_object_classes(connection: AsyncConnection) -> None: session = AsyncSession(bind=connection) await session.begin() - at_dao = AttributeTypeDAO(session) - oc_dao = ObjectClassDAO(session) + async with container(scope=Scope.REQUEST) as cnt: + at_dao = await cnt.get(AttributeTypeDAO) + oc_dao = await cnt.get(ObjectClassDAO) for oc_name, at_names in ( ("user", ["nsAccountLock", "shadowExpire"]), @@ -393,7 +395,7 @@ async def _modify_object_classes(connection: AsyncConnection) -> None: session.commit() -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_index( "idx_object_classes_name_gin_trgm", diff --git a/app/alembic/versions/35d1542d2505_add_entity_id.py b/app/alembic/versions/35d1542d2505_add_entity_id.py index 4a3d6009d..2e0c020bd 100644 --- a/app/alembic/versions/35d1542d2505_add_entity_id.py +++ b/app/alembic/versions/35d1542d2505_add_entity_id.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy.sql import text # revision identifiers, used by Alembic. @@ -17,7 +18,7 @@ depends_on: None = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.add_column( "EntityTypes", @@ -87,7 +88,7 @@ def upgrade() -> None: op.drop_column("Directory", "entity_type_name") -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.add_column( "Directory", diff --git a/app/alembic/versions/4334e2e871a4_add_sessions_ttl.py b/app/alembic/versions/4334e2e871a4_add_sessions_ttl.py index e656fd296..583a11afc 100644 --- a/app/alembic/versions/4334e2e871a4_add_sessions_ttl.py +++ b/app/alembic/versions/4334e2e871a4_add_sessions_ttl.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision = "4334e2e871a4" @@ -16,7 +17,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.add_column( "Policies", @@ -38,7 +39,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_column("Policies", "http_session_ttl") op.drop_column("Policies", "ldap_session_ttl") diff --git a/app/alembic/versions/4442d1d982a4_remove_krb_policy.py b/app/alembic/versions/4442d1d982a4_remove_krb_policy.py index 92d706192..919b0e104 100644 --- a/app/alembic/versions/4442d1d982a4_remove_krb_policy.py +++ b/app/alembic/versions/4442d1d982a4_remove_krb_policy.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer from sqlalchemy import delete from sqlalchemy.orm import Session @@ -21,7 +22,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -29,5 +30,5 @@ def upgrade() -> None: session.execute(delete(Attribute).filter_by(name="krbpwdpolicyreference")) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" diff --git a/app/alembic/versions/4798b12b97aa_dedicated_servers.py b/app/alembic/versions/4798b12b97aa_dedicated_servers.py index 460e36d20..ae625df78 100644 --- a/app/alembic/versions/4798b12b97aa_dedicated_servers.py +++ b/app/alembic/versions/4798b12b97aa_dedicated_servers.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from loguru import logger from sqlalchemy.orm import Session @@ -21,7 +22,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.create_table( "DedicatedServer", @@ -88,7 +89,7 @@ def upgrade() -> None: session.commit() -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" bind = op.get_bind() session = Session(bind=bind) diff --git a/app/alembic/versions/4e8772277cfe_add_web_permissions.py b/app/alembic/versions/4e8772277cfe_add_web_permissions.py index 437bcea4f..5381ad7e7 100644 --- a/app/alembic/versions/4e8772277cfe_add_web_permissions.py +++ b/app/alembic/versions/4e8772277cfe_add_web_permissions.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer from sqlalchemy import Column, select, text from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -21,7 +22,7 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" async def _add_api_permissions(connection: AsyncConnection) -> None: @@ -48,6 +49,6 @@ async def _add_api_permissions(connection: AsyncConnection) -> None: op.run_async(_add_api_permissions) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_column("Roles", "permissions") diff --git a/app/alembic/versions/56082d7ac0d4_remove_old_templates.py b/app/alembic/versions/56082d7ac0d4_remove_old_templates.py index b2dd56e0c..655ab9bc6 100644 --- a/app/alembic/versions/56082d7ac0d4_remove_old_templates.py +++ b/app/alembic/versions/56082d7ac0d4_remove_old_templates.py @@ -6,6 +6,8 @@ """ +from dishka import AsyncContainer + # revision identifiers, used by Alembic. revision: None | str = "56082d7ac0d4" down_revision: None | str = "16a9fa2c1f1e" @@ -13,9 +15,9 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" diff --git a/app/alembic/versions/59e98bbd8ad8_.py b/app/alembic/versions/59e98bbd8ad8_.py index 810ca7178..aa8ba7145 100644 --- a/app/alembic/versions/59e98bbd8ad8_.py +++ b/app/alembic/versions/59e98bbd8ad8_.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. @@ -17,7 +18,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.create_table( "AccessPolicies", @@ -331,7 +332,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_index("ix_directory_objectGUID", table_name="Directory") op.drop_index(op.f("ix_Directory_path"), table_name="Directory") diff --git a/app/alembic/versions/6303f5c706ec_update_krbadmin_useraccountcontrol_.py b/app/alembic/versions/6303f5c706ec_update_krbadmin_useraccountcontrol_.py index f01dd0b00..d71ea9c05 100644 --- a/app/alembic/versions/6303f5c706ec_update_krbadmin_useraccountcontrol_.py +++ b/app/alembic/versions/6303f5c706ec_update_krbadmin_useraccountcontrol_.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer from sqlalchemy import select, update from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession from sqlalchemy.orm import joinedload @@ -23,7 +24,7 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" async def _update_krbadmin_uac(connection: AsyncConnection) -> None: @@ -89,7 +90,7 @@ async def _change_uid_admin(connection: AsyncConnection) -> None: op.run_async(_change_uid_admin) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" async def _downgrade_krbadmin_uac(connection: AsyncConnection) -> None: diff --git a/app/alembic/versions/692ae64e0cc5_.py b/app/alembic/versions/692ae64e0cc5_.py index e2cef3b6b..60e46018e 100755 --- a/app/alembic/versions/692ae64e0cc5_.py +++ b/app/alembic/versions/692ae64e0cc5_.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision = "692ae64e0cc5" @@ -15,7 +16,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" # ### commands auto generated by Alembic - please adjust! ### op.create_unique_constraint( @@ -26,7 +27,7 @@ def upgrade() -> None: # ### end Alembic commands ### -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" # ### commands auto generated by Alembic - please adjust! ### op.drop_constraint( diff --git a/app/alembic/versions/6f8fe2548893_fix_read_only.py b/app/alembic/versions/6f8fe2548893_fix_read_only.py index f190cb676..1717c0124 100644 --- a/app/alembic/versions/6f8fe2548893_fix_read_only.py +++ b/app/alembic/versions/6f8fe2548893_fix_read_only.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer from sqlalchemy import delete, select, update from sqlalchemy.orm import Session @@ -22,7 +23,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -84,5 +85,5 @@ def upgrade() -> None: session.commit() -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" diff --git a/app/alembic/versions/8164b4a9e1f1_add_ou_computers.py b/app/alembic/versions/8164b4a9e1f1_add_ou_computers.py index 8d6ab8b18..f53db528a 100644 --- a/app/alembic/versions/8164b4a9e1f1_add_ou_computers.py +++ b/app/alembic/versions/8164b4a9e1f1_add_ou_computers.py @@ -7,17 +7,13 @@ """ from alembic import op +from dishka import AsyncContainer, Scope from sqlalchemy import delete, exists, select from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession from entities import Directory -from ldap_protocol.ldap_schema.entity_type_dao import EntityTypeDAO -from ldap_protocol.ldap_schema.object_class_dao import ObjectClassDAO -from ldap_protocol.roles.ace_dao import AccessControlEntryDAO -from ldap_protocol.roles.role_dao import RoleDAO from ldap_protocol.roles.role_use_case import RoleUseCase from ldap_protocol.utils.queries import get_base_directories -from password_utils import PasswordUtils from repo.pg.tables import queryable_attr as qa # revision identifiers, used by Alembic. @@ -35,20 +31,17 @@ } -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" from ldap_protocol.auth.setup_gateway import SetupGateway async def _create_ou_computers(connection: AsyncConnection) -> None: session = AsyncSession(bind=connection) await session.begin() - object_class_dao = ObjectClassDAO(session) - entity_type_dao = EntityTypeDAO(session, object_class_dao) - setup_gateway = SetupGateway( - session, - PasswordUtils(), - entity_type_dao, - ) + + async with container(scope=Scope.REQUEST) as cnt: + setup_gateway = await cnt.get(SetupGateway) + role_use_case = await cnt.get(RoleUseCase) base_directories = await get_base_directories(session) if not base_directories: @@ -77,9 +70,6 @@ async def _create_ou_computers(connection: AsyncConnection) -> None: if not ou_computers_dir: raise Exception("Directory 'ou=computers' not found.") - role_dao = RoleDAO(session) - ace_dao = AccessControlEntryDAO(session) - role_use_case = RoleUseCase(role_dao, ace_dao) await role_use_case.inherit_parent_aces( parent_directory=domain_dir, directory=ou_computers_dir, @@ -90,7 +80,7 @@ async def _create_ou_computers(connection: AsyncConnection) -> None: op.run_async(_create_ou_computers) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" async def _delete_ou_computers(connection: AsyncConnection) -> None: diff --git a/app/alembic/versions/8c2bd40dd809_add_protocols_attr.py b/app/alembic/versions/8c2bd40dd809_add_protocols_attr.py index 8d83c9170..b18a512ea 100644 --- a/app/alembic/versions/8c2bd40dd809_add_protocols_attr.py +++ b/app/alembic/versions/8c2bd40dd809_add_protocols_attr.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision = "8c2bd40dd809" @@ -16,7 +17,7 @@ depends_on: None = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" for protocol_field in ("is_http", "is_ldap", "is_kerberos"): op.add_column( @@ -30,7 +31,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" for protocol_field in ("is_http", "is_ldap", "is_kerberos"): op.drop_column("Policies", protocol_field) diff --git a/app/alembic/versions/93ba193c6a53_add_hash_index_on_dir_path.py b/app/alembic/versions/93ba193c6a53_add_hash_index_on_dir_path.py index 37baac07c..5610e4661 100644 --- a/app/alembic/versions/93ba193c6a53_add_hash_index_on_dir_path.py +++ b/app/alembic/versions/93ba193c6a53_add_hash_index_on_dir_path.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision: None | str = "93ba193c6a53" @@ -16,7 +17,7 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.execute( sa.text( @@ -26,6 +27,6 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.execute(sa.text("DROP INDEX idx_directory_path_hash")) diff --git a/app/alembic/versions/a7971f00ba4d_index_single_level.py b/app/alembic/versions/a7971f00ba4d_index_single_level.py index 611594085..0a147ea98 100644 --- a/app/alembic/versions/a7971f00ba4d_index_single_level.py +++ b/app/alembic/versions/a7971f00ba4d_index_single_level.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision = "a7971f00ba4d" @@ -16,7 +17,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Create index for Directory depth field.""" op.execute( sa.text( @@ -89,7 +90,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Remove indexes for Directory depth field and Attributes table.""" op.drop_index("idx_User_san_gin", "Users") op.drop_index("idx_User_upn_gin", "Users") diff --git a/app/alembic/versions/ad52bc16b87d_extend_password_policy_for_api.py b/app/alembic/versions/ad52bc16b87d_extend_password_policy_for_api.py index 5246e47c3..26b592787 100644 --- a/app/alembic/versions/ad52bc16b87d_extend_password_policy_for_api.py +++ b/app/alembic/versions/ad52bc16b87d_extend_password_policy_for_api.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy import update from sqlalchemy.orm import Session @@ -23,7 +24,7 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -101,7 +102,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_table("GroupPasswordPolicyMemberships") diff --git a/app/alembic/versions/ba78cef9700a_initial_entity_type.py b/app/alembic/versions/ba78cef9700a_initial_entity_type.py index 1e46ed611..2770ebe29 100644 --- a/app/alembic/versions/ba78cef9700a_initial_entity_type.py +++ b/app/alembic/versions/ba78cef9700a_initial_entity_type.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer, Scope from sqlalchemy import exists, or_, select from sqlalchemy.dialects import postgresql from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -18,7 +19,6 @@ from ldap_protocol.ldap_schema.dto import EntityTypeDTO from ldap_protocol.ldap_schema.entity_type_dao import EntityTypeDAO from ldap_protocol.ldap_schema.entity_type_use_case import EntityTypeUseCase -from ldap_protocol.ldap_schema.object_class_dao import ObjectClassDAO from ldap_protocol.utils.queries import get_base_directories from repo.pg.tables import queryable_attr as qa @@ -30,7 +30,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade database schema and data, creating Entity Types.""" op.create_table( "EntityTypes", @@ -103,15 +103,8 @@ async def _create_entity_types(connection: AsyncConnection) -> None: if not await get_base_directories(session): return - object_class_dao = ObjectClassDAO(session) - entity_type_dao = EntityTypeDAO( - session, - object_class_dao=object_class_dao, - ) - entity_type_use_case = EntityTypeUseCase( - entity_type_dao, - object_class_dao, - ) + async with container(scope=Scope.REQUEST) as cnt: + entity_type_use_case = await cnt.get(EntityTypeUseCase) for entity_type_data in ENTITY_TYPE_DATAS: await entity_type_use_case.create( @@ -171,11 +164,8 @@ async def _attach_entity_type_to_directories( if not await get_base_directories(session): return - object_class_dao = ObjectClassDAO(session) - entity_type_dao = EntityTypeDAO( - session, - object_class_dao=object_class_dao, - ) + async with container(scope=Scope.REQUEST) as cnt: + entity_type_dao = await cnt.get(EntityTypeDAO) await entity_type_dao.attach_entity_type_to_directories() @@ -187,7 +177,7 @@ async def _attach_entity_type_to_directories( op.drop_column("EntityTypes", "id") -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade database schema and data back to the previous state.""" op.drop_index( "idx_entity_types_name_gin_trgm", diff --git a/app/alembic/versions/bf435bbd95ff_add_rdn_attr_name.py b/app/alembic/versions/bf435bbd95ff_add_rdn_attr_name.py index c0a1342f9..3ba82ea7d 100644 --- a/app/alembic/versions/bf435bbd95ff_add_rdn_attr_name.py +++ b/app/alembic/versions/bf435bbd95ff_add_rdn_attr_name.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy.orm import Session from entities import Attribute, Directory @@ -22,7 +23,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.add_column("Directory", sa.Column("rdname", sa.String(length=64))) @@ -57,7 +58,7 @@ def upgrade() -> None: @temporary_stub_entity_type_name -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" bind = op.get_bind() session = Session(bind=bind) diff --git a/app/alembic/versions/bv546ccd35fa_fix_krbadmin_attrs.py b/app/alembic/versions/bv546ccd35fa_fix_krbadmin_attrs.py index 1f4c7ac0f..53979d701 100644 --- a/app/alembic/versions/bv546ccd35fa_fix_krbadmin_attrs.py +++ b/app/alembic/versions/bv546ccd35fa_fix_krbadmin_attrs.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy.orm import Session from entities import Attribute, Directory @@ -22,7 +23,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -79,5 +80,5 @@ def upgrade() -> None: session.commit() -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" diff --git a/app/alembic/versions/c007129b7973_renew_sls_gpos_rsops.py b/app/alembic/versions/c007129b7973_renew_sls_gpos_rsops.py index 1e3b7c40c..bc6bb3701 100644 --- a/app/alembic/versions/c007129b7973_renew_sls_gpos_rsops.py +++ b/app/alembic/versions/c007129b7973_renew_sls_gpos_rsops.py @@ -6,6 +6,8 @@ """ +from dishka import AsyncContainer + # revision identifiers, used by Alembic. revision: None | str = "c007129b7973" down_revision: None | str = "8164b4a9e1f1" @@ -13,9 +15,9 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" diff --git a/app/alembic/versions/c4888c68e221_fix_admin_attr_and_policy.py b/app/alembic/versions/c4888c68e221_fix_admin_attr_and_policy.py index bbd904958..c8d47a7fc 100644 --- a/app/alembic/versions/c4888c68e221_fix_admin_attr_and_policy.py +++ b/app/alembic/versions/c4888c68e221_fix_admin_attr_and_policy.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession from sqlalchemy.orm import joinedload @@ -25,7 +26,7 @@ depends_on: None | list[str] = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" async def _attach_entity_type_to_directories( @@ -101,5 +102,5 @@ async def _change_ldap_session_ttl(connection: AsyncConnection) -> None: op.run_async(_attach_entity_type_to_directories) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" diff --git a/app/alembic/versions/dafg3a4b22ab_add_preauth_princ.py b/app/alembic/versions/dafg3a4b22ab_add_preauth_princ.py index 06731ae67..e7b426043 100644 --- a/app/alembic/versions/dafg3a4b22ab_add_preauth_princ.py +++ b/app/alembic/versions/dafg3a4b22ab_add_preauth_princ.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy.orm import Session from entities import Attribute, CatalogueSetting, User @@ -23,7 +24,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -76,7 +77,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_index(op.f("ix_Settings_name"), table_name="Settings") op.create_index( diff --git a/app/alembic/versions/df4c52a613e5_migrate_password_prop_from_E.py b/app/alembic/versions/df4c52a613e5_migrate_password_prop_from_E.py index d1c078db1..6fef5b0bc 100644 --- a/app/alembic/versions/df4c52a613e5_migrate_password_prop_from_E.py +++ b/app/alembic/versions/df4c52a613e5_migrate_password_prop_from_E.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer, Scope from sqlalchemy import update from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession from sqlalchemy.orm import Session @@ -27,7 +28,7 @@ _BAN_WORDS = set(f.read().split("\n")) -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -49,7 +50,9 @@ async def _create_common_passwords(connection: AsyncConnection) -> None: session = AsyncSession(bind=connection) await session.begin() - password_ban_word_repo = PasswordBanWordRepository(session) + async with container(scope=Scope.REQUEST) as cnt: + password_ban_word_repo = await cnt.get(PasswordBanWordRepository) + await password_ban_word_repo.replace(_BAN_WORDS) await session.commit() @@ -256,7 +259,7 @@ async def _create_common_passwords(connection: AsyncConnection) -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.execute( sa.text("DROP INDEX IF EXISTS idx_password_ban_words_word_gin_trgm"), diff --git a/app/alembic/versions/e4d6d99d32bd_add_audit_policies.py b/app/alembic/versions/e4d6d99d32bd_add_audit_policies.py index 77ad0f091..9fdd83900 100644 --- a/app/alembic/versions/e4d6d99d32bd_add_audit_policies.py +++ b/app/alembic/versions/e4d6d99d32bd_add_audit_policies.py @@ -10,6 +10,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer, Scope from sqlalchemy.dialects import postgresql from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -26,7 +27,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" async def _create_audit_policies(connection: AsyncConnection) -> None: @@ -34,8 +35,10 @@ async def _create_audit_policies(connection: AsyncConnection) -> None: if not await get_base_directories(session): return - audit_dao = AuditPoliciesDAO(session) - dest_dao = AuditDestinationDAO(session) + + async with container(scope=Scope.REQUEST) as cnt: + audit_dao = await cnt.get(AuditPoliciesDAO) + dest_dao = await cnt.get(AuditDestinationDAO) manager = Mock(spec=RawAuditManager) use_case = AuditUseCase(audit_dao, dest_dao, manager) await use_case.create_policies() @@ -139,7 +142,7 @@ async def _create_audit_policies(connection: AsyncConnection) -> None: op.run_async(_create_audit_policies) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_table("AuditPolicyTriggers") op.drop_table("AuditPolicies") diff --git a/app/alembic/versions/eeaed5989eb0_group_policies.py b/app/alembic/versions/eeaed5989eb0_group_policies.py index 49b46fed6..de76492b8 100644 --- a/app/alembic/versions/eeaed5989eb0_group_policies.py +++ b/app/alembic/versions/eeaed5989eb0_group_policies.py @@ -6,6 +6,8 @@ """ +from dishka import AsyncContainer + # revision identifiers, used by Alembic. revision = "eeaed5989eb0" down_revision = "e4d6d99d32bd" @@ -13,9 +15,9 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: """Upgrade.""" -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: """Downgrade.""" diff --git a/app/alembic/versions/f1abf7ef2443_add_container_object_class.py b/app/alembic/versions/f1abf7ef2443_add_container_object_class.py index d879bd591..e4679d9f8 100644 --- a/app/alembic/versions/f1abf7ef2443_add_container_object_class.py +++ b/app/alembic/versions/f1abf7ef2443_add_container_object_class.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer from sqlalchemy import delete, func, insert, select, update from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -20,7 +21,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" async def _migrate_ou_to_cn_containers( @@ -105,7 +106,7 @@ async def _migrate_ou_to_cn_containers( op.run_async(_migrate_ou_to_cn_containers) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" async def _migrate_cn_to_ou_containers( diff --git a/app/alembic/versions/f24ed0e49df2_add_filter_anr.py b/app/alembic/versions/f24ed0e49df2_add_filter_anr.py index 991da67c7..b6ec3ee1a 100644 --- a/app/alembic/versions/f24ed0e49df2_add_filter_anr.py +++ b/app/alembic/versions/f24ed0e49df2_add_filter_anr.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer from sqlalchemy.dialects import postgresql from sqlalchemy.orm import Session @@ -34,7 +35,7 @@ ) -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" bind = op.get_bind() session = Session(bind=bind) @@ -67,7 +68,7 @@ def upgrade() -> None: session.commit() -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.alter_column( "EntityTypes", diff --git a/app/alembic/versions/f68a134a3685_add_bypass.py b/app/alembic/versions/f68a134a3685_add_bypass.py index c39e0136d..fe8b90e23 100644 --- a/app/alembic/versions/f68a134a3685_add_bypass.py +++ b/app/alembic/versions/f68a134a3685_add_bypass.py @@ -8,6 +8,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision = "f68a134a3685" @@ -16,7 +17,7 @@ depends_on: None | str = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" op.add_column( "Policies", @@ -38,7 +39,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" op.drop_column("Policies", "bypass_service_failure") op.drop_column("Policies", "bypass_no_connection") diff --git a/app/alembic/versions/fafc3d0b11ec_.py b/app/alembic/versions/fafc3d0b11ec_.py index 40ce32bab..9cd271bb9 100644 --- a/app/alembic/versions/fafc3d0b11ec_.py +++ b/app/alembic/versions/fafc3d0b11ec_.py @@ -7,6 +7,7 @@ """ from alembic import op +from dishka import AsyncContainer from sqlalchemy import delete, exists, select from sqlalchemy.exc import DBAPIError, IntegrityError from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession @@ -28,7 +29,7 @@ @temporary_stub_entity_type_name -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Upgrade.""" async def _create_readonly_grp_and_plcy( @@ -66,7 +67,7 @@ async def _create_readonly_grp_and_plcy( @temporary_stub_entity_type_name -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Downgrade.""" async def _delete_readonly_grp_and_plcy( diff --git a/app/alembic/versions/fc8b7617c60a_attr_index.py b/app/alembic/versions/fc8b7617c60a_attr_index.py index 4ce948f4c..ced401ee1 100644 --- a/app/alembic/versions/fc8b7617c60a_attr_index.py +++ b/app/alembic/versions/fc8b7617c60a_attr_index.py @@ -7,6 +7,7 @@ import sqlalchemy as sa from alembic import op +from dishka import AsyncContainer # revision identifiers, used by Alembic. revision = "fc8b7617c60a" @@ -15,7 +16,7 @@ depends_on: str | None = None -def upgrade() -> None: +def upgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Create index for Attribute name field.""" op.execute( sa.text( @@ -31,7 +32,7 @@ def upgrade() -> None: ) -def downgrade() -> None: +def downgrade(container: AsyncContainer) -> None: # noqa: ARG001 """Drop index for Attribute name field.""" op.execute(sa.text("DROP INDEX idx_attributes_lw_name_btree")) op.execute(sa.text("DROP INDEX idx_attributes_name_gin_trgm")) diff --git a/app/ioc.py b/app/ioc.py index 2c733e6a8..0e2af189e 100644 --- a/app/ioc.py +++ b/app/ioc.py @@ -12,6 +12,7 @@ from fastapi import Request from loguru import logger from sqlalchemy.ext.asyncio import ( + AsyncConnection, AsyncEngine, AsyncSession, async_sessionmaker, @@ -783,3 +784,26 @@ async def get_ldap_mfa( settings, ), ) + + +class MigrationProvider(Provider): + """Provider for migrations.""" + + scope = Scope.APP + + @provide(scope=Scope.APP) + async def get_session_factory( + self, + connection: AsyncConnection, + ) -> AsyncSession: + """Create session factory.""" + return AsyncSession(connection) + + @provide(scope=Scope.APP) + async def get_conn_factory( + self, + engine: AsyncEngine, + ) -> AsyncIterator[AsyncConnection]: + """Create session factory.""" + async with engine.connect() as connection: + yield connection diff --git a/app/ldap_protocol/session_storage/base.py b/app/ldap_protocol/session_storage/base.py index cc5724159..f4f9b3ac7 100644 --- a/app/ldap_protocol/session_storage/base.py +++ b/app/ldap_protocol/session_storage/base.py @@ -9,8 +9,6 @@ from secrets import token_hex from typing import Literal, Self -from loguru import logger - from config import Settings from .exceptions import ( @@ -175,9 +173,6 @@ async def get_user_id( raise SessionStorageInvalidKeyError("Invalid payload key") try: - logger.debug( - f"Retrieving session data for session_id: {session_id}", - ) data = await self.get(session_id) except KeyError: raise SessionStorageInvalidKeyError("Invalid session key") diff --git a/interface b/interface index 21b31fed4..1fda50bb1 160000 --- a/interface +++ b/interface @@ -1 +1 @@ -Subproject commit 21b31fed42a5082311a458da4d475c839f99a717 +Subproject commit 1fda50bb14cf19ca33b0df0d06ea7ecee8b0432c diff --git a/tests/conftest.py b/tests/conftest.py index 58937dbd3..8ec23b2be 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -820,6 +820,26 @@ async def add_schema( ) +class TestMigrationProvider(Provider): + """Provider for migrations.""" + + scope = Scope.APP + _cached_conn: AsyncConnection | None = None + + @provide(scope=Scope.APP, cache=False) + async def get_session_factory( + self, + connection: AsyncConnection, + ) -> AsyncSession: + """Create session factory.""" + return AsyncSession(connection) + + @provide(scope=Scope.RUNTIME, provides=AsyncConnection) + async def get_conn_factory(self) -> AsyncConnection | None: + """Create session factory.""" + return self._cached_conn + + @pytest_asyncio.fixture(scope="session", autouse=True) async def _migrations( add_schema: None, # noqa: ARG001 @@ -840,14 +860,34 @@ def downgrade(conn: AsyncConnection) -> None: config.attributes["connection"] = conn command.downgrade(config, "base") + test_migration_provider = TestMigrationProvider() async with engine.begin() as conn: config.attributes["connection"] = conn + test_migration_provider._cached_conn = conn # noqa: SLF001 + config.attributes["dishka_container"] = make_async_container( + TestProvider(), + MFACredsProvider(), + test_migration_provider, + context={Settings: settings}, + start_scope=Scope.RUNTIME, + ) await conn.run_sync(upgrade) # type: ignore + test_migration_provider._cached_conn = None # noqa: SLF001 yield async with engine.begin() as conn: + config.attributes["connection"] = conn + test_migration_provider._cached_conn = conn # noqa: SLF001 + config.attributes["dishka_container"] = make_async_container( + TestProvider(), + MFACredsProvider(), + test_migration_provider, + context={Settings: settings}, + start_scope=Scope.RUNTIME, + ) await conn.run_sync(downgrade) # type: ignore + test_migration_provider._cached_conn = None # noqa: SLF001 @pytest_asyncio.fixture(scope="function") From 29b044b90674d3967a3feb9f6b95d5c489087011 Mon Sep 17 00:00:00 2001 From: TheMihMih Date: Wed, 17 Dec 2025 16:40:35 +0300 Subject: [PATCH 2/2] refactor: pr fixes --- Makefile | 4 ++-- app/alembic/env.py | 11 ++++++++++- app/ioc.py | 2 +- tests/conftest.py | 25 ++++++------------------- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index d529a3b2a..fa7fd3fa5 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ launch: ## run standalone app without tty container docker compose run sh -c "alembic upgrade head && python ." downgrade: ## re-run migration - docker compose run ldap_server sh -c\ + docker exec -it multidirectory_api sh -c\ "alembic downgrade -1; alembic upgrade head;" down: ## shutdown services @@ -71,4 +71,4 @@ migrations: ## generate migration file docker compose run ldap_server alembic revision --autogenerate migrate: ## upgrade db - docker compose run ldap_server python multidirectory.py --migrate \ No newline at end of file + docker compose run ldap_server alembic upgrade head \ No newline at end of file diff --git a/app/alembic/env.py b/app/alembic/env.py index 76f68b5eb..6c08a67bd 100644 --- a/app/alembic/env.py +++ b/app/alembic/env.py @@ -9,7 +9,13 @@ from sqlalchemy.ext.asyncio import AsyncConnection from config import Settings -from ioc import MainProvider, MigrationProvider +from ioc import ( + HTTPProvider, + MainProvider, + MFACredsProvider, + MFAProvider, + MigrationProvider, +) from repo.pg.tables import metadata # this is the Alembic Config object, which provides @@ -72,6 +78,9 @@ def run_migrations_online() -> None: if not dishka_container: dishka_container = make_async_container( MainProvider(), + MFACredsProvider(), + MFAProvider(), + HTTPProvider(), MigrationProvider(), context={Settings: settings}, ) diff --git a/app/ioc.py b/app/ioc.py index 3957a4270..c1a1d7e93 100644 --- a/app/ioc.py +++ b/app/ioc.py @@ -799,7 +799,7 @@ class MigrationProvider(Provider): scope = Scope.APP @provide(scope=Scope.APP) - async def get_session_factory( + def get_session_factory( self, connection: AsyncConnection, ) -> AsyncSession: diff --git a/tests/conftest.py b/tests/conftest.py index 5b0e0242d..1a41b3783 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -827,21 +827,15 @@ async def add_schema( class TestMigrationProvider(Provider): """Provider for migrations.""" - scope = Scope.APP - _cached_conn: AsyncConnection | None = None + async_conn = from_context(provides=AsyncConnection, scope=Scope.RUNTIME) @provide(scope=Scope.APP, cache=False) - async def get_session_factory( + def get_session_factory( self, - connection: AsyncConnection, + async_conn: AsyncConnection, ) -> AsyncSession: """Create session factory.""" - return AsyncSession(connection) - - @provide(scope=Scope.RUNTIME, provides=AsyncConnection) - async def get_conn_factory(self) -> AsyncConnection | None: - """Create session factory.""" - return self._cached_conn + return AsyncSession(async_conn) @pytest_asyncio.fixture(scope="session", autouse=True) @@ -867,31 +861,24 @@ def downgrade(conn: AsyncConnection) -> None: test_migration_provider = TestMigrationProvider() async with engine.begin() as conn: config.attributes["connection"] = conn - test_migration_provider._cached_conn = conn # noqa: SLF001 config.attributes["dishka_container"] = make_async_container( TestProvider(), - MFACredsProvider(), test_migration_provider, - context={Settings: settings}, + context={Settings: settings, AsyncConnection: conn}, start_scope=Scope.RUNTIME, ) await conn.run_sync(upgrade) # type: ignore - test_migration_provider._cached_conn = None # noqa: SLF001 yield async with engine.begin() as conn: - config.attributes["connection"] = conn - test_migration_provider._cached_conn = conn # noqa: SLF001 config.attributes["dishka_container"] = make_async_container( TestProvider(), - MFACredsProvider(), test_migration_provider, - context={Settings: settings}, + context={Settings: settings, AsyncConnection: conn}, start_scope=Scope.RUNTIME, ) await conn.run_sync(downgrade) # type: ignore - test_migration_provider._cached_conn = None # noqa: SLF001 @pytest_asyncio.fixture(scope="function")