diff --git a/backend/app/services/auth_service.py b/backend/app/services/auth_service.py index 1e8efba..c9995c3 100644 --- a/backend/app/services/auth_service.py +++ b/backend/app/services/auth_service.py @@ -15,6 +15,7 @@ from app.core.security import ( ) from app.core.mom_database import MomSessionLocal from app.core.logging import user_var +from app.core.roles import SUPER_ADMIN from app.schemas.user import LoginResponse, UserResponse security = HTTPBearer() @@ -24,9 +25,14 @@ def login(username: str, password: str) -> LoginResponse: """登录 — 签发双 Token(Access + Refresh)""" db = MomSessionLocal() try: - # 1. 普通用户:LIKE '%/username' 模糊匹配 MOM sys_user 表 - # 并且只允许本部门(settings.ORG_DEPARTMENT)的人登录 —— IRIS 与 LICA - # 共用同一个 MOM 库,这里不加部门条件的话,另一个部门的人也能登进来。 + # 1. LIKE '%/username' 定位 MOM sys_user 账号,再按部门收敛 —— + # IRIS 与 LICA 共用同一个 MOM 库,不加部门条件的话,另一个部门的 + # 普通账号也能登进来。 + # + # ⚠️ 唯一的例外是 SUPER_ADMIN:超管**跨部门放行**,供运维/管理员在 + # 两个实例之间切换。其余角色(INBOUND / SUPERVISOR / WAREHOUSE_MGR / + # SALES)必须严格属于本部门(settings.ORG_DEPARTMENT)。 + # # 不匹配时统一报「用户名或密码错误」,不区分「账号不存在」与「存在但 # 不属于本部门」,避免给账号探测者提供线索。 from sqlalchemy import text @@ -35,9 +41,13 @@ def login(username: str, password: str) -> LoginResponse: "SELECT id, username, department, role, password_hash " "FROM sys_user " "WHERE username LIKE :pattern " - " AND department = :dept" + " AND (department = :dept OR role = :super_admin)" ), - {"pattern": f"%/{username}", "dept": settings.ORG_DEPARTMENT}, + { + "pattern": f"%/{username}", + "dept": settings.ORG_DEPARTMENT, + "super_admin": SUPER_ADMIN, + }, ) row = result.fetchone()