Initial commit: Office365 web management platform
This commit is contained in:
131
office365_admin/settings.py
Normal file
131
office365_admin/settings.py
Normal file
@@ -0,0 +1,131 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
GRAPH_BASE_URL = "https://graph.microsoft.com/v1.0"
|
||||
GRAPH_SCOPE = "https://graph.microsoft.com/.default"
|
||||
TOKEN_ENDPOINT_TEMPLATE = "https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
|
||||
|
||||
|
||||
def _env_bool(name: str, default: bool = False) -> bool:
|
||||
return os.getenv(name, str(default)).strip().lower() in {"1", "true", "yes", "on"}
|
||||
|
||||
|
||||
def _env_int(name: str, default: int) -> int:
|
||||
try:
|
||||
return int(os.getenv(name, str(default)).strip())
|
||||
except ValueError:
|
||||
return default
|
||||
|
||||
|
||||
@dataclass
|
||||
class Settings:
|
||||
app_name: str
|
||||
host: str
|
||||
port: int
|
||||
debug: bool
|
||||
session_secret: str
|
||||
auth_enabled: bool
|
||||
admin_username: str
|
||||
admin_password: str
|
||||
client_id: str
|
||||
tenant_id: str
|
||||
client_secret: str
|
||||
default_password: str
|
||||
default_domain: str
|
||||
default_usage_location: str
|
||||
default_license_sku: str
|
||||
force_change_password: bool
|
||||
graph_base_url: str
|
||||
token_endpoint: str
|
||||
scope: str
|
||||
default_page_size: int = 25
|
||||
max_page_size: int = 100
|
||||
validation_errors: tuple[str, ...] = field(default_factory=tuple)
|
||||
warnings: tuple[str, ...] = field(default_factory=tuple)
|
||||
|
||||
@property
|
||||
def graph_ready(self) -> bool:
|
||||
return not self.validation_errors
|
||||
|
||||
@property
|
||||
def effective_auth_enabled(self) -> bool:
|
||||
return self.auth_enabled and bool(self.admin_username and self.admin_password)
|
||||
|
||||
def to_public_dict(self) -> dict:
|
||||
return {
|
||||
"appName": self.app_name,
|
||||
"graphFlavor": "Microsoft Graph Global",
|
||||
"graphReady": self.graph_ready,
|
||||
"validationErrors": list(self.validation_errors),
|
||||
"warnings": list(self.warnings),
|
||||
"authEnabled": self.effective_auth_enabled,
|
||||
"defaultDomain": self.default_domain,
|
||||
"defaultUsageLocation": self.default_usage_location,
|
||||
"defaultLicenseSku": self.default_license_sku,
|
||||
"forceChangePassword": self.force_change_password,
|
||||
"pageSize": self.default_page_size,
|
||||
"maxPageSize": self.max_page_size,
|
||||
}
|
||||
|
||||
|
||||
def load_settings() -> Settings:
|
||||
load_dotenv()
|
||||
|
||||
tenant_id = os.getenv("TENANT_ID", "").strip()
|
||||
graph_base_url = GRAPH_BASE_URL
|
||||
token_endpoint = TOKEN_ENDPOINT_TEMPLATE.format(tenant_id=tenant_id) if tenant_id else ""
|
||||
scope = GRAPH_SCOPE
|
||||
|
||||
validation_errors: list[str] = []
|
||||
warnings: list[str] = []
|
||||
|
||||
required_fields = {
|
||||
"CLIENT_ID": os.getenv("CLIENT_ID", "").strip(),
|
||||
"TENANT_ID": tenant_id,
|
||||
"CLIENT_SECRET": os.getenv("CLIENT_SECRET", "").strip(),
|
||||
"DEFAULT_PASSWORD": os.getenv("DEFAULT_PASSWORD", "").strip(),
|
||||
}
|
||||
|
||||
for field_name, value in required_fields.items():
|
||||
if not value:
|
||||
validation_errors.append(f"{field_name} 未配置")
|
||||
|
||||
if not os.getenv("DEFAULT_DOMAIN", "").strip():
|
||||
warnings.append("DEFAULT_DOMAIN 未配置,创建账号时必须填写完整 userPrincipalName。")
|
||||
|
||||
auth_enabled = _env_bool("WEB_AUTH_ENABLED", True)
|
||||
admin_username = os.getenv("ADMIN_USERNAME", "").strip()
|
||||
admin_password = os.getenv("ADMIN_PASSWORD", "").strip()
|
||||
if auth_enabled and not (admin_username and admin_password):
|
||||
warnings.append("WEB_AUTH_ENABLED=true 但未配置后台登录账号,已自动退回为无登录保护模式。")
|
||||
|
||||
return Settings(
|
||||
app_name=os.getenv("APP_NAME", "Office 365 User Management Platform").strip(),
|
||||
host=os.getenv("HOST", "0.0.0.0").strip(),
|
||||
port=_env_int("PORT", 8000),
|
||||
debug=_env_bool("DEBUG", False),
|
||||
session_secret=os.getenv("SESSION_SECRET", "office365-admin-dev-secret").strip(),
|
||||
auth_enabled=auth_enabled,
|
||||
admin_username=admin_username,
|
||||
admin_password=admin_password,
|
||||
client_id=required_fields["CLIENT_ID"],
|
||||
tenant_id=required_fields["TENANT_ID"],
|
||||
client_secret=required_fields["CLIENT_SECRET"],
|
||||
default_password=required_fields["DEFAULT_PASSWORD"],
|
||||
default_domain=os.getenv("DEFAULT_DOMAIN", "").strip(),
|
||||
default_usage_location=os.getenv("DEFAULT_USAGE_LOCATION", "US").strip() or "US",
|
||||
default_license_sku=os.getenv("DEFAULT_LICENSE_SKU", "").strip(),
|
||||
force_change_password=_env_bool("FORCE_CHANGE_PASSWORD", True),
|
||||
graph_base_url=graph_base_url,
|
||||
token_endpoint=token_endpoint,
|
||||
scope=scope,
|
||||
default_page_size=min(max(_env_int("DEFAULT_PAGE_SIZE", 25), 1), 100),
|
||||
max_page_size=min(max(_env_int("MAX_PAGE_SIZE", 100), 10), 500),
|
||||
validation_errors=tuple(validation_errors),
|
||||
warnings=tuple(warnings),
|
||||
)
|
||||
Reference in New Issue
Block a user