Add hierarchical mail servers and credentials

This commit is contained in:
2026-07-28 19:32:56 +02:00
parent 2813c671c0
commit 3735027b3d
15 changed files with 4105 additions and 246 deletions

View File

@@ -9,6 +9,7 @@ from sqlalchemy import BigInteger, Boolean, DateTime, ForeignKey, Index, Integer
from sqlalchemy.orm import Mapped, mapped_column
from govoplan_core.db.base import Base, TimestampMixin
from govoplan_core.security import credential_envelopes as core_credential_models # noqa: F401
def new_uuid() -> str:
@@ -30,6 +31,7 @@ class MailServerProfile(Base, TimestampMixin):
slug: Mapped[str] = mapped_column(String(100), nullable=False)
description: Mapped[str | None] = mapped_column(Text)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
inherit_to_lower_scopes: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
smtp_config: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False)
smtp_username: Mapped[str | None] = mapped_column(String(320))
smtp_password_encrypted: Mapped[str | None] = mapped_column(Text)
@@ -42,6 +44,56 @@ class MailServerProfile(Base, TimestampMixin):
updated_by_user_id: Mapped[str | None] = mapped_column(ForeignKey("access_users.id", ondelete="SET NULL"), nullable=True, index=True)
class MailServerEndpoint(Base, TimestampMixin):
__tablename__ = "mail_server_endpoints"
__table_args__ = (
UniqueConstraint("profile_id", "protocol", "name", name="uq_mail_server_endpoints_profile_protocol_name"),
Index("ix_mail_server_endpoints_profile_protocol", "profile_id", "protocol", "is_active"),
Index("ix_mail_server_endpoints_scope", "tenant_id", "scope_type", "scope_id"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
profile_id: Mapped[str] = mapped_column(
ForeignKey("mail_server_profiles.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
tenant_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
protocol: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
name: Mapped[str] = mapped_column(String(255), nullable=False)
config: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False)
scope_type: Mapped[str] = mapped_column(String(20), default="tenant", nullable=False, index=True)
scope_id: Mapped[str | None] = mapped_column(String(36), nullable=True, index=True)
inherit_to_lower_scopes: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
is_default: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, index=True)
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
transport_revision: Mapped[str] = mapped_column(String(36), default=new_uuid, nullable=False)
created_by_user_id: Mapped[str | None] = mapped_column(ForeignKey("access_users.id", ondelete="SET NULL"), nullable=True, index=True)
updated_by_user_id: Mapped[str | None] = mapped_column(ForeignKey("access_users.id", ondelete="SET NULL"), nullable=True, index=True)
class MailServerCredentialBinding(Base, TimestampMixin):
__tablename__ = "mail_server_credential_bindings"
__table_args__ = (
UniqueConstraint("server_id", "credential_id", name="uq_mail_server_credential_bindings_server_credential"),
Index("ix_mail_server_credential_bindings_default", "server_id", "is_default"),
)
id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid)
server_id: Mapped[str] = mapped_column(
ForeignKey("mail_server_endpoints.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
credential_id: Mapped[str] = mapped_column(
ForeignKey("core_credential_envelopes.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
is_default: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, index=True)
created_by_user_id: Mapped[str | None] = mapped_column(ForeignKey("access_users.id", ondelete="SET NULL"), nullable=True, index=True)
class MailProfilePolicy(Base, TimestampMixin):
__tablename__ = "mail_profile_policies"
__table_args__ = (