chore: auto release commit (2026-09-15 00:32:44)
All checks were successful
技能自动化发布 / release (push) Successful in 7s
All checks were successful
技能自动化发布 / release (push) Successful in 7s
This commit is contained in:
77
scripts/service/config_viewer.py
Normal file
77
scripts/service/config_viewer.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""读取并脱敏 .env 配置供 UI 查看(v1.1.18)。
|
||||
|
||||
仅显示 .env 文件中的非空 key;命中 (TOKEN|SECRET|KEY|PASSWORD) 的字段自动脱敏为 ***。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from util.runtime_paths import get_env_path
|
||||
|
||||
|
||||
# 匹配任一含 TOKEN / SECRET / KEY / PASSWORD 的 key 名(不区分大小写)
|
||||
_SECRET_PATTERN = re.compile(r"(TOKEN|SECRET|KEY|PASSWORD)", re.IGNORECASE)
|
||||
|
||||
|
||||
def _parse_env_file(path: Path) -> dict[str, str]:
|
||||
"""手动解析 .env(避免依赖 python-dotenv)。
|
||||
|
||||
- 跳过空行 / 注释(# 开头)
|
||||
- 支持 KEY=VALUE 格式
|
||||
- 自动去除包裹的 "..." 或 '...'
|
||||
"""
|
||||
if not path.exists():
|
||||
return {}
|
||||
result: dict[str, str] = {}
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
if "=" not in line:
|
||||
continue
|
||||
k, _, v = line.partition("=")
|
||||
k = k.strip()
|
||||
v = v.strip()
|
||||
# 去掉行尾注释(不处理引号内的 #,简单实现)
|
||||
if " #" in v:
|
||||
v = v.split(" #", 1)[0].strip()
|
||||
if v.startswith('"') and v.endswith('"') and len(v) >= 2:
|
||||
v = v[1:-1]
|
||||
elif v.startswith("'") and v.endswith("'") and len(v) >= 2:
|
||||
v = v[1:-1]
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
|
||||
def _mask_secret(value: str) -> str:
|
||||
if not value:
|
||||
return ""
|
||||
if len(value) <= 4:
|
||||
return "***"
|
||||
return value[:2] + "***" + value[-2:]
|
||||
|
||||
|
||||
def read_env_config() -> dict:
|
||||
"""读取 .env 中的非空 key,敏感 key 脱敏为 ***。
|
||||
|
||||
Returns:
|
||||
{
|
||||
"env_path": str,
|
||||
"exists": bool,
|
||||
"config": {key: value_or_masked_value, ...}
|
||||
}
|
||||
"""
|
||||
path = get_env_path()
|
||||
parsed = _parse_env_file(path)
|
||||
out: dict[str, str] = {}
|
||||
for k, v in sorted(parsed.items()):
|
||||
if not v:
|
||||
continue
|
||||
if _SECRET_PATTERN.search(k):
|
||||
out[k] = _mask_secret(v)
|
||||
else:
|
||||
out[k] = v
|
||||
return {"env_path": str(path), "exists": path.exists(), "config": out}
|
||||
Reference in New Issue
Block a user