cjovs commited on
Commit
db95bcf
·
verified ·
1 Parent(s): 89cf340

Stop persisting DeepSeek secrets into bucket config

Browse files
Files changed (2) hide show
  1. app/config.py +70 -11
  2. start_hf.py +15 -44
app/config.py CHANGED
@@ -5,29 +5,88 @@ import os
5
  logger = logging.getLogger(__name__)
6
 
7
  CONFIG_PATH = os.getenv("CONFIG_PATH", "config.json")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  def load_config():
11
  """从 config.json 加载配置,出错则返回空 dict"""
12
  try:
13
  with open(CONFIG_PATH, "r", encoding="utf-8") as f:
14
- return json.load(f)
15
  except Exception as e:
16
  logger.warning(f"[load_config] 无法读取配置文件: {e}")
17
- return {}
18
 
19
 
20
  def save_config(cfg):
21
- """将配置写回 config.json(移除可序列的 _session 字段)"""
22
  try:
23
- # 深拷贝配置,跳过不可序列化的字段
24
- def clean(obj):
25
- if isinstance(obj, dict):
26
- return {k: clean(v) for k, v in obj.items() if not k.startswith("_")}
27
- elif isinstance(obj, list):
28
- return [clean(item) for item in obj]
29
- return obj
30
- cfg_clean = clean(cfg)
31
  with open(CONFIG_PATH, "w", encoding="utf-8") as f:
32
  json.dump(cfg_clean, f, ensure_ascii=False, indent=2)
33
  except Exception as e:
 
5
  logger = logging.getLogger(__name__)
6
 
7
  CONFIG_PATH = os.getenv("CONFIG_PATH", "config.json")
8
+ SENSITIVE_ACCOUNT_FIELDS = {"password", "token", "hif_dliq", "hif_leim"}
9
+
10
+
11
+ def _account_from_env() -> dict:
12
+ account = os.getenv("DEEPSEEK_ACCOUNT", "").strip()
13
+ password = os.getenv("DEEPSEEK_PASSWORD", "").strip()
14
+ if not account or not password:
15
+ return {}
16
+ env_account = {"password": password, "token": ""}
17
+ if "@" in account:
18
+ env_account["email"] = account
19
+ else:
20
+ env_account["mobile"] = account
21
+ return env_account
22
+
23
+
24
+ def _merge_env_secrets(config: dict) -> dict:
25
+ merged = dict(config) if isinstance(config, dict) else {}
26
+
27
+ api_key = os.getenv("DEEPSEEK_API_KEY", "").strip()
28
+ if api_key:
29
+ merged["keys"] = [api_key]
30
+
31
+ env_account = _account_from_env()
32
+ if env_account:
33
+ accounts = merged.get("accounts")
34
+ if not isinstance(accounts, list):
35
+ accounts = []
36
+ desired_identity = env_account.get("email") or env_account.get("mobile")
37
+ identity_key = "email" if "email" in env_account else "mobile"
38
+ replaced = False
39
+ merged_accounts = []
40
+ for account in accounts:
41
+ if not isinstance(account, dict):
42
+ continue
43
+ current_identity = account.get("email") or account.get("mobile")
44
+ if current_identity == desired_identity:
45
+ updated = dict(account)
46
+ updated[identity_key] = desired_identity
47
+ updated["password"] = env_account["password"]
48
+ merged_accounts.append(updated)
49
+ replaced = True
50
+ else:
51
+ merged_accounts.append(account)
52
+ if not replaced:
53
+ merged_accounts.append(env_account)
54
+ merged["accounts"] = merged_accounts
55
+
56
+ return merged
57
+
58
+
59
+ def _sanitize_for_persistence(obj):
60
+ if isinstance(obj, dict):
61
+ sanitized = {}
62
+ for key, value in obj.items():
63
+ if key.startswith("_"):
64
+ continue
65
+ if key == "keys":
66
+ continue
67
+ if key in SENSITIVE_ACCOUNT_FIELDS:
68
+ continue
69
+ sanitized[key] = _sanitize_for_persistence(value)
70
+ return sanitized
71
+ if isinstance(obj, list):
72
+ return [_sanitize_for_persistence(item) for item in obj]
73
+ return obj
74
 
75
 
76
  def load_config():
77
  """从 config.json 加载配置,出错则返回空 dict"""
78
  try:
79
  with open(CONFIG_PATH, "r", encoding="utf-8") as f:
80
+ return _merge_env_secrets(json.load(f))
81
  except Exception as e:
82
  logger.warning(f"[load_config] 无法读取配置文件: {e}")
83
+ return _merge_env_secrets({})
84
 
85
 
86
  def save_config(cfg):
87
+ """将配置写回 config.json,但持久密钥、密码或会话令牌。"""
88
  try:
89
+ cfg_clean = _sanitize_for_persistence(cfg)
 
 
 
 
 
 
 
90
  with open(CONFIG_PATH, "w", encoding="utf-8") as f:
91
  json.dump(cfg_clean, f, ensure_ascii=False, indent=2)
92
  except Exception as e:
start_hf.py CHANGED
@@ -5,40 +5,22 @@ import sys
5
  from pathlib import Path
6
 
7
 
8
- def _account_from_env() -> dict:
9
- account = os.getenv("DEEPSEEK_ACCOUNT", "").strip()
10
- password = os.getenv("DEEPSEEK_PASSWORD", "").strip()
11
- if not account or not password:
12
- return {}
13
- account_config = {"password": password, "token": ""}
14
- if "@" in account:
15
- account_config["email"] = account
16
- else:
17
- account_config["mobile"] = account
18
- return account_config
19
 
20
 
21
- def _merge_account(existing_accounts: list[dict], desired_account: dict) -> list[dict]:
22
- if not desired_account:
23
- return existing_accounts
24
- desired_identity = desired_account.get("email") or desired_account.get("mobile")
25
- identity_key = "email" if "email" in desired_account else "mobile"
26
- merged = []
27
- replaced = False
28
- for account in existing_accounts:
29
- current_identity = account.get("email") or account.get("mobile")
30
- if current_identity == desired_identity:
31
- updated = dict(account)
32
- updated[identity_key] = desired_identity
33
- updated["password"] = desired_account["password"]
34
- updated.setdefault("token", "")
35
- merged.append(updated)
36
- replaced = True
37
- else:
38
- merged.append(account)
39
- if not replaced:
40
- merged.append(desired_account)
41
- return merged
42
 
43
 
44
  def prepare_runtime_files() -> None:
@@ -57,19 +39,8 @@ def prepare_runtime_files() -> None:
57
  except Exception:
58
  config = {}
59
 
60
- api_key = os.getenv("DEEPSEEK_API_KEY", "").strip()
61
- if api_key:
62
- config["keys"] = [api_key]
63
- else:
64
- config.setdefault("keys", [])
65
-
66
- existing_accounts = config.get("accounts")
67
- if not isinstance(existing_accounts, list):
68
- existing_accounts = []
69
- config["accounts"] = _merge_account(existing_accounts, _account_from_env())
70
-
71
  config_path.write_text(
72
- json.dumps(config, ensure_ascii=False, indent=2),
73
  encoding="utf-8",
74
  )
75
  db_path.touch(exist_ok=True)
 
5
  from pathlib import Path
6
 
7
 
8
+ SENSITIVE_FIELDS = {"keys", "password", "token", "hif_dliq", "hif_leim"}
 
 
 
 
 
 
 
 
 
 
9
 
10
 
11
+ def _sanitize_for_persistence(obj):
12
+ if isinstance(obj, dict):
13
+ sanitized = {}
14
+ for key, value in obj.items():
15
+ if key.startswith("_"):
16
+ continue
17
+ if key in SENSITIVE_FIELDS:
18
+ continue
19
+ sanitized[key] = _sanitize_for_persistence(value)
20
+ return sanitized
21
+ if isinstance(obj, list):
22
+ return [_sanitize_for_persistence(item) for item in obj]
23
+ return obj
 
 
 
 
 
 
 
 
24
 
25
 
26
  def prepare_runtime_files() -> None:
 
39
  except Exception:
40
  config = {}
41
 
 
 
 
 
 
 
 
 
 
 
 
42
  config_path.write_text(
43
+ json.dumps(_sanitize_for_persistence(config), ensure_ascii=False, indent=2),
44
  encoding="utf-8",
45
  )
46
  db_path.touch(exist_ok=True)