登录接口配套:加人工具 + 给组员的转交文档(docs/29)
- tools/create_test_user.py:一条命令建"可登录的测试账号"(用户 + 角色 + bcrypt 密码), 并用 IdentityService.resolve 打印**真实解析结果**。sys_user / sys_user_role 没有 ORM 模型、全靠裸 SQL,手写容易漏必填字段;更要紧的是 assigned_at 那个静默陷阱(见下)。 重复执行同一 --id 是覆盖语义,改角色也用它。 - tools/set_user_password.py:hash_password 改从 auth_service 取,消除第二份实现。 - app/service/auth_service.py:新增 hash_password,与 verify_password 放在一起, 让"写密码"和"校验密码"永远同一套算法。 - docs/29-Agent组员登录接口使用说明.md:给组员的转交文档(接口契约、加人步骤、 前端接入示例、常见问题、当前边界)。 文档里专门写清三条最容易踩的: 1. 登录用 username 而不是用户 id —— 演示账号是 cust_t / risk_t / admin_t, 不是 9001/9002/9003。这条不写明,联调时一定有人按 id 试。 2. sys_user_role.assigned_at 的 DATETIME(0) 毫秒舍入陷阱:落在未来会让账号 "登录成功但 roles=()",**不报错**。create_test_user 统一往前留 5 秒。 3. roles / data_scope 只用于前端分流界面,不是权限凭证 —— 鉴权每次请求查库解析, 所以权限变更立即生效,前端也不该拿它们做安全判断。 另:create_test_user 的 ON DUPLICATE KEY UPDATE 用 MySQL 8.0.19+ 的 `AS new` 别名语法, 避开已弃用的 VALUES()(实测本机 8.0.27 会打弃用警告)。 验证:文档守卫 38 份无编号冲突 / ruff 干净 / mypy 183 文件 0 错 / 登录集成测试 10 passed。
This commit is contained in:
@@ -29,10 +29,10 @@ import asyncio
|
||||
import sys
|
||||
from datetime import UTC, datetime
|
||||
|
||||
import bcrypt
|
||||
from sqlalchemy import text
|
||||
|
||||
from app.infrastructure.db import SessionFactory
|
||||
from app.service.auth_service import hash_password
|
||||
|
||||
if hasattr(sys.stdout, "reconfigure"):
|
||||
sys.stdout.reconfigure(errors="replace") # type: ignore[union-attr]
|
||||
@@ -49,10 +49,6 @@ DEMO_PASSWORDS: dict[str, str] = {
|
||||
BCRYPT_PREFIXES = ("$2a$", "$2b$", "$2y$")
|
||||
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
return bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")
|
||||
|
||||
|
||||
def _is_real_hash(value: str | None) -> bool:
|
||||
return bool(value) and str(value).startswith(BCRYPT_PREFIXES)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user