54 lines
2.0 KiB
Python
54 lines
2.0 KiB
Python
from functools import lru_cache
|
|
|
|
from pydantic import AnyHttpUrl, Field, SecretStr, field_validator
|
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
model_config = SettingsConfigDict(env_file=None, extra="ignore")
|
|
|
|
database_url: str = Field(alias="SMS_DATABASE_URL")
|
|
service_token: SecretStr = Field(alias="SMS_SERVICE_TOKEN", min_length=32)
|
|
idgtl_base_url: AnyHttpUrl = Field(
|
|
default=AnyHttpUrl("https://direct.i-dgtl.ru"), alias="IDGTL_SMS_BASE_URL"
|
|
)
|
|
idgtl_api_key: SecretStr | None = Field(default=None, alias="IDGTL_SMS_API_KEY")
|
|
callback_public_url: AnyHttpUrl = Field(alias="IDGTL_SMS_CALLBACK_PUBLIC_URL")
|
|
callback_username: SecretStr = Field(alias="IDGTL_SMS_CALLBACK_USERNAME")
|
|
callback_password: SecretStr = Field(alias="IDGTL_SMS_CALLBACK_PASSWORD")
|
|
log_level: str = Field(default="INFO", alias="LOG_LEVEL")
|
|
api_port: int = Field(default=8080, alias="SMS_API_PORT", ge=1, le=65535)
|
|
|
|
@field_validator(
|
|
"service_token",
|
|
"callback_username",
|
|
"callback_password",
|
|
)
|
|
@classmethod
|
|
def reject_placeholders(cls, value: SecretStr) -> SecretStr:
|
|
raw = value.get_secret_value().strip()
|
|
if not raw or raw.lower() in {"changeme", "secret", "token", "<secret>"}:
|
|
raise ValueError("secret is missing or is a placeholder")
|
|
return value
|
|
|
|
@field_validator("idgtl_api_key")
|
|
@classmethod
|
|
def reject_api_key_placeholder(cls, value: SecretStr | None) -> SecretStr | None:
|
|
if value is None:
|
|
return None
|
|
return cls.reject_placeholders(value)
|
|
|
|
@field_validator("callback_public_url")
|
|
@classmethod
|
|
def callback_must_be_https(cls, value: AnyHttpUrl) -> AnyHttpUrl:
|
|
if value.scheme != "https":
|
|
raise ValueError("callback URL must use HTTPS")
|
|
if value.username or value.password:
|
|
raise ValueError("callback URL must not contain credentials")
|
|
return value
|
|
|
|
|
|
@lru_cache
|
|
def get_settings() -> Settings:
|
|
return Settings()
|