From b8c1455c57ad2c41fe4e0867cea34c70d1294866 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:35:15 +0000 Subject: [PATCH 1/2] Initial plan From f2e7d2bdacfe6f9ed505005cb894a81075ab190d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:44:01 +0000 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=20Tenant=20ID=20=E9=95=BF=E5=BA=A6=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: BukeLy <19304666+BukeLy@users.noreply.github.com> --- env.example | 6 ++++++ src/config.py | 12 ++++++++++++ src/tenant_deps.py | 20 ++++++++++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/env.example b/env.example index db7a4f2..800b21c 100644 --- a/env.example +++ b/env.example @@ -230,6 +230,12 @@ MAX_FILE_PATHS=100 # 最大文件路径数(默认100) # 最多缓存多少个租户实例(超过后会使用 LRU 策略清理) MAX_TENANT_INSTANCES=50 +# --- 租户 ID 验证配置 --- +# 租户 ID 最小长度(默认 3) +# TENANT_ID_MIN_LENGTH=3 +# 租户 ID 最大长度(默认 50) +# TENANT_ID_MAX_LENGTH=50 + # ====== RAG-Anything VLM 增强配置 ====== # 用于控制 MinerU 远程模式下的图表处理质量 diff --git a/src/config.py b/src/config.py index 0d1f8f5..288267c 100644 --- a/src/config.py +++ b/src/config.py @@ -241,6 +241,18 @@ class MultiTenantConfig(BaseSettings): alias="MAX_TENANT_INSTANCES" ) + # Tenant ID Validation + tenant_id_min_length: int = Field( + default=3, + description="Minimum Tenant ID Length", + alias="TENANT_ID_MIN_LENGTH" + ) + tenant_id_max_length: int = Field( + default=50, + description="Maximum Tenant ID Length", + alias="TENANT_ID_MAX_LENGTH" + ) + class Config: env_file = ".env" extra = "ignore" diff --git a/src/tenant_deps.py b/src/tenant_deps.py index cf1eb4d..72fac61 100644 --- a/src/tenant_deps.py +++ b/src/tenant_deps.py @@ -8,6 +8,14 @@ from fastapi import Query, HTTPException from src.logger import logger +from src.config import get_config + + +# 在模块加载时获取配置值,用于 Query 参数定义 +# 注意:这些值在模块加载时缓存,配置更改需要重启服务才能生效 +_config = get_config() +_TENANT_ID_MIN_LENGTH = _config.multi_tenant.tenant_id_min_length +_TENANT_ID_MAX_LENGTH = _config.multi_tenant.tenant_id_max_length async def validate_tenant_access(tenant_id: str) -> bool: @@ -33,9 +41,9 @@ async def validate_tenant_access(tenant_id: str) -> bool: logger.warning("Empty tenant_id") return False - # 长度验证(3-50 字符) - if len(tenant_id) < 3 or len(tenant_id) > 50: - logger.warning(f"Invalid tenant_id length: {len(tenant_id)}") + # 长度验证(使用模块级缓存的配置值) + if len(tenant_id) < _TENANT_ID_MIN_LENGTH or len(tenant_id) > _TENANT_ID_MAX_LENGTH: + logger.warning(f"Invalid tenant_id length: {len(tenant_id)} (allowed: {_TENANT_ID_MIN_LENGTH}-{_TENANT_ID_MAX_LENGTH})") return False # 字符验证(仅允许字母、数字、下划线、连字符) @@ -59,9 +67,9 @@ async def validate_tenant_access(tenant_id: str) -> bool: async def get_tenant_id( tenant_id: Optional[str] = Query( default=None, - description="租户ID(必填,3-50字符,支持字母数字下划线连字符)", - min_length=3, - max_length=50, + description=f"租户ID(必填,{_TENANT_ID_MIN_LENGTH}-{_TENANT_ID_MAX_LENGTH}字符,支持字母数字下划线连字符)", + min_length=_TENANT_ID_MIN_LENGTH, + max_length=_TENANT_ID_MAX_LENGTH, regex=r'^[a-zA-Z0-9_-]+$' ) ) -> str: