config.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. from typing import Any, Dict, List, Optional, Union
  2. from pydantic import AnyHttpUrl, validator
  3. from pydantic_settings import BaseSettings
  4. class Settings(BaseSettings):
  5. PROJECT_NAME: str = "Unified Authentication Platform"
  6. API_V1_STR: str = "/api/v1"
  7. # Database
  8. MYSQL_SERVER: str = "localhost"
  9. MYSQL_USER: str = "root"
  10. MYSQL_PASSWORD: str = "secret"
  11. MYSQL_DB: str = "uap_db"
  12. MYSQL_PORT: int = 3306
  13. DATABASE_URI: Optional[str] = None
  14. @validator("DATABASE_URI", pre=True)
  15. def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
  16. if isinstance(v, str):
  17. return v
  18. return f"mysql://{values.get('MYSQL_USER')}:{values.get('MYSQL_PASSWORD')}@{values.get('MYSQL_SERVER')}:{values.get('MYSQL_PORT')}/{values.get('MYSQL_DB')}"
  19. # Redis
  20. REDIS_HOST: str = "localhost"
  21. REDIS_PORT: int = 6379
  22. REDIS_DB: int = 0
  23. REDIS_PASSWORD: Optional[str] = None
  24. # Security
  25. SECRET_KEY: str = "change_me_in_production"
  26. ALGORITHM: str = "HS256"
  27. ACCESS_TOKEN_EXPIRE_MINUTES: int = 129600 # ~90 days (3 months)
  28. ACCESS_TOKEN_EXPIRE_MINUTES_LONG: int = 525600 # 365 days (1 year)
  29. # Identity QR (AES-256-GCM payload for personal QR code)
  30. IDENTITY_QR_VALID_SECONDS: int = 60 # 1 minute
  31. # 32 字节 AES 密钥:64 位 hex(推荐)、Base64、或 UTF-8 恰 32 字符;生产环境务必替换
  32. IDENTITY_QR_ENCRYPTION_KEY: str = (
  33. "0f1e2d3c4b5a69788796a5b4c3d2e1f0deadbeefcafebabe0123456789abcdef"
  34. )
  35. # CORS
  36. BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = []
  37. @validator("BACKEND_CORS_ORIGINS", pre=True)
  38. def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
  39. if isinstance(v, str) and not v.startswith("["):
  40. return [i.strip() for i in v.split(",")]
  41. elif isinstance(v, (list, str)):
  42. return v
  43. raise ValueError(v)
  44. # Captcha
  45. CAPTCHA_EXPIRE_SECONDS: int = 600
  46. # SMS
  47. # SMS_PROVIDER: str = "mock" # Options: "mock", "aliyun"
  48. SMS_PROVIDER: str = "aliyun"
  49. ALIYUN_ACCESS_KEY_ID: Optional[str] = "LTAI5tDScnqnCTKVPwLgHCqS"
  50. ALIYUN_ACCESS_KEY_SECRET: Optional[str] = "cRr1ThS29pycEiZ3nvCokZjswMEYP3"
  51. ALIYUN_SMS_SIGN_NAME: Optional[str] = "速通互联验证服务"
  52. ALIYUN_SMS_TEMPLATE_CODE: Optional[str] = "100001"
  53. # MinIO
  54. MINIO_ENDPOINT: str = "https://api.hnyunzhu.com:9004"
  55. MINIO_ACCESS_KEY: str = "1jC3nmjfWAyMGJ3pinbT"
  56. MINIO_SECRET_KEY: str = "6FHE9lzeQ6rZ3wIXSA9jGu8pGf49vgwT18NJ9XpO"
  57. MINIO_BUCKET_NAME: str = "unified-message-files"
  58. MINIO_DB_BACKUP_BUCKET_NAME: str = "unified-db-backups"
  59. MINIO_DISTRIBUTION_BUCKET_NAME: str = "unified-application-distribution"
  60. MINIO_UPDATE_BUCKET_NAME: str = "app-updates" # 公开读桶,用于自建更新文件 update/
  61. MINIO_SECURE: bool = False
  62. # 登录页「下载客户端」跳转地址(通常为下载落地页);不配则隐藏入口,不写数据库
  63. CLIENT_DOWNLOAD_URL_MOBILE: Optional[str] = "https://api.hnyunzhu.com/d/gAAAAABp3aYH7i4_dgAmlQLb-ruUiqbPyc5vH23EEB7pvIWEZHbBwekS1hfaWPqyew2QuqGfcPMtxGd7Zvei0_Ijv-LyPst1NAYv1skXP4LklYTAVjuCvRM%3D?platform=android"
  64. CLIENT_DOWNLOAD_URL_PC: Optional[str] = "https://api.hnyunzhu.com/d/gAAAAABp3aYH7i4_dgAmlQLb-ruUiqbPyc5vH23EEB7pvIWEZHbBwekS1hfaWPqyew2QuqGfcPMtxGd7Zvei0_Ijv-LyPst1NAYv1skXP4LklYTAVjuCvRM%3D?platform=windows"
  65. class Config:
  66. case_sensitive = True
  67. env_file = ".env"
  68. settings = Settings()