refactor(idm): consume identity and organization contracts
This commit is contained in:
@@ -2,12 +2,12 @@ from __future__ import annotations
|
||||
|
||||
from sqlalchemy import or_
|
||||
|
||||
from govoplan_core.core.identity import IdentityDirectory
|
||||
from govoplan_core.core.idm import IdmDirectory, OrganizationFunctionAssignmentRef
|
||||
from govoplan_core.core.organizations import OrganizationDirectory
|
||||
from govoplan_core.db.session import get_database
|
||||
from govoplan_core.security.time import utc_now
|
||||
from govoplan_identity.backend.db.models import IdentityAccountLink
|
||||
from govoplan_idm.backend.db.models import IdmOrganizationFunctionAssignment
|
||||
from govoplan_organizations.backend.db.models import OrganizationFunction
|
||||
|
||||
|
||||
def _status(active: bool) -> str:
|
||||
@@ -33,6 +33,10 @@ def _assignment_ref(item: IdmOrganizationFunctionAssignment) -> OrganizationFunc
|
||||
|
||||
|
||||
class SqlIdmDirectory(IdmDirectory):
|
||||
def __init__(self, *, identities: IdentityDirectory, organizations: OrganizationDirectory) -> None:
|
||||
self._identities = identities
|
||||
self._organizations = organizations
|
||||
|
||||
def get_organization_function_assignment(self, assignment_id: str) -> OrganizationFunctionAssignmentRef | None:
|
||||
with get_database().session() as session:
|
||||
item = session.get(IdmOrganizationFunctionAssignment, assignment_id)
|
||||
@@ -52,13 +56,7 @@ class SqlIdmDirectory(IdmDirectory):
|
||||
*,
|
||||
tenant_id: str | None = None,
|
||||
) -> tuple[OrganizationFunctionAssignmentRef, ...]:
|
||||
with get_database().session() as session:
|
||||
identity_ids = [
|
||||
row[0]
|
||||
for row in session.query(IdentityAccountLink.identity_id)
|
||||
.filter(IdentityAccountLink.account_id == account_id)
|
||||
.all()
|
||||
]
|
||||
identity_ids = [identity.id for identity in self._identities.identities_for_accounts((account_id,))]
|
||||
if not identity_ids:
|
||||
return ()
|
||||
return self._assignments_for_identity_ids(identity_ids=tuple(identity_ids), tenant_id=tenant_id, account_id=account_id)
|
||||
@@ -76,11 +74,9 @@ class SqlIdmDirectory(IdmDirectory):
|
||||
with get_database().session() as session:
|
||||
query = (
|
||||
session.query(IdmOrganizationFunctionAssignment)
|
||||
.join(OrganizationFunction, OrganizationFunction.id == IdmOrganizationFunctionAssignment.function_id)
|
||||
.filter(
|
||||
IdmOrganizationFunctionAssignment.identity_id.in_(identity_ids),
|
||||
IdmOrganizationFunctionAssignment.is_active.is_(True),
|
||||
OrganizationFunction.is_active.is_(True),
|
||||
or_(IdmOrganizationFunctionAssignment.valid_from.is_(None), IdmOrganizationFunctionAssignment.valid_from <= now),
|
||||
or_(IdmOrganizationFunctionAssignment.valid_until.is_(None), IdmOrganizationFunctionAssignment.valid_until > now),
|
||||
)
|
||||
@@ -90,4 +86,44 @@ class SqlIdmDirectory(IdmDirectory):
|
||||
query = query.filter(or_(IdmOrganizationFunctionAssignment.account_id.is_(None), IdmOrganizationFunctionAssignment.account_id == account_id))
|
||||
if tenant_id is not None:
|
||||
query = query.filter(IdmOrganizationFunctionAssignment.tenant_id == tenant_id)
|
||||
return tuple(_assignment_ref(item) for item in query.all())
|
||||
items = query.all()
|
||||
source_ids = {
|
||||
item.delegated_from_assignment_id
|
||||
for item in items
|
||||
if item.source in {"delegated", "acting_for"}
|
||||
and item.delegated_from_assignment_id is not None
|
||||
}
|
||||
effective_sources = (
|
||||
session.query(IdmOrganizationFunctionAssignment)
|
||||
.filter(
|
||||
IdmOrganizationFunctionAssignment.id.in_(source_ids),
|
||||
IdmOrganizationFunctionAssignment.is_active.is_(True),
|
||||
or_(
|
||||
IdmOrganizationFunctionAssignment.valid_from.is_(None),
|
||||
IdmOrganizationFunctionAssignment.valid_from <= now,
|
||||
),
|
||||
or_(
|
||||
IdmOrganizationFunctionAssignment.valid_until.is_(None),
|
||||
IdmOrganizationFunctionAssignment.valid_until > now,
|
||||
),
|
||||
)
|
||||
.all()
|
||||
if source_ids
|
||||
else ()
|
||||
)
|
||||
effective_sources_by_id = {item.id: item for item in effective_sources}
|
||||
active_items: list[IdmOrganizationFunctionAssignment] = []
|
||||
for item in items:
|
||||
if item.source in {"delegated", "acting_for"}:
|
||||
source = effective_sources_by_id.get(item.delegated_from_assignment_id or "")
|
||||
if (
|
||||
source is None
|
||||
or source.tenant_id != item.tenant_id
|
||||
or source.function_id != item.function_id
|
||||
):
|
||||
continue
|
||||
function = self._organizations.get_function(item.function_id)
|
||||
if function is None or function.status != "active" or function.tenant_id != item.tenant_id:
|
||||
continue
|
||||
active_items.append(item)
|
||||
return tuple(_assignment_ref(item) for item in active_items)
|
||||
|
||||
Reference in New Issue
Block a user