248 lines
8.1 KiB
Python
248 lines
8.1 KiB
Python
import uuid
|
|
from datetime import date, datetime
|
|
|
|
from sqlalchemy import (
|
|
Boolean,
|
|
CheckConstraint,
|
|
Date,
|
|
DateTime,
|
|
ForeignKey,
|
|
Integer,
|
|
String,
|
|
Text,
|
|
func,
|
|
)
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
|
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
class Account(Base):
|
|
__tablename__ = "users"
|
|
__table_args__ = (
|
|
CheckConstraint(
|
|
"account_type IN ('individual', 'company')",
|
|
name="ck_users_account_type",
|
|
),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
account_type: Mapped[str] = mapped_column(String(20))
|
|
email: Mapped[str] = mapped_column(String(320), unique=True, index=True)
|
|
first_name: Mapped[str] = mapped_column(String(80))
|
|
last_name: Mapped[str] = mapped_column(String(80))
|
|
date_of_birth: Mapped[date] = mapped_column(Date)
|
|
phone_number: Mapped[str] = mapped_column(String(24), unique=True)
|
|
company_domain: Mapped[str | None] = mapped_column(String(253), nullable=True)
|
|
org_role: Mapped[str] = mapped_column(String(20), default="user")
|
|
member_status: Mapped[str] = mapped_column(String(20), default="active")
|
|
created_by_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("users.id"),
|
|
nullable=True,
|
|
)
|
|
invitation_email: Mapped[str | None] = mapped_column(String(320), nullable=True)
|
|
must_change_password: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
password_hash: Mapped[str] = mapped_column(String(255))
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
)
|
|
mail_domains: Mapped[list["MailDomain"]] = relationship(back_populates="account")
|
|
|
|
|
|
class MailDomain(Base):
|
|
__tablename__ = "mail_domains"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
domain_name: Mapped[str] = mapped_column(String(253), unique=True, index=True)
|
|
domain_type: Mapped[str] = mapped_column(String(20))
|
|
account_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("users.id"),
|
|
nullable=True,
|
|
)
|
|
mail_host: Mapped[str] = mapped_column(String(253))
|
|
dkim_selector: Mapped[str] = mapped_column(String(63))
|
|
dkim_private_key: Mapped[str] = mapped_column(Text)
|
|
dkim_public_key: Mapped[str] = mapped_column(Text)
|
|
status: Mapped[str] = mapped_column(String(20), default="pending_dns")
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
)
|
|
account: Mapped[Account | None] = relationship(back_populates="mail_domains")
|
|
dns_records: Mapped[list["DomainDnsRecord"]] = relationship(
|
|
back_populates="domain",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
smtp_credentials: Mapped[list["SmtpCredential"]] = relationship(
|
|
back_populates="domain",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
|
|
|
|
class DomainDnsRecord(Base):
|
|
__tablename__ = "domain_dns_records"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
domain_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("mail_domains.id"),
|
|
index=True,
|
|
)
|
|
record_type: Mapped[str] = mapped_column(String(10))
|
|
host: Mapped[str] = mapped_column(String(253))
|
|
value: Mapped[str] = mapped_column(Text)
|
|
purpose: Mapped[str] = mapped_column(String(20))
|
|
ttl: Mapped[int] = mapped_column(Integer, default=3600)
|
|
domain: Mapped[MailDomain] = relationship(back_populates="dns_records")
|
|
|
|
|
|
class SmtpCredential(Base):
|
|
__tablename__ = "smtp_credentials"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
domain_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("mail_domains.id"),
|
|
index=True,
|
|
)
|
|
username: Mapped[str] = mapped_column(String(120), unique=True, index=True)
|
|
password_hash: Mapped[str] = mapped_column(String(255))
|
|
label: Mapped[str] = mapped_column(String(120))
|
|
is_active: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
)
|
|
domain: Mapped[MailDomain] = relationship(back_populates="smtp_credentials")
|
|
|
|
|
|
class OrgSecuritySettings(Base):
|
|
__tablename__ = "org_security_settings"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
company_domain: Mapped[str] = mapped_column(String(253), unique=True, index=True)
|
|
require_strong_passwords: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
require_mfa_admins: Mapped[bool] = mapped_column(Boolean, default=True)
|
|
require_mfa_all_users: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
session_timeout_minutes: Mapped[int] = mapped_column(Integer, default=60)
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
onupdate=func.now(),
|
|
)
|
|
|
|
|
|
class MailGroup(Base):
|
|
__tablename__ = "mail_groups"
|
|
__table_args__ = (
|
|
CheckConstraint(
|
|
"group_type IN ('distribution', 'dynamic')",
|
|
name="ck_mail_groups_group_type",
|
|
),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
company_domain: Mapped[str] = mapped_column(String(253), index=True)
|
|
name: Mapped[str] = mapped_column(String(120))
|
|
email: Mapped[str] = mapped_column(String(320), unique=True, index=True)
|
|
group_type: Mapped[str] = mapped_column(String(20), default="distribution")
|
|
created_by_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("users.id"),
|
|
nullable=True,
|
|
)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
)
|
|
members: Mapped[list["MailGroupMember"]] = relationship(
|
|
back_populates="group",
|
|
cascade="all, delete-orphan",
|
|
)
|
|
|
|
|
|
class MailGroupMember(Base):
|
|
__tablename__ = "mail_group_members"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
group_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("mail_groups.id"),
|
|
index=True,
|
|
)
|
|
account_id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("users.id"),
|
|
index=True,
|
|
)
|
|
group: Mapped[MailGroup] = relationship(back_populates="members")
|
|
account: Mapped[Account] = relationship()
|
|
|
|
|
|
class MailAlias(Base):
|
|
__tablename__ = "mail_aliases"
|
|
__table_args__ = (
|
|
CheckConstraint(
|
|
"alias_type IN ('user', 'group')",
|
|
name="ck_mail_aliases_alias_type",
|
|
),
|
|
CheckConstraint(
|
|
"status IN ('active', 'disabled')",
|
|
name="ck_mail_aliases_status",
|
|
),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
primary_key=True,
|
|
default=uuid.uuid4,
|
|
)
|
|
company_domain: Mapped[str] = mapped_column(String(253), index=True)
|
|
alias_address: Mapped[str] = mapped_column(String(320), unique=True, index=True)
|
|
forwards_to: Mapped[str] = mapped_column(String(320))
|
|
alias_type: Mapped[str] = mapped_column(String(20), default="user")
|
|
is_domain_alias: Mapped[bool] = mapped_column(Boolean, default=False)
|
|
status: Mapped[str] = mapped_column(String(20), default="active")
|
|
created_by_id: Mapped[uuid.UUID | None] = mapped_column(
|
|
UUID(as_uuid=True),
|
|
ForeignKey("users.id"),
|
|
nullable=True,
|
|
)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True),
|
|
server_default=func.now(),
|
|
)
|