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
16 changes: 14 additions & 2 deletions app/alembic/versions/01f3f05a5b11_add_primary_group_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
from sqlalchemy.orm import Session, selectinload

from entities import Attribute, Directory, EntityType, Group
from enums import EntityTypeNames
from ldap_protocol.ldap_schema.attribute_value_validator import (
AttributeValueValidator,
)
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
Expand Down Expand Up @@ -48,6 +52,7 @@ async def _add_domain_computers_group(connection: AsyncConnection) -> None:
entity_type_dao = EntityTypeDAO(
session,
object_class_dao=object_class_dao,
attribute_value_validator=AttributeValueValidator(),
)
role_dao = RoleDAO(session)
ace_dao = AccessControlEntryDAO(session)
Expand All @@ -66,12 +71,15 @@ async def _add_domain_computers_group(connection: AsyncConnection) -> None:
dir_, group_ = await create_group(
name="domain computers",
sid=515,
attribute_value_validator=AttributeValueValidator(),
session=session,
)

await session.flush()

computer_entity_type = await entity_type_dao.get("Computer")
computer_entity_type = await entity_type_dao.get(
EntityTypeNames.COMPUTER,
)
computer_dirs = await session.scalars(
select(Directory)
.where(
Expand Down Expand Up @@ -126,7 +134,11 @@ async def _add_primary_group_id(connection: AsyncConnection) -> None:

entity_type = await session.scalars(
select(qa(EntityType.id))
.where(qa(EntityType.name).in_(["User", "Computer"])),
.where(
qa(EntityType.name).in_(
[EntityTypeNames.USER, EntityTypeNames.COMPUTER],
),
),
) # fmt: skip

entity_type_ids = list(entity_type.all())
Expand Down
4 changes: 0 additions & 4 deletions app/alembic/versions/692ae64e0cc5_.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,17 @@

def upgrade() -> None:
"""Upgrade."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_unique_constraint(
"group_policy_uc",
"GroupAccessPolicyMemberships",
["group_id", "policy_id"],
)
# ### end Alembic commands ###


def downgrade() -> None:
"""Downgrade."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(
"group_policy_uc",
"GroupAccessPolicyMemberships",
type_="unique",
)
# ### end Alembic commands ###
11 changes: 10 additions & 1 deletion app/alembic/versions/8164b4a9e1f1_add_ou_computers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession

from entities import Directory
from ldap_protocol.ldap_schema.attribute_value_validator import (
AttributeValueValidator,
)
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
Expand Down Expand Up @@ -43,11 +46,17 @@ 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)
attribute_value_validator = AttributeValueValidator()
entity_type_dao = EntityTypeDAO(
session,
object_class_dao,
attribute_value_validator=attribute_value_validator,
)
setup_gateway = SetupGateway(
session,
PasswordUtils(),
entity_type_dao,
attribute_value_validator=attribute_value_validator,
)

base_directories = await get_base_directories(session)
Expand Down
9 changes: 7 additions & 2 deletions app/alembic/versions/ba78cef9700a_initial_entity_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
from constants import ENTITY_TYPE_DATAS
from entities import Attribute, Directory, User
from extra.alembic_utils import temporary_stub_entity_type_name
from ldap_protocol.ldap_schema.attribute_value_validator import (
AttributeValueValidator,
)
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
Expand Down Expand Up @@ -107,6 +110,7 @@ async def _create_entity_types(connection: AsyncConnection) -> None:
entity_type_dao = EntityTypeDAO(
session,
object_class_dao=object_class_dao,
attribute_value_validator=AttributeValueValidator(),
)
entity_type_use_case = EntityTypeUseCase(
entity_type_dao,
Expand All @@ -116,8 +120,8 @@ async def _create_entity_types(connection: AsyncConnection) -> None:
for entity_type_data in ENTITY_TYPE_DATAS:
await entity_type_use_case.create(
EntityTypeDTO(
name=entity_type_data["name"], # type: ignore
object_class_names=entity_type_data["object_class_names"], # type: ignore
name=entity_type_data["name"],
object_class_names=entity_type_data["object_class_names"],
is_system=True,
),
)
Expand Down Expand Up @@ -175,6 +179,7 @@ async def _attach_entity_type_to_directories(
entity_type_dao = EntityTypeDAO(
session,
object_class_dao=object_class_dao,
attribute_value_validator=AttributeValueValidator(),
)

await entity_type_dao.attach_entity_type_to_directories()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from sqlalchemy.orm import joinedload

from entities import Attribute, Directory, NetworkPolicy
from ldap_protocol.ldap_schema.attribute_value_validator import (
AttributeValueValidator,
)
from ldap_protocol.ldap_schema.entity_type_dao import EntityTypeDAO
from ldap_protocol.ldap_schema.object_class_dao import ObjectClassDAO
from ldap_protocol.utils.helpers import create_integer_hash
Expand Down Expand Up @@ -43,6 +46,7 @@ async def _attach_entity_type_to_directories(
entity_type_dao = EntityTypeDAO(
session,
object_class_dao=object_class_dao,
attribute_value_validator=AttributeValueValidator(),
)
await entity_type_dao.attach_entity_type_to_directories()
await session.commit()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from sqlalchemy.ext.asyncio import AsyncConnection, AsyncSession

from entities import Attribute, Directory, EntityType
from enums import EntityTypeNames
from repo.pg.tables import queryable_attr as qa

# revision identifiers, used by Alembic.
Expand Down Expand Up @@ -39,7 +40,7 @@ async def _migrate_ou_to_cn_containers(
)
entity_type = await session.scalar(
select(EntityType)
.where(qa(EntityType.name) == "Container"),
.where(qa(EntityType.name) == EntityTypeNames.CONTAINER),
) # fmt: skip

for directory in directories:
Expand Down Expand Up @@ -124,7 +125,7 @@ async def _migrate_cn_to_ou_containers(
)
entity_type = await session.scalar(
select(EntityType)
.where(qa(EntityType.name) == "Organizational Unit"),
.where(qa(EntityType.name) == EntityTypeNames.ORGANIZATIONAL_UNIT),
) # fmt: skip

for directory in directories:
Expand Down
4 changes: 4 additions & 0 deletions app/alembic/versions/fafc3d0b11ec_.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

from entities import Directory
from extra.alembic_utils import temporary_stub_entity_type_name
from ldap_protocol.ldap_schema.attribute_value_validator import (
AttributeValueValidator,
)
from ldap_protocol.utils.queries import (
create_group,
get_base_directories,
Expand Down Expand Up @@ -52,6 +55,7 @@ async def _create_readonly_grp_and_plcy(
dir_, _ = await create_group(
name="readonly domain controllers",
sid=521,
attribute_value_validator=AttributeValueValidator(),
session=session,
)

Expand Down
4 changes: 2 additions & 2 deletions app/api/ldap_schema/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from pydantic import BaseModel, Field

from enums import KindType
from enums import EntityTypeNames, KindType
from ldap_protocol.ldap_schema.constants import (
DEFAULT_ENTITY_TYPE_IS_SYSTEM,
OID_REGEX_PATTERN,
Expand Down Expand Up @@ -82,7 +82,7 @@ class EntityTypeSchema(BaseModel, Generic[_IdT]):
"""Entity Type Schema."""

id: _IdT = Field(default=None) # type: ignore[assignment]
name: str
name: EntityTypeNames | str
is_system: bool
object_class_names: list[str] = Field(
default_factory=list,
Expand Down
86 changes: 50 additions & 36 deletions app/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
License: https://github.com/MultiDirectoryLab/MultiDirectory/blob/main/LICENSE
"""

from typing import TypedDict

from enums import EntityTypeNames

group_attrs = {
"objectClass": ["top"],
"groupType": ["-2147483646"],
Expand Down Expand Up @@ -207,24 +211,37 @@
]


ENTITY_TYPE_DATAS = [
{
"name": "Domain",
"object_class_names": ["top", "domain", "domainDNS"],
},
{"name": "Computer", "object_class_names": ["top", "computer"]},
{"name": "Container", "object_class_names": ["top", "container"]},
{
"name": "Organizational Unit",
"object_class_names": ["top", "container", "organizationalUnit"],
},
{
"name": "Group",
"object_class_names": ["top", "group", "posixGroup"],
},
{
"name": "User",
"object_class_names": [
class EntityTypeData(TypedDict):
"""Entity Type data."""

name: EntityTypeNames
object_class_names: list[str]


ENTITY_TYPE_DATAS: tuple[EntityTypeData, ...] = (
EntityTypeData(
name=EntityTypeNames.DOMAIN,
object_class_names=["top", "domain", "domainDNS"],
),
EntityTypeData(
name=EntityTypeNames.COMPUTER,
object_class_names=["top", "computer"],
),
EntityTypeData(
name=EntityTypeNames.CONTAINER,
object_class_names=["top", "container"],
),
EntityTypeData(
name=EntityTypeNames.ORGANIZATIONAL_UNIT,
object_class_names=["top", "container", "organizationalUnit"],
),
EntityTypeData(
name=EntityTypeNames.GROUP,
object_class_names=["top", "group", "posixGroup"],
),
EntityTypeData(
name=EntityTypeNames.USER,
object_class_names=[
"top",
"user",
"person",
Expand All @@ -233,28 +250,25 @@
"shadowAccount",
"inetOrgPerson",
],
},
{"name": "KRB Container", "object_class_names": ["krbContainer"]},
{
"name": "KRB Principal",
"object_class_names": [
),
EntityTypeData(
name=EntityTypeNames.KRB_CONTAINER,
object_class_names=["krbContainer"],
),
EntityTypeData(
name=EntityTypeNames.KRB_PRINCIPAL,
object_class_names=[
"krbprincipal",
"krbprincipalaux",
"krbTicketPolicyAux",
],
},
{
"name": "KRB Realm Container",
"object_class_names": [
"top",
"krbrealmcontainer",
"krbticketpolicyaux",
],
},
]
PRIMARY_ENTITY_TYPE_NAMES = {
entity_type_data["name"] for entity_type_data in ENTITY_TYPE_DATAS
}
),
EntityTypeData(
name=EntityTypeNames.KRB_REALM_CONTAINER,
object_class_names=["top", "krbrealmcontainer", "krbticketpolicyaux"],
),
)


FIRST_SETUP_DATA = [
{
Expand Down
18 changes: 18 additions & 0 deletions app/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,24 @@ class MFAChallengeStatuses(StrEnum):
PENDING = "pending"


class EntityTypeNames(StrEnum):
Comment thread
milov-dmitriy marked this conversation as resolved.
"""Enum of base (system) Entity Types.

Used for system objects.
Custom Entity Types aren't included here.
"""

DOMAIN = "Domain"
COMPUTER = "Computer"
CONTAINER = "Container"
ORGANIZATIONAL_UNIT = "Organizational Unit"
GROUP = "Group"
USER = "User"
KRB_CONTAINER = "KRB Container"
KRB_PRINCIPAL = "KRB Principal"
KRB_REALM_CONTAINER = "KRB Realm Container"


class KindType(StrEnum):
"""Object kind types."""

Expand Down
10 changes: 4 additions & 6 deletions app/extra/scripts/uac_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,10 @@ async def disable_accounts(
String,
)
conditions = [
(
cast(Attribute.value, Integer).op("&")(
UserAccountControlFlag.ACCOUNTDISABLE,
)
== 0
),
cast(Attribute.value, Integer).op("&")(
UserAccountControlFlag.ACCOUNTDISABLE,
)
== 0,
qa(Attribute.directory_id).in_(subquery),
qa(Attribute.name) == "userAccountControl",
]
Expand Down
7 changes: 7 additions & 0 deletions app/ioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
from ldap_protocol.ldap_schema.attribute_type_use_case import (
AttributeTypeUseCase,
)
from ldap_protocol.ldap_schema.attribute_value_validator import (
AttributeValueValidator,
)
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
Expand Down Expand Up @@ -416,6 +419,10 @@ async def get_dhcp_mngr(
kea_dhcp_repository=dhcp_api_repository,
)

attribute_value_validator = provide(
AttributeValueValidator,
scope=Scope.RUNTIME,
)
attribute_type_dao = provide(AttributeTypeDAO, scope=Scope.REQUEST)
object_class_dao = provide(ObjectClassDAO, scope=Scope.REQUEST)
entity_type_dao = provide(EntityTypeDAO, scope=Scope.REQUEST)
Expand Down
Loading