功能(文档预览):集成 ONLYOFFICE 安全只读预览与工作台体验
新增 ONLYOFFICE 配置签名、内部内容接口、容器编排与反向代理。 打通网页端和桌面端独立预览工作区,完善文档入口、布局及帮助体验。 补充桌面安全发布门禁、开发脚本、使用文档和前后端测试。
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from functools import lru_cache
|
||||
from typing import Literal, Optional
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from pydantic import Field
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
@@ -50,6 +51,12 @@ class Settings(BaseSettings):
|
||||
MONITORING_RETENTION_INTERVAL_SECONDS: int = Field(default=86400, ge=60, le=604800)
|
||||
USER_LOGIN_ACTIVITY_RETENTION_DAYS: int = Field(default=180, ge=30, le=3650)
|
||||
USER_SESSION_ONLINE_SECONDS: int = Field(default=300, ge=60, le=3600)
|
||||
ONLYOFFICE_ENABLED: bool = False
|
||||
ONLYOFFICE_JWT_SECRET: Optional[str] = None
|
||||
ONLYOFFICE_INTERNAL_URL: str = "http://onlyoffice"
|
||||
ONLYOFFICE_STORAGE_BASE_URL: str = "http://backend:8000"
|
||||
ONLYOFFICE_INSTANCE_ID: Optional[str] = None
|
||||
ONLYOFFICE_CONFIG_TTL_SECONDS: int = Field(default=300, ge=60, le=900)
|
||||
|
||||
|
||||
@lru_cache
|
||||
@@ -60,6 +67,30 @@ def get_settings() -> Settings:
|
||||
settings = get_settings()
|
||||
|
||||
|
||||
def validate_onlyoffice_configuration() -> None:
|
||||
if not settings.ONLYOFFICE_ENABLED:
|
||||
return
|
||||
secret = (settings.ONLYOFFICE_JWT_SECRET or "").strip()
|
||||
instance_id = (settings.ONLYOFFICE_INSTANCE_ID or "").strip()
|
||||
if secret == settings.JWT_SECRET_KEY:
|
||||
raise RuntimeError("ONLYOFFICE_JWT_SECRET must not reuse JWT_SECRET_KEY")
|
||||
if len(secret) < 32:
|
||||
raise RuntimeError("ONLYOFFICE_JWT_SECRET must contain at least 32 characters when ONLYOFFICE is enabled")
|
||||
if not instance_id:
|
||||
raise RuntimeError("ONLYOFFICE_INSTANCE_ID is required when ONLYOFFICE is enabled")
|
||||
for name, value in (
|
||||
("ONLYOFFICE_INTERNAL_URL", settings.ONLYOFFICE_INTERNAL_URL),
|
||||
("ONLYOFFICE_STORAGE_BASE_URL", settings.ONLYOFFICE_STORAGE_BASE_URL),
|
||||
):
|
||||
parsed = urlsplit(value.strip())
|
||||
if parsed.scheme.lower() not in {"http", "https"} or not parsed.hostname:
|
||||
raise RuntimeError(f"{name} must be an HTTP(S) URL")
|
||||
if parsed.username or parsed.password or parsed.query or parsed.fragment:
|
||||
raise RuntimeError(f"{name} must not contain credentials, a query, or a fragment")
|
||||
if parsed.path not in {"", "/"}:
|
||||
raise RuntimeError(f"{name} must not contain a path")
|
||||
|
||||
|
||||
def get_cors_allowed_origins() -> list[str]:
|
||||
return [
|
||||
origin.strip()
|
||||
|
||||
Reference in New Issue
Block a user