security: 修改admin密码并移除前端默认账户显示

- 将admin默认密码从admin123修改为Zhidi@n2023
- 更新数据库中admin用户密码哈希
- 更新后端配置、环境变量模板及测试脚本中的密码
- 移除登录页默认管理员账户密码提示文字
- 清空登录表单密码默认值,避免泄露
- 重新构建前端dist产物
This commit is contained in:
hiderfong
2026-04-25 09:05:08 +08:00
parent 6d70520e79
commit ddb8cb8471
6 changed files with 97 additions and 95 deletions
+1 -1
View File
@@ -25,5 +25,5 @@ REFRESH_TOKEN_EXPIRE_DAYS=7
# Default superuser (created on first startup) # Default superuser (created on first startup)
FIRST_SUPERUSER_USERNAME=admin FIRST_SUPERUSER_USERNAME=admin
FIRST_SUPERUSER_PASSWORD=admin123 FIRST_SUPERUSER_PASSWORD=Zhidi@n2023
FIRST_SUPERUSER_EMAIL=admin@datapo.com FIRST_SUPERUSER_EMAIL=admin@datapo.com
+1 -1
View File
@@ -29,7 +29,7 @@ class Settings(BaseSettings):
CORS_ORIGINS: List[str] = ["http://localhost:5173", "http://127.0.0.1:5173"] CORS_ORIGINS: List[str] = ["http://localhost:5173", "http://127.0.0.1:5173"]
FIRST_SUPERUSER_USERNAME: str = "admin" FIRST_SUPERUSER_USERNAME: str = "admin"
FIRST_SUPERUSER_PASSWORD: str = "admin123" FIRST_SUPERUSER_PASSWORD: str = "Zhidi@n2023"
FIRST_SUPERUSER_EMAIL: str = "admin@datapo.com" FIRST_SUPERUSER_EMAIL: str = "admin@datapo.com"
class Config: class Config:
+91 -89
View File
@@ -1,4 +1,5 @@
import sys, requests import sys, requests
BASE = "http://localhost:8000" BASE = "http://localhost:8000"
API = f"{BASE}/api/v1" API = f"{BASE}/api/v1"
errors, passed = [], [] errors, passed = [], []
@@ -13,112 +14,113 @@ def get_items(resp):
d = resp.json().get("data", []) d = resp.json().get("data", [])
if isinstance(d, list): if isinstance(d, list):
return d return d
if isinstance(d, dict): return d.get("items", [])
return d.get("items", [])
return []
def get_total(resp): def get_total(resp):
return resp.json().get("total", 0) return resp.json().get("total", 0)
print("\n[1/15] Health") def main():
r = requests.get(f"{BASE}/health") print("\n[1/15] Health")
check("health", r.status_code == 200 and r.json().get("status") == "ok") r = requests.get(f"{BASE}/health")
check("health", r.status_code == 200 and r.json().get("status") == "ok")
print("\n[2/15] Auth") print("\n[2/15] Auth")
r = requests.post(f"{API}/auth/login", json={"username": "admin", "password": "admin123"}) r = requests.post(f"{API}/auth/login", json={"username": "admin", "password": "Zhidi@n2023"})
check("login", r.status_code == 200) check("login", r.status_code == 200)
token = r.json().get("data", {}).get("access_token", "") token = r.json().get("data", {}).get("access_token", "")
check("token", bool(token)) check("token", bool(token))
headers = {"Authorization": f"Bearer {token}"} headers = {"Authorization": f"Bearer {token}"}
print("\n[3/15] User") print("\n[3/15] User")
r = requests.get(f"{API}/users/me", headers=headers) r = requests.get(f"{API}/users/me", headers=headers)
check("me", r.status_code == 200 and r.json()["data"]["username"] == "admin") check("me", r.status_code == 200 and r.json()["data"]["username"] == "admin")
r = requests.get(f"{API}/users?page_size=100", headers=headers) 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))}") check("users", r.status_code == 200 and len(get_items(r)) >= 80, f"got {len(get_items(r))}")
print("\n[4/15] Depts") print("\n[4/15] Depts")
r = requests.get(f"{API}/users/depts", headers=headers) 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', []))}") 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") print("\n[5/15] DataSources")
r = requests.get(f"{API}/datasources", headers=headers) 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))}") check("datasources", r.status_code == 200 and len(get_items(r)) >= 12, f"got {len(get_items(r))}")
print("\n[6/15] Metadata") print("\n[6/15] Metadata")
r = requests.get(f"{API}/metadata/databases", headers=headers) 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))}") 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) 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))}") 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) 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)}") check("columns", r.status_code == 200 and get_total(r) >= 10000, f"total={get_total(r)}")
print("\n[7/15] Classification") print("\n[7/15] Classification")
r = requests.get(f"{API}/classifications/levels", headers=headers) r = requests.get(f"{API}/classifications/levels", headers=headers)
check("levels", r.status_code == 200 and len(r.json().get("data", [])) == 5) check("levels", r.status_code == 200 and len(r.json().get("data", [])) == 5)
r = requests.get(f"{API}/classifications/categories", headers=headers) 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', []))}") 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) 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)}") check("results", r.status_code == 200 and get_total(r) >= 1000, f"total={get_total(r)}")
print("\n[8/15] Projects") print("\n[8/15] Projects")
r = requests.get(f"{API}/projects", headers=headers) 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))}") check("projects", r.status_code == 200 and len(get_items(r)) >= 8, f"got {len(get_items(r))}")
print("\n[9/15] Tasks") print("\n[9/15] Tasks")
r = requests.get(f"{API}/tasks/my-tasks", headers=headers) 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))}") check("tasks", r.status_code == 200 and len(get_items(r)) >= 20, f"got {len(get_items(r))}")
print("\n[10/15] Dashboard") print("\n[10/15] Dashboard")
r = requests.get(f"{API}/dashboard/stats", headers=headers) r = requests.get(f"{API}/dashboard/stats", headers=headers)
check("stats", r.status_code == 200) check("stats", r.status_code == 200)
stats = r.json().get("data", {}) stats = r.json().get("data", {})
check("stats.data_sources", stats.get("data_sources", 0) >= 12, f"got {stats.get('data_sources')}") 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.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.columns", stats.get("columns", 0) >= 10000, f"got {stats.get('columns')}")
check("stats.labeled", stats.get("labeled", 0) >= 10000, f"got {stats.get('labeled')}") check("stats.labeled", stats.get("labeled", 0) >= 10000, f"got {stats.get('labeled')}")
r = requests.get(f"{API}/dashboard/distribution", headers=headers) r = requests.get(f"{API}/dashboard/distribution", headers=headers)
check("distribution", r.status_code == 200 and "level_distribution" in r.json().get("data", {})) check("distribution", r.status_code == 200 and "level_distribution" in r.json().get("data", {}))
print("\n[11/15] Reports") print("\n[11/15] Reports")
r = requests.get(f"{API}/reports/stats", headers=headers) r = requests.get(f"{API}/reports/stats", headers=headers)
check("report stats", r.status_code == 200) check("report stats", r.status_code == 200)
print("\n[12/15] Masking") print("\n[12/15] Masking")
r = requests.get(f"{API}/masking/rules", headers=headers) r = requests.get(f"{API}/masking/rules", headers=headers)
check("masking rules", r.status_code == 200) check("masking rules", r.status_code == 200)
print("\n[13/15] Watermark") print("\n[13/15] Watermark")
r = requests.post(f"{API}/watermark/trace", headers={**headers, "Content-Type": "application/json"}, json={"content": "test 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) check("watermark trace", r.status_code == 200)
print("\n[14/15] Risk") print("\n[14/15] Risk")
r = requests.get(f"{API}/risk/top", headers=headers) r = requests.get(f"{API}/risk/top", headers=headers)
check("risk top", r.status_code == 200) check("risk top", r.status_code == 200)
print("\n[15/15] Compliance") print("\n[15/15] Compliance")
r = requests.get(f"{API}/compliance/issues", headers=headers) r = requests.get(f"{API}/compliance/issues", headers=headers)
check("compliance issues", r.status_code == 200) check("compliance issues", r.status_code == 200)
# Additional modules print("\n[Bonus] Additional modules")
print("\n[Bonus] Additional modules") r = requests.get(f"{API}/lineage/graph", headers=headers)
r = requests.get(f"{API}/lineage/graph", headers=headers) check("lineage graph", r.status_code == 200 and "nodes" in r.json().get("data", {}))
check("lineage graph", r.status_code == 200 and "nodes" in r.json().get("data", {})) r = requests.get(f"{API}/alerts/records", headers=headers)
r = requests.get(f"{API}/alerts/records", headers=headers) check("alert records", r.status_code == 200)
check("alert records", r.status_code == 200) r = requests.get(f"{API}/schema-changes/logs", headers=headers)
r = requests.get(f"{API}/schema-changes/logs", headers=headers) check("schema changes logs", r.status_code == 200)
check("schema changes logs", r.status_code == 200) r = requests.get(f"{API}/unstructured/files", headers=headers)
r = requests.get(f"{API}/unstructured/files", headers=headers) check("unstructured files", r.status_code == 200)
check("unstructured files", r.status_code == 200) r = requests.get(f"{API}/api-assets", headers=headers)
r = requests.get(f"{API}/api-assets", headers=headers) check("api assets", r.status_code == 200)
check("api assets", r.status_code == 200)
print("\n" + "="*60) print("\n" + "="*60)
print(f"Results: {len(passed)} passed, {len(errors)} failed") print(f"Results: {len(passed)} passed, {len(errors)} failed")
print("="*60) print("="*60)
if errors: if errors:
for n, d in errors: print(f"{n}: {d}") for n, d in errors: print(f"{n}: {d}")
sys.exit(1) sys.exit(1)
else: else:
print("🎉 All integration tests passed!") print("🎉 All integration tests passed!")
sys.exit(0) sys.exit(0)
if __name__ == "__main__":
main()
+1 -1
View File
@@ -47,7 +47,7 @@ def test_health_check():
def test_login(): 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 assert response.status_code == 200
data = response.json() data = response.json()
assert data["code"] == 200 assert data["code"] == 200
+1 -1
View File
@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>DataPointer - 数据分类分级管理平台</title> <title>DataPointer - 数据分类分级管理平台</title>
<script type="module" crossorigin src="/assets/index-54C8aHj2.js"></script> <script type="module" crossorigin src="/assets/index-B2ZsjZSQ.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CdImMPt_.css"> <link rel="stylesheet" crossorigin href="/assets/index-CdImMPt_.css">
</head> </head>
<body> <body>
+2 -2
View File
@@ -45,7 +45,7 @@
</el-form> </el-form>
<div class="login-footer"> <div class="login-footer">
<p>默认管理员admin / admin123</p> <!-- 生产环境不显示默认账户 -->
</div> </div>
</div> </div>
</div> </div>
@@ -65,7 +65,7 @@ const formRef = ref()
const form = reactive({ const form = reactive({
username: 'admin', username: 'admin',
password: 'admin123', password: '',
}) })
const rules = { const rules = {