local_config_service.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import os
  2. import sqlite3
  3. from typing import Optional
  4. # DB path: backend/data/local_config.db(相对于本文件所在的 services 目录往上两级)
  5. _THIS_DIR = os.path.dirname(os.path.abspath(__file__))
  6. _BACKEND_ROOT = os.path.abspath(os.path.join(_THIS_DIR, "..", ".."))
  7. DB_PATH = os.path.join(_BACKEND_ROOT, "data", "local_config.db")
  8. _SSO_KEYS = [
  9. "sso_enable_redirect",
  10. "cas_base_url",
  11. "app_public_base_url",
  12. "frontend_base_url",
  13. "sso_service_path",
  14. "sso_login_url",
  15. "sso_logout_url",
  16. ]
  17. _ADMIN_API_KEY_KEYS = ["admin_api_key"]
  18. def _init_db() -> None:
  19. os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
  20. with sqlite3.connect(DB_PATH) as conn:
  21. conn.execute(
  22. """
  23. CREATE TABLE IF NOT EXISTS local_config (
  24. key TEXT PRIMARY KEY,
  25. value TEXT NOT NULL,
  26. updated_at DATETIME DEFAULT (datetime('now'))
  27. )
  28. """
  29. )
  30. conn.commit()
  31. def get_all() -> dict:
  32. rows: dict[str, str] = {}
  33. with sqlite3.connect(DB_PATH) as conn:
  34. cursor = conn.execute("SELECT key, value FROM local_config")
  35. for key, value in cursor.fetchall():
  36. rows[key] = value
  37. sso: dict = {}
  38. for k in _SSO_KEYS:
  39. raw = rows.get(k) # None 表示 db 中没有该 key
  40. if raw is None:
  41. sso[k] = None # 让调用方自行决定默认值
  42. elif k == "sso_enable_redirect":
  43. sso[k] = raw == "true"
  44. else:
  45. sso[k] = raw
  46. admin_api_key_raw = rows.get("admin_api_key", "")
  47. admin_api_key_section = {
  48. "admin_api_key": "***" if admin_api_key_raw else ""
  49. }
  50. return {"sso": sso, "admin_api_key": admin_api_key_section}
  51. def get_admin_api_key() -> Optional[str]:
  52. """返回原始(未脱敏)的 admin_api_key,不存在则返回 None。"""
  53. try:
  54. with sqlite3.connect(DB_PATH) as conn:
  55. row = conn.execute("SELECT value FROM local_config WHERE key='admin_api_key'").fetchone()
  56. return row[0] if row else None
  57. except Exception:
  58. return None
  59. def upsert(conn: sqlite3.Connection, key: str, value: str) -> None:
  60. conn.execute(
  61. "INSERT OR REPLACE INTO local_config (key, value, updated_at) VALUES (?, ?, datetime('now'))",
  62. (key, value),
  63. )
  64. def upsert_many(data: dict) -> None:
  65. with sqlite3.connect(DB_PATH) as conn:
  66. for key, value in data.items():
  67. upsert(conn, key, value)
  68. conn.commit()
  69. # Ensure table exists on first import
  70. _init_db()