fix(security): retire default-credential surface (yanxue-20260914-cma-defaultcred-code-fix)
- Login.vue: no prefilled default creds; no anonymous entity enumeration on mount - deploy.sh: readiness polling (0.5s/30s cap) replaces fixed sleep 3; login smoke reads same-source 600 secret file, missing file = explicit abort - 19 verify/check/gen_report scripts: shared _admin_creds() loader (CMA_ADMIN_ENV -> ops .secrets -> profile copy); no hardcoded creds - tests: single TEST_USER_PASSWORD fixture constant; docs: pointer to 600 secret file; removed 4 legacy .bak + pycache residue
This commit is contained in:
@@ -26,6 +26,32 @@ import urllib.request
|
||||
|
||||
import pymysql
|
||||
|
||||
# 2026-09-14 凭据面收口(cma-defaultcred-code-fix):原快照里的硬编码默认账号/口令改为同源加载,
|
||||
# 快照的期/阈值断言一字未动(历史原文仍在 git 历史里)。
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
if os.environ.get("FORCE_SNAPSHOT") != "1":
|
||||
print("⛔ 这是 20260908 的历史验收快照,不是活检查;复跑结果不代表当前回归。")
|
||||
print(" 现行活检查:python3 backend/scripts/verify_bep_threshold_fix.py")
|
||||
@@ -120,7 +146,7 @@ check("576 GAP red pending", alerts.get(576) == ("red", "pending"), str(alerts.g
|
||||
check("577 COVER_CASH yellow pending", alerts.get(577) == ("yellow", "pending"), str(alerts.get(577)))
|
||||
|
||||
print("== 5. bep-card 端点 ==")
|
||||
login = http_json("/api/cma/auth/login", "POST", {"username": "admin", "password": "admin123", "entity_id": 1})
|
||||
login = http_json("/api/cma/auth/login", "POST", {"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": 1})
|
||||
card = http_json("/api/cma/dashboard/bep-card", token=login["token"])
|
||||
check("available", card.get("available") is True)
|
||||
check("book red", card["book"]["cover_level"] == "red", str(card["book"]))
|
||||
|
||||
@@ -18,6 +18,30 @@ import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "http://127.0.0.1:8010"
|
||||
MARK = "【系统验证临时数据-验证后删除】"
|
||||
KPI_CODE = "E2E_WT_TIER"
|
||||
@@ -75,7 +99,7 @@ def main():
|
||||
|
||||
# ── 1. 登录(人token, entity=1) ──
|
||||
st, r = http("POST", "/api/cma/auth/login",
|
||||
{"username": "admin", "password": "admin123", "entity_id": 1})
|
||||
{"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": 1})
|
||||
check("登录 admin entity=1", st == 200, f"http={st}")
|
||||
token = r.get("token") if st == 200 else ""
|
||||
auth = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
@@ -11,6 +11,31 @@ import time
|
||||
import urllib.request
|
||||
import websocket
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
CDP_HTTP = "http://127.0.0.1:9224"
|
||||
BASE = "https://cma.sxbh.ltd/api/cma"
|
||||
|
||||
@@ -78,7 +103,7 @@ def login_via_fetch(c, entity_id):
|
||||
(async () => {{
|
||||
const r = await fetch('{BASE}/auth/login', {{
|
||||
method: 'POST', headers: {{'Content-Type': 'application/json'}},
|
||||
body: JSON.stringify({{username:'admin', password:'admin123', entity_id:{entity_id}}})
|
||||
body: JSON.stringify({{username:'{ADMIN_USER}', password:'{ADMIN_PASS}', entity_id:{entity_id}}})
|
||||
}});
|
||||
const j = await r.json();
|
||||
if (!r.ok) return 'LOGIN_FAIL:' + JSON.stringify(j);
|
||||
|
||||
@@ -3,6 +3,31 @@
|
||||
"""2026-09-07 预算版本管理UI修复 - 生产API验证"""
|
||||
import json, urllib.request, ssl, sys
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "https://cma.sxbh.ltd/api/cma"
|
||||
|
||||
def http(url, data=None, headers=None, method=None):
|
||||
@@ -14,7 +39,7 @@ def http(url, data=None, headers=None, method=None):
|
||||
return json.loads(r.read().decode())
|
||||
|
||||
def login(entity_id):
|
||||
body = json.dumps({"username": "admin", "password": "admin123", "entity_id": entity_id}).encode()
|
||||
body = json.dumps({"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": entity_id}).encode()
|
||||
r = http(BASE + "/auth/login", data=body, headers={"Content-Type": "application/json"}, method="POST")
|
||||
return r["token"]
|
||||
|
||||
|
||||
@@ -18,6 +18,31 @@ import sys
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "http://127.0.0.1:8010"
|
||||
TMP_MARK = "【系统验证临时数据-验证后删除】"
|
||||
|
||||
@@ -52,7 +77,7 @@ def main():
|
||||
|
||||
# 1. 登录博海账套 (admin, entity_id=2)
|
||||
st, r = http("POST", "/api/cma/auth/login",
|
||||
{"username": "admin", "password": "admin123", "entity_id": 2})
|
||||
{"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": 2})
|
||||
check("登录博海(entity_id=2)", st == 200 and "token" in (r or {}),
|
||||
f"st={st} keys={sorted((r or {}).keys())}")
|
||||
token = (r or {}).get("token", "")
|
||||
|
||||
@@ -23,6 +23,30 @@ import urllib.request
|
||||
import urllib.error
|
||||
from datetime import datetime
|
||||
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "http://127.0.0.1:8010"
|
||||
MARK = "【系统验证临时数据-验证后删除】"
|
||||
PREFIX = "E2E-RD-"
|
||||
@@ -63,7 +87,7 @@ def main():
|
||||
|
||||
# ── 0. 登录(admin entity=1) ──
|
||||
st, r = http("POST", "/api/cma/auth/login",
|
||||
{"username": "admin", "password": "admin123", "entity_id": 1})
|
||||
{"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": 1})
|
||||
check("登录 admin entity=1", st == 200, f"http={st}")
|
||||
token = r.get("token") if st == 200 else ""
|
||||
auth = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
@@ -15,8 +15,33 @@ import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "http://127.0.0.1:8010"
|
||||
ADMIN = {"username": "admin", "password": "admin123"}
|
||||
ADMIN = {"username": ADMIN_USER, "password": ADMIN_PASS}
|
||||
MARK = "【系统验证临时数据-验证后删除】"
|
||||
TEMP_TAG = "e2e-verify-temp"
|
||||
RULE_TYPE = "customer_concentration"
|
||||
|
||||
@@ -7,6 +7,30 @@ import pymysql
|
||||
|
||||
# 2026-09-12 库访问治理(ops):凭据从 backend/.env 读取,无明文兜底
|
||||
import os
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
try:
|
||||
from dotenv import load_dotenv as _ld_gov
|
||||
_ld_gov('/root/cma-management/backend/.env')
|
||||
@@ -38,7 +62,7 @@ def get(path, token):
|
||||
|
||||
def main():
|
||||
# 1. 登录 entity1
|
||||
r = post("/api/cma/auth/login", {"username": "admin", "password": "admin123", "entity_id": 1})
|
||||
r = post("/api/cma/auth/login", {"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": 1})
|
||||
token = r.get("access_token") or r.get("token")
|
||||
assert token, f"登录失败: {r}"
|
||||
print("1. 登录 entity1 OK")
|
||||
|
||||
@@ -3,6 +3,31 @@ import json
|
||||
import sys
|
||||
import urllib.request
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "http://127.0.0.1:8010"
|
||||
|
||||
|
||||
@@ -28,7 +53,7 @@ def post(path, body, token=None, method="POST"):
|
||||
|
||||
def main():
|
||||
# 1. 登录(账套模式 entity_id=1)
|
||||
status, login = post("/api/cma/auth/login", {"username": "admin", "password": "admin123", "entity_id": 1})
|
||||
status, login = post("/api/cma/auth/login", {"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": 1})
|
||||
token = login.get("token") or login.get("access_token")
|
||||
if status != 200 or not token:
|
||||
print("FAIL login:", status, login)
|
||||
|
||||
@@ -8,6 +8,30 @@ import os
|
||||
import json
|
||||
import urllib.request
|
||||
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = os.getenv("CMA_BASE", "http://127.0.0.1:8010")
|
||||
|
||||
|
||||
@@ -24,7 +48,7 @@ def post(path, body, token=None):
|
||||
|
||||
def main():
|
||||
# 登录(账套模式必须 entity_id)
|
||||
login = post("/api/cma/auth/login", {"username": "admin", "password": "admin123", "entity_id": 1})
|
||||
login = post("/api/cma/auth/login", {"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": 1})
|
||||
token = login.get("token") or login.get("access_token")
|
||||
if not token:
|
||||
print("❌ 登录失败:", login)
|
||||
|
||||
@@ -15,8 +15,33 @@ import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "http://127.0.0.1:8010"
|
||||
ADMIN = {"username": "admin", "password": "admin123"}
|
||||
ADMIN = {"username": ADMIN_USER, "password": ADMIN_PASS}
|
||||
MARK = "【系统验证临时数据-验证后删除】"
|
||||
|
||||
# 规则目标:酣客 → 应收账款周转天数(F_AR_DAYS, id=6,有 2026-09 预测日志)
|
||||
|
||||
@@ -5,6 +5,31 @@
|
||||
"""
|
||||
import sys
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
env = {}
|
||||
with open('/root/cma-management/backend/.env') as f:
|
||||
for line in f:
|
||||
@@ -85,7 +110,7 @@ def api(method, path, token=None, body=None):
|
||||
return e.code, e.read().decode()
|
||||
|
||||
def login(eid):
|
||||
st, body = api("POST", "/api/cma/auth/login", body={"username": "admin", "password": "admin123", "entity_id": eid})
|
||||
st, body = api("POST", "/api/cma/auth/login", body={"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": eid})
|
||||
if st != 200:
|
||||
print(f" ⚠️ 登录 entity{eid} 失败 {st}: {body[:200]}")
|
||||
return None
|
||||
|
||||
@@ -10,6 +10,31 @@ import sys
|
||||
import time
|
||||
import urllib.request
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
BASE = "http://127.0.0.1:8010/api/cma"
|
||||
MARK = "【系统验证临时数据-验证后删除】"
|
||||
PASSED = []
|
||||
@@ -36,7 +61,7 @@ def api(method, path, token=None, body=None):
|
||||
return e.code, {"detail": raw[:300]}
|
||||
|
||||
def login(entity_id):
|
||||
st, d = api("POST", "/auth/login", body={"username": "admin", "password": "admin123", "entity_id": entity_id})
|
||||
st, d = api("POST", "/auth/login", body={"username": ADMIN_USER, "password": ADMIN_PASS, "entity_id": entity_id})
|
||||
assert st == 200, f"login entity{entity_id} fail: {d}"
|
||||
return d["token"]
|
||||
|
||||
|
||||
@@ -16,10 +16,35 @@ import time
|
||||
import urllib.request
|
||||
import websocket
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
CDP_HTTP = "http://127.0.0.1:9224"
|
||||
FIXED_URL = "http://127.0.0.1:5199"
|
||||
MULTI_URL = "http://127.0.0.1:5200"
|
||||
USER, PWD = "admin", "admin123"
|
||||
USER, PWD = ADMIN_USER, ADMIN_PASS
|
||||
|
||||
FAILS = []
|
||||
PASSES = []
|
||||
|
||||
@@ -12,6 +12,31 @@ import time
|
||||
import urllib.request
|
||||
import websocket
|
||||
|
||||
import os # noqa: E402 (凭据加载器需要)
|
||||
# ---- 管理员凭据同源加载(2026-09-14 cma-defaultcred-code-fix)----
|
||||
# 生产凭据只存 600 密钥文件;禁止在脚本/文档/日志里硬编码口令。
|
||||
# 顺序:$CMA_ADMIN_ENV → wecom-ops 主副本(ops 轮换落点,权威) → 本 profile 副本。
|
||||
def _admin_creds():
|
||||
"""返回 (user, password, 来源文件);未找到 → 显式报错退出(不静默退回默认口令)"""
|
||||
for p in (os.environ.get("CMA_ADMIN_ENV"),
|
||||
"/root/.hermes/profiles/wecom-ops/.secrets/cma-admin.env",
|
||||
"/root/.hermes/profiles/wecom-fullstack/.secrets/cma-admin.env"):
|
||||
if p and os.path.isfile(p):
|
||||
kv = {}
|
||||
for line in open(p, encoding="utf-8"):
|
||||
line = line.strip()
|
||||
if "=" in line and not line.startswith("#"):
|
||||
k, v = line.split("=", 1)
|
||||
kv[k.strip()] = v.strip().strip('"').strip("'")
|
||||
if kv.get("CMA_ADMIN_USER") and kv.get("CMA_ADMIN_PASS"):
|
||||
return kv["CMA_ADMIN_USER"], kv["CMA_ADMIN_PASS"], p
|
||||
raise SystemExit("[错误] 未找到 CMA 管理员凭据:请设 $CMA_ADMIN_ENV,或准备 600 权限密钥文件 "
|
||||
".secrets/cma-admin.env(键名 CMA_ADMIN_USER / CMA_ADMIN_PASS)")
|
||||
|
||||
|
||||
ADMIN_USER, ADMIN_PASS, CRED_SRC = _admin_creds()
|
||||
print(f"[creds] 来源={CRED_SRC} 账号={ADMIN_USER}(口令不回显)")
|
||||
|
||||
CDP_HTTP = "http://127.0.0.1:9225"
|
||||
TITLE_NEEDLE = "E2E-验证 建议中心UI实证"
|
||||
|
||||
@@ -80,7 +105,7 @@ def main():
|
||||
(async () => {
|
||||
const d = await (await fetch('/api/cma/auth/login', {method:'POST',
|
||||
headers:{'Content-Type':'application/json'},
|
||||
body: JSON.stringify({username:'admin', password:'admin123', entity_id:1})
|
||||
body: JSON.stringify({username:'__CMA_ADMIN_USER__', password:'__CMA_ADMIN_PASS__', entity_id:1})
|
||||
})).json();
|
||||
if (!d.token) return 'LOGIN_FAIL: ' + JSON.stringify(d).slice(0,200);
|
||||
localStorage.setItem('cma_token', d.token);
|
||||
@@ -90,7 +115,7 @@ def main():
|
||||
location.href = '/ai-suggestions';
|
||||
return 'LOGIN_OK entity=' + d.entity_id;
|
||||
})()
|
||||
"""
|
||||
""".replace("__CMA_ADMIN_USER__", ADMIN_USER).replace("__CMA_ADMIN_PASS__", ADMIN_PASS)
|
||||
print("LOGIN:", c.eval(js_login))
|
||||
time.sleep(6)
|
||||
print("URL:", c.eval("location.href"))
|
||||
|
||||
Reference in New Issue
Block a user