72 lines
3.4 KiB
Python
72 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
import enum
|
|
import uuid
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
from sqlalchemy import DateTime, Enum, ForeignKey, Integer, String, Text, UniqueConstraint, func
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base_class import Base
|
|
|
|
|
|
class SmtpSecurity(str, enum.Enum):
|
|
NONE = "NONE"
|
|
SSL = "SSL"
|
|
STARTTLS = "STARTTLS"
|
|
|
|
|
|
class EmailVerificationPurpose(str, enum.Enum):
|
|
REGISTER = "REGISTER"
|
|
PASSWORD_RESET = "PASSWORD_RESET"
|
|
PASSWORD_RESET_LINK = "PASSWORD_RESET_LINK"
|
|
|
|
|
|
class SystemEmailSettings(Base):
|
|
__tablename__ = "system_email_settings"
|
|
__table_args__ = (UniqueConstraint("register_domain", name="uq_system_email_settings_register_domain"),)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
register_domain: Mapped[str] = mapped_column(String(255), nullable=False, default="huapont.cn")
|
|
smtp_host: Mapped[str] = mapped_column(String(255), nullable=False, default="")
|
|
smtp_port: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
smtp_security: Mapped[SmtpSecurity] = mapped_column(
|
|
Enum(SmtpSecurity, name="smtp_security"),
|
|
nullable=False,
|
|
default=SmtpSecurity.SSL,
|
|
server_default=SmtpSecurity.SSL.value,
|
|
)
|
|
smtp_username: Mapped[str] = mapped_column(String(255), nullable=False, default="")
|
|
smtp_password_encrypted: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
|
sender_email: Mapped[str] = mapped_column(String(255), nullable=False, default="")
|
|
sender_name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
|
allowed_register_domain: Mapped[str] = mapped_column(String(255), nullable=False, default="huapont.cn")
|
|
verification_code_ttl_minutes: Mapped[int] = mapped_column(Integer, nullable=False, default=10)
|
|
send_cooldown_seconds: Mapped[int] = mapped_column(Integer, nullable=False, default=60)
|
|
max_verify_attempts: Mapped[int] = mapped_column(Integer, nullable=False, default=5)
|
|
updated_by: Mapped[Optional[uuid.UUID]] = mapped_column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=True)
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
|
|
updated_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
|
|
)
|
|
|
|
|
|
class EmailVerificationCode(Base):
|
|
__tablename__ = "email_verification_codes"
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
email: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
|
purpose: Mapped[EmailVerificationPurpose] = mapped_column(
|
|
Enum(EmailVerificationPurpose, name="email_verification_purpose"),
|
|
nullable=False,
|
|
default=EmailVerificationPurpose.REGISTER,
|
|
server_default=EmailVerificationPurpose.REGISTER.value,
|
|
)
|
|
code_hash: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
|
|
verified_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
attempt_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default="0")
|
|
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())
|