From ddb8cb8471c0b166bb17a5cd33271f751dce6d82 Mon Sep 17 00:00:00 2001 From: hiderfong Date: Sat, 25 Apr 2026 09:05:08 +0800 Subject: [PATCH] =?UTF-8?q?security:=20=E4=BF=AE=E6=94=B9admin=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E5=B9=B6=E7=A7=BB=E9=99=A4=E5=89=8D=E7=AB=AF=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E8=B4=A6=E6=88=B7=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将admin默认密码从admin123修改为Zhidi@n2023 - 更新数据库中admin用户密码哈希 - 更新后端配置、环境变量模板及测试脚本中的密码 - 移除登录页默认管理员账户密码提示文字 - 清空登录表单密码默认值,避免泄露 - 重新构建前端dist产物 --- backend/.env.example | 2 +- backend/app/core/config.py | 2 +- backend/scripts/api_integration_test.py | 180 ++++++++++++------------ backend/tests/test_auth.py | 2 +- frontend/dist/index.html | 2 +- frontend/src/views/auth/Login.vue | 4 +- 6 files changed, 97 insertions(+), 95 deletions(-) diff --git a/backend/.env.example b/backend/.env.example index 316c0d90..bb33f8e8 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -25,5 +25,5 @@ REFRESH_TOKEN_EXPIRE_DAYS=7 # Default superuser (created on first startup) FIRST_SUPERUSER_USERNAME=admin -FIRST_SUPERUSER_PASSWORD=admin123 +FIRST_SUPERUSER_PASSWORD=Zhidi@n2023 FIRST_SUPERUSER_EMAIL=admin@datapo.com diff --git a/backend/app/core/config.py b/backend/app/core/config.py index b1644871..67cf8ca8 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -29,7 +29,7 @@ class Settings(BaseSettings): CORS_ORIGINS: List[str] = ["http://localhost:5173", "http://127.0.0.1:5173"] FIRST_SUPERUSER_USERNAME: str = "admin" - FIRST_SUPERUSER_PASSWORD: str = "admin123" + FIRST_SUPERUSER_PASSWORD: str = "Zhidi@n2023" FIRST_SUPERUSER_EMAIL: str = "admin@datapo.com" class Config: diff --git a/backend/scripts/api_integration_test.py b/backend/scripts/api_integration_test.py index 50b24a00..e53b9095 100644 --- a/backend/scripts/api_integration_test.py +++ b/backend/scripts/api_integration_test.py @@ -1,4 +1,5 @@ import sys, requests + BASE = "http://localhost:8000" API = f"{BASE}/api/v1" errors, passed = [], [] @@ -13,112 +14,113 @@ def get_items(resp): d = resp.json().get("data", []) if isinstance(d, list): return d - if isinstance(d, dict): - return d.get("items", []) - return [] + return d.get("items", []) def get_total(resp): return resp.json().get("total", 0) -print("\n[1/15] Health") -r = requests.get(f"{BASE}/health") -check("health", r.status_code == 200 and r.json().get("status") == "ok") +def main(): + print("\n[1/15] Health") + r = requests.get(f"{BASE}/health") + check("health", r.status_code == 200 and r.json().get("status") == "ok") -print("\n[2/15] Auth") -r = requests.post(f"{API}/auth/login", json={"username": "admin", "password": "admin123"}) -check("login", r.status_code == 200) -token = r.json().get("data", {}).get("access_token", "") -check("token", bool(token)) -headers = {"Authorization": f"Bearer {token}"} + print("\n[2/15] Auth") + r = requests.post(f"{API}/auth/login", json={"username": "admin", "password": "Zhidi@n2023"}) + check("login", r.status_code == 200) + token = r.json().get("data", {}).get("access_token", "") + check("token", bool(token)) + headers = {"Authorization": f"Bearer {token}"} -print("\n[3/15] User") -r = requests.get(f"{API}/users/me", headers=headers) -check("me", r.status_code == 200 and r.json()["data"]["username"] == "admin") -r = requests.get(f"{API}/users?page_size=100", headers=headers) -check("users", r.status_code == 200 and len(get_items(r)) >= 80, f"got {len(get_items(r))}") + print("\n[3/15] User") + r = requests.get(f"{API}/users/me", headers=headers) + check("me", r.status_code == 200 and r.json()["data"]["username"] == "admin") + r = requests.get(f"{API}/users?page_size=100", headers=headers) + check("users", r.status_code == 200 and len(get_items(r)) >= 80, f"got {len(get_items(r))}") -print("\n[4/15] Depts") -r = requests.get(f"{API}/users/depts", headers=headers) -check("depts", r.status_code == 200 and len(r.json().get("data", [])) >= 12, f"got {len(r.json().get('data', []))}") + print("\n[4/15] Depts") + r = requests.get(f"{API}/users/depts", headers=headers) + check("depts", r.status_code == 200 and len(r.json().get("data", [])) >= 12, f"got {len(r.json().get('data', []))}") -print("\n[5/15] DataSources") -r = requests.get(f"{API}/datasources", headers=headers) -check("datasources", r.status_code == 200 and len(get_items(r)) >= 12, f"got {len(get_items(r))}") + print("\n[5/15] DataSources") + r = requests.get(f"{API}/datasources", headers=headers) + check("datasources", r.status_code == 200 and len(get_items(r)) >= 12, f"got {len(get_items(r))}") -print("\n[6/15] Metadata") -r = requests.get(f"{API}/metadata/databases", headers=headers) -check("databases", r.status_code == 200 and len(get_items(r)) >= 31, f"got {len(get_items(r))}") -r = requests.get(f"{API}/metadata/tables", headers=headers) -check("tables", r.status_code == 200 and len(get_items(r)) >= 800, f"got {len(get_items(r))}") -r = requests.get(f"{API}/metadata/columns", headers=headers) -check("columns", r.status_code == 200 and get_total(r) >= 10000, f"total={get_total(r)}") + print("\n[6/15] Metadata") + r = requests.get(f"{API}/metadata/databases", headers=headers) + check("databases", r.status_code == 200 and len(get_items(r)) >= 31, f"got {len(get_items(r))}") + r = requests.get(f"{API}/metadata/tables", headers=headers) + check("tables", r.status_code == 200 and len(get_items(r)) >= 800, f"got {len(get_items(r))}") + r = requests.get(f"{API}/metadata/columns", headers=headers) + check("columns", r.status_code == 200 and get_total(r) >= 10000, f"total={get_total(r)}") -print("\n[7/15] Classification") -r = requests.get(f"{API}/classifications/levels", headers=headers) -check("levels", r.status_code == 200 and len(r.json().get("data", [])) == 5) -r = requests.get(f"{API}/classifications/categories", headers=headers) -check("categories", r.status_code == 200 and len(r.json().get("data", [])) >= 20, f"got {len(r.json().get('data', []))}") -r = requests.get(f"{API}/classifications/results", headers=headers) -check("results", r.status_code == 200 and get_total(r) >= 1000, f"total={get_total(r)}") + print("\n[7/15] Classification") + r = requests.get(f"{API}/classifications/levels", headers=headers) + check("levels", r.status_code == 200 and len(r.json().get("data", [])) == 5) + r = requests.get(f"{API}/classifications/categories", headers=headers) + check("categories", r.status_code == 200 and len(r.json().get("data", [])) >= 20, f"got {len(r.json().get('data', []))}") + r = requests.get(f"{API}/classifications/results", headers=headers) + check("results", r.status_code == 200 and get_total(r) >= 1000, f"total={get_total(r)}") -print("\n[8/15] Projects") -r = requests.get(f"{API}/projects", headers=headers) -check("projects", r.status_code == 200 and len(get_items(r)) >= 8, f"got {len(get_items(r))}") + print("\n[8/15] Projects") + r = requests.get(f"{API}/projects", headers=headers) + check("projects", r.status_code == 200 and len(get_items(r)) >= 8, f"got {len(get_items(r))}") -print("\n[9/15] Tasks") -r = requests.get(f"{API}/tasks/my-tasks", headers=headers) -check("tasks", r.status_code == 200 and len(get_items(r)) >= 20, f"got {len(get_items(r))}") + print("\n[9/15] Tasks") + r = requests.get(f"{API}/tasks/my-tasks", headers=headers) + check("tasks", r.status_code == 200 and len(get_items(r)) >= 20, f"got {len(get_items(r))}") -print("\n[10/15] Dashboard") -r = requests.get(f"{API}/dashboard/stats", headers=headers) -check("stats", r.status_code == 200) -stats = r.json().get("data", {}) -check("stats.data_sources", stats.get("data_sources", 0) >= 12, f"got {stats.get('data_sources')}") -check("stats.tables", stats.get("tables", 0) >= 800, f"got {stats.get('tables')}") -check("stats.columns", stats.get("columns", 0) >= 10000, f"got {stats.get('columns')}") -check("stats.labeled", stats.get("labeled", 0) >= 10000, f"got {stats.get('labeled')}") -r = requests.get(f"{API}/dashboard/distribution", headers=headers) -check("distribution", r.status_code == 200 and "level_distribution" in r.json().get("data", {})) + print("\n[10/15] Dashboard") + r = requests.get(f"{API}/dashboard/stats", headers=headers) + check("stats", r.status_code == 200) + stats = r.json().get("data", {}) + check("stats.data_sources", stats.get("data_sources", 0) >= 12, f"got {stats.get('data_sources')}") + check("stats.tables", stats.get("tables", 0) >= 800, f"got {stats.get('tables')}") + check("stats.columns", stats.get("columns", 0) >= 10000, f"got {stats.get('columns')}") + check("stats.labeled", stats.get("labeled", 0) >= 10000, f"got {stats.get('labeled')}") + r = requests.get(f"{API}/dashboard/distribution", headers=headers) + check("distribution", r.status_code == 200 and "level_distribution" in r.json().get("data", {})) -print("\n[11/15] Reports") -r = requests.get(f"{API}/reports/stats", headers=headers) -check("report stats", r.status_code == 200) + print("\n[11/15] Reports") + r = requests.get(f"{API}/reports/stats", headers=headers) + check("report stats", r.status_code == 200) -print("\n[12/15] Masking") -r = requests.get(f"{API}/masking/rules", headers=headers) -check("masking rules", r.status_code == 200) + print("\n[12/15] Masking") + r = requests.get(f"{API}/masking/rules", headers=headers) + check("masking rules", r.status_code == 200) -print("\n[13/15] Watermark") -r = requests.post(f"{API}/watermark/trace", headers={**headers, "Content-Type": "application/json"}, json={"content": "test watermark"}) -check("watermark trace", r.status_code == 200) + print("\n[13/15] Watermark") + r = requests.post(f"{API}/watermark/trace", headers={**headers, "Content-Type": "application/json"}, json={"content": "test watermark"}) + check("watermark trace", r.status_code == 200) -print("\n[14/15] Risk") -r = requests.get(f"{API}/risk/top", headers=headers) -check("risk top", r.status_code == 200) + print("\n[14/15] Risk") + r = requests.get(f"{API}/risk/top", headers=headers) + check("risk top", r.status_code == 200) -print("\n[15/15] Compliance") -r = requests.get(f"{API}/compliance/issues", headers=headers) -check("compliance issues", r.status_code == 200) + print("\n[15/15] Compliance") + r = requests.get(f"{API}/compliance/issues", headers=headers) + check("compliance issues", r.status_code == 200) -# Additional modules -print("\n[Bonus] Additional modules") -r = requests.get(f"{API}/lineage/graph", headers=headers) -check("lineage graph", r.status_code == 200 and "nodes" in r.json().get("data", {})) -r = requests.get(f"{API}/alerts/records", headers=headers) -check("alert records", r.status_code == 200) -r = requests.get(f"{API}/schema-changes/logs", headers=headers) -check("schema changes logs", r.status_code == 200) -r = requests.get(f"{API}/unstructured/files", headers=headers) -check("unstructured files", r.status_code == 200) -r = requests.get(f"{API}/api-assets", headers=headers) -check("api assets", r.status_code == 200) + print("\n[Bonus] Additional modules") + r = requests.get(f"{API}/lineage/graph", headers=headers) + check("lineage graph", r.status_code == 200 and "nodes" in r.json().get("data", {})) + r = requests.get(f"{API}/alerts/records", headers=headers) + check("alert records", r.status_code == 200) + r = requests.get(f"{API}/schema-changes/logs", headers=headers) + check("schema changes logs", r.status_code == 200) + r = requests.get(f"{API}/unstructured/files", headers=headers) + check("unstructured files", r.status_code == 200) + r = requests.get(f"{API}/api-assets", headers=headers) + check("api assets", r.status_code == 200) -print("\n" + "="*60) -print(f"Results: {len(passed)} passed, {len(errors)} failed") -print("="*60) -if errors: - for n, d in errors: print(f" ❌ {n}: {d}") - sys.exit(1) -else: - print("🎉 All integration tests passed!") - sys.exit(0) + print("\n" + "="*60) + print(f"Results: {len(passed)} passed, {len(errors)} failed") + print("="*60) + if errors: + for n, d in errors: print(f" ❌ {n}: {d}") + sys.exit(1) + else: + print("🎉 All integration tests passed!") + sys.exit(0) + +if __name__ == "__main__": + main() diff --git a/backend/tests/test_auth.py b/backend/tests/test_auth.py index 74258a4e..8b164e6c 100644 --- a/backend/tests/test_auth.py +++ b/backend/tests/test_auth.py @@ -47,7 +47,7 @@ def test_health_check(): def test_login(): - response = client.post("/api/v1/auth/login", json={"username": "admin", "password": "admin123"}) + response = client.post("/api/v1/auth/login", json={"username": "admin", "password": "Zhidi@n2023"}) assert response.status_code == 200 data = response.json() assert data["code"] == 200 diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 3582673a..ea8c4313 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -5,7 +5,7 @@ DataPointer - 数据分类分级管理平台 - + diff --git a/frontend/src/views/auth/Login.vue b/frontend/src/views/auth/Login.vue index 6514ff20..68923849 100644 --- a/frontend/src/views/auth/Login.vue +++ b/frontend/src/views/auth/Login.vue @@ -45,7 +45,7 @@ @@ -65,7 +65,7 @@ const formRef = ref() const form = reactive({ username: 'admin', - password: 'admin123', + password: '', }) const rules = {