# RMDC 用户认证模块详细设计说明书 (DDS) **产品名称**: RMDC 用户认证模块 (rmdc-user-auth) **版本**: v2.0 **编制日期**: 2026-01-27 --- ## 1. 概述 ### 1.1 模块定位 `rmdc-user-auth` 提供 RMDC 统一的用户认证、账户生命周期管理与权限服务,支持 RSA 加密登录、JWT 鉴权、密码过期策略,以及通过工单驱动的用户注册/管理审批流程。 ### 1.2 核心职责 1. **身份认证**:RSA-OAEP 密码加密 + bcrypt 校验,颁发 4h 有效的 JWT。 2. **账号管理**:用户 CRUD、密码修改、个人资料更新,支持密码过期、首次登录强制改密与状态控制(active/locked/disabled)。 3. **审批工作流集成**:用户注册/管理通过 `rmdc-work-procedure` 工单审批,遵循"谁注册谁管理"。 4. **权限服务**: 1. Jenkins 分支层级权限(Org/Repo/Branch)权限,对外暴露权限检查接口。 2. Project 项目权限(数据权限)权限 3. DeliveryUpdate 微服务更新权限 5. **系统配置**:RSA 密钥对、登录策略、注册开关等配置的存取与缓存。 ### 1.3 版本修订历史 | 版本 | 日期 | 修订内容 | |:---|:---|:---| | v1.0 | 2026-01-23 | 基于现有代码首次形成 DDS,覆盖认证、工单、权限与数据模型 | | v2.0 | 2026-01-27 | 新增用户有效期字段、强制改密机制、用户注册/管理工单流程详细设计、模块依赖关系流程图 | --- ## 2. 系统架构 ### 2.1 模块依赖关系 ```mermaid graph TB subgraph 核心层 Core[rmdc-core
API Gateway] end subgraph 用户与权限 UA[rmdc-user-auth
用户认证/权限] end subgraph 业务协作 PM[rmdc-project-management
项目管理] WP[rmdc-work-procedure
工单流程] JB[rmdc-jenkins-branch-dac
Jenkins分支权限] end subgraph 基础设施 CMN[rmdc-common
公共模块] Aud[rmdc-audit-log
审计日志] end Core --> UA Core --> PM Core --> WP UA -->|用户注册/管理工单| WP UA -->|Jenkins资源查询| JB UA --> CMN UA --> Aud PM -->|用户鉴权/查询| UA PM -->|项目权限管理| UA PM -->|项目工单| WP WP -->|用户状态回调| UA WP -->|项目状态回调| PM ``` ### 2.2 用户模块与工单模块依赖关系详图 ```mermaid graph TB subgraph rmdc_core["rmdc-core (入口层)"] INIT[模块初始化] end subgraph rmdc_user_auth["rmdc-user-auth (用户认证层)"] UH[UserHandler
用户接口] UWH[UserWorkflowHandler
用户工单接口] US[UserService
用户服务] URS[UserRegistrationService
注册工单服务] UMS[UserManagementService
管理工单服务] end subgraph rmdc_work_procedure["rmdc-work-procedure (工单层)"] WH[WorkflowHandler
工单接口] WS[WorkflowService
工单服务] WC[WorkflowCallbacks
状态回调] end INIT -->|注入用户状态回调| WS INIT -->|注入工单创建器| US UH --> US UWH --> URS UWH --> UMS URS -->|创建注册工单| WS UMS -->|创建管理工单| WS WC -->|审批通过: 激活用户| US WC -->|审批打回: 通知修改| URS WC -->|撤销: 删除待审批用户| US WC -->|管理审批通过: 执行变更| UMS ``` ### 2.3 接口注入机制 采用 **接口注入(依赖注入)** 方式实现模块间回调,与项目管理模块保持一致的架构模式。 #### 2.3.1 工单模块回调用户模块的接口 ```go // UserStatusUpdater 用户状态更新接口 // 由 rmdc-core 在初始化时注入,工单模块状态变更时调用 type UserStatusUpdater interface { // UpdateUserStatus 更新用户状态(审批通过时激活) UpdateUserStatus(userID int64, status string) error // ActivateUser 激活用户(注册审批通过) ActivateUser(userID int64) error // DeletePendingUser 删除待审批用户(工单撤销时) DeletePendingUser(userID int64) error // ExecuteUserManagement 执行用户管理操作(管理审批通过) ExecuteUserManagement(userID int64, action string, payload map[string]interface{}) error } ``` #### 2.3.2 用户模块调用工单模块的接口 ```go // WorkflowCreator 工单创建接口 // 由 rmdc-core 在初始化时注入,用户模块通过此接口创建工单 type WorkflowCreator interface { // CreateRegistrationWorkflow 创建用户注册工单 CreateRegistrationWorkflow(ctx context.Context, req *RegistrationWorkflowRequest) (string, error) // CreateManagementWorkflow 创建用户管理工单 CreateManagementWorkflow(ctx context.Context, req *ManagementWorkflowRequest) (string, error) } ``` ### 2.4 技术栈 - Gin (HTTP 路由) - GORM (ORM,依赖 `models.DatabaseConnections` 提供多库连接:User/Jenkins/Core/Workflow) - JWT (HS256) - RSA-OAEP (2048) 前端密码加密,密钥 30 天轮换 - bcrypt (密码存储) - 内部模块依赖:`rmdc-work-procedure`(工单)、`rmdc-jenkins-branch-dac`(Jenkins 资源)、`rmdc-common`(日志、返回码、模型) ### 2.5 路由与中间件分层 - `/api/auth/*`:免 token,含获取 RSA 公钥、登录、注册。 - `/api/users`、`/api/user`、`/api/permissions`:需 `AuthMiddleware(jwtSecret)` 校验 JWT,部分再叠加 `RequireAdmin()`。 - 中间件: - `AuthMiddleware`:解析 Bearer JWT,校验签名和用户状态为 `active`,注入用户上下文。 - `RequireAdmin`:判定角色包含 `admin` 字样(superadmin/admin)。 ### 2.6 组件关系 - Handler 层:`auth_handler`、`user_handler`、`permission_handler` 注册 HTTP 路由。 - Service 层:`AuthService`、`RSAService`、`UserService`、`JenkinsPermissionService`、`SystemConfigService`、注册/管理工单服务。 - DAO 层:`UserDao`、`RSAKeypairDao`、`JenkinsPermissionDao`、`BasePermissionDao`、`SystemConfigDao`、`JenkinsDao`。 - 公共接口:`pkg/permission.PermissionChecker` 对外暴露权限检查,供其他模块调用。 --- ## 3. 认证与登录设计 ### 3.1 登录流程(RSA + JWT) 1. 前端调用 `GET /api/auth/rsa/public-key` 获取当前有效公钥(30 天有效,过期自动轮换)。 2. 前端用 RSA-OAEP(SHA-256, 2048) 加密密码,提交 `POST /api/auth/login`,字段 `encrypted_password`。 3. 后端 `RSAService` 解密,`AuthService` 用 bcrypt 校验 `users.password_hash`。 4. 生成 HS256 JWT,默认有效期 4h,Claims 包含用户基础信息与 `status`。 5. 返回 Token 与用户信息,并返回以下标识: - `must_change_password`: 首次登录或密码重置后需强制修改密码 - `password_expire_days`: 密码剩余有效天数(7 天内提示) - `account_expire_days`: 账户剩余有效天数(7 天内提示) ### 3.2 密钥与密码策略 - RSA 密钥:`rsa_keypairs` 表存储 PEM,对外只暴露公钥;过期自动生成新对,异步清理过期数据。 - 密码哈希:bcrypt 默认成本;密码有效期 3 个月(注册/重置/直改都会刷新过期时间)。 - 账户状态:active/locked/disabled;JWT 校验时必须 active。 - 首次登录强制改密:新注册用户或重置密码后,`must_change_password` 标识为 true。 - 登录失败计数:字段存在,逻辑留有 TODO(未实现锁定策略)。 ### 3.3 JWT 中间件行为 - 解析 Authorization: Bearer ,校验签名与过期。 - 校验 `claims.Status == "active"`,否则 401。 - 注入上下文键:`user_id/username/english_name/phone/group_name/role/dev_role/status`。 ### 3.4 缺省/限制 - 无刷新接口;Token 过期需重新登录。 - 无服务器端注销接口(前端丢弃 Token)。 --- ## 4. 用户生命周期管理 ### 4.1 用户状态定义 | 状态 | 说明 | 触发条件 | |:---|:---|:---| | `disabled` | 待审批状态 | 用户注册后默认状态 | | `active` | 正常激活 | 注册工单审批通过 | | `locked` | 临时锁定 | 登录失败次数过多 / 管理员手动锁定 | ### 4.2 用户生命周期状态机 ```mermaid stateDiagram-v2 [*] --> disabled: 用户注册 disabled --> disabled: 保存草稿 disabled --> disabled: 工单打回,等待修改 disabled --> active: 注册工单审批通过 disabled --> [*]: 工单撤销,删除用户 active --> active: 正常使用 active --> active: 信息更新 active --> locked: 登录失败锁定 active --> disabled: 管理员禁用 active --> [*]: 管理员删除 locked --> active: 解锁 locked --> disabled: 管理员禁用 note right of disabled: 用户刚注册,等待审批 note right of active: 正常使用状态 note right of locked: 临时锁定,可解锁 ``` ### 4.3 用户有效期机制 #### 4.3.1 有效期设置规则 | 用户类型 | 有效期选项 | 默认值 | 说明 | |:---|:---|:---|:---| | SuperAdmin 创建的用户 | 无限制 / 自定义 | 永久 | SuperAdmin 可设置任意有效期 | | Admin 创建的用户 | 1个月/3个月/6个月/1年 | 3个月 | 必须设置有效期 | | Normal 创建的用户 | 1个月/3个月/6个月/1年 | 3个月 | 必须设置有效期 | #### 4.3.2 有效期字段设计 ```go // 用户表新增字段 AccountExpiresAt *time.Time `json:"account_expires_at"` // 账户有效期 ``` #### 4.3.3 有效期检查逻辑 1. **登录时检查**:若 `account_expires_at` 不为空且已过期,拒绝登录并返回账户已过期提示 2. **接口检查**:JWT 中间件校验用户状态时,同时检查账户有效期 3. **提前提醒**:账户有效期剩余 7 天内,登录时返回提醒信息 ### 4.4 强制修改密码机制 #### 4.4.1 触发条件 | 条件 | 字段标识 | 处理方式 | |:---|:---|:---| | 首次登录 | `must_change_password = true` | 登录成功后跳转改密页面 | | 密码重置后 | `must_change_password = true` | 使用临时密码登录后强制改密 | | 密码过期 | `password_expires_at` 已过期 | 拒绝登录,提示密码已过期 | #### 4.4.2 密码过期时间线 ```mermaid flowchart TB A["创建用户 / 重置密码"] B["password_expires_at = now + 90天\nmust_change_password = true"] C["首次登录"] D["强制修改密码"] E["修改密码后:\npassword_expires_at = now + 90天\nmust_change_password = false"] F["正常使用"] G["第83天:提醒"] H["第90天:强制过期"] A --> B --> C --> D --> E --> F --> G --> H ``` --- ## 5. 用户注册与管理权限 ### 5.1 角色与注册/管理权限矩阵 | 操作者角色 | 可注册角色 | 可管理范围 | 说明 | |:---|:---|:---|:---| | SuperAdmin | superadmin/admin/normal/third | 所有用户 | 完全权限 | | Admin | normal/third | 自己注册的用户 | 遵循"谁注册谁管理" | | Normal | third | 自己注册的用户 | 仅可注册三方用户 | | Third | - | - | 无注册和管理权限 | ### 5.2 管理操作权限矩阵 | 操作 | SuperAdmin | Admin | Normal | Third | |:---|:---|:---|:---|:---| | 修改用户信息 | ✅ 所有用户 | ✅ 自己注册的 | ✅ 自己注册的 | ❌ | | 启用用户 | ✅ 所有用户 | ✅ 自己注册的 | ✅ 自己注册的 | ❌ | | 禁用用户 | ✅ 所有用户 | ✅ 自己注册的 | ✅ 自己注册的 | ❌ | | 删除用户 | ✅ 所有用户 | ✅ 自己注册的 | ✅ 自己注册的 | ❌ | | 重置密码 | ✅ 所有用户 | ✅ 自己注册的 | ❌ | ❌ | | 延长有效期 | ✅ 所有用户 | ❌ | ❌ | ❌ | ### 5.3 "谁注册谁管理"原则 1. **注册关系记录**:用户表中 `registered_by_id` 记录注册人 ID 2. **权限检查规则**: - SuperAdmin:可管理所有用户 - Admin/Normal:只能管理 `registered_by_id == current_user_id` 的用户 3. **审批归属**:所有用户注册/管理工单由 SuperAdmin 审批 --- ## 6. 用户注册工单流程 ### 6.1 工单流程概述 ```mermaid sequenceDiagram participant User as 注册发起人 participant UA as rmdc-user-auth participant WP as rmdc-work-procedure participant SA as SuperAdmin User->>UA: POST /api/users (创建用户) UA->>UA: 创建用户记录
(status=disabled, 默认密码) UA->>WP: CreateWorkflow(user_registration) WP-->>UA: workflow_id UA-->>User: 返回成功,工单ID WP->>SA: 通知:新用户注册待审批 alt 审批通过 SA->>WP: POST /api/workflow/approve WP->>UA: ActivateUser(user_id) UA->>UA: status = active UA-->>WP: success WP->>User: 通知:用户注册已通过 else 审批打回 SA->>WP: POST /api/workflow/return WP->>User: 通知:请修改用户信息 User->>UA: PUT /api/users/:id (修改信息) User->>WP: POST /api/workflow/resubmit else 撤销 User->>WP: POST /api/workflow/revoke WP->>UA: DeletePendingUser(user_id) UA->>UA: DELETE users WHERE status=disabled end ``` ### 6.2 工单状态与用户状态映射 | 工单事件 | 工单状态 | 用户状态 | 说明 | |:---|:---|:---|:---| | create | pending_review | disabled | 创建用户并提交审核 | | approve | approved | active | 审核通过,激活用户 | | return | returned | disabled (保持) | 打回修改,用户状态不变 | | resubmit | pending_review | disabled (保持) | 重新提交审核 | | revoke | revoked | (删除) | 撤销工单,删除待审批用户 | ### 6.3 注册工单业务载荷 ```go // RegistrationWorkflowPayload 注册工单业务载荷 type RegistrationWorkflowPayload struct { TargetUserID int64 `json:"target_user_id"` // 被注册用户ID TargetUsername string `json:"target_username"` // 被注册用户名 TargetRole string `json:"target_role"` // 被注册用户角色 RegisteredByID int64 `json:"registered_by_id"` // 注册人ID RegisteredByName string `json:"registered_by_name"` // 注册人姓名 AccountExpiresAt time.Time `json:"account_expires_at"` // 账户有效期 RegistrationReason string `json:"registration_reason"` // 注册原因 } ``` ### 6.4 注册接口设计要点 1. **不暴露密码设置**:注册接口不接收密码参数,后端自动生成默认密码(如 `Rmdc@2026`) 2. **必须设置有效期**:非 SuperAdmin 创建用户时,必须选择有效期(1个月/3个月/6个月/1年) 3. **自动创建工单**:用户创建接口内部调用工单模块创建审批工单 4. **工单初始状态**:直接进入 `pending_review`,由 SuperAdmin 审批 --- ## 7. 用户管理工单流程 ### 7.1 管理操作类型 | 操作类型代码 | 操作名称 | 说明 | 需要审批 | |:---|:---|:---|:---| | `update` | 修改用户信息 | 修改基本信息(姓名、邮箱等) | 是 | | `enable` | 启用用户 | 将 disabled 用户改为 active | 是 | | `disable` | 禁用用户 | 将 active 用户改为 disabled | 是 | | `delete` | 删除用户 | 软删除用户 | 是 | | `reset_password` | 重置密码 | 重置为默认密码 | 是 | | `extend_validity` | 延长有效期 | 延长账户有效期 | 是 | ### 7.2 工单流程 > **重要**:前端不允许直接调用创建工单接口,工单由用户管理接口(如 `PUT /api/users/:id`)内部自动创建。 ```mermaid sequenceDiagram participant Operator as 操作人 participant UA as rmdc-user-auth participant WP as rmdc-work-procedure participant SA as SuperAdmin Operator->>UA: PUT /api/users/:id (修改用户信息) Note right of Operator: 或 POST /api/users/:id/enable|disable|delete UA->>UA: CheckManagementPermission UA->>UA: 记录原始数据快照 UA->>WP: CreateWorkflow(user_management) WP-->>UA: workflow_id UA-->>Operator: 返回成功,工单ID WP->>SA: 通知:用户管理待审批 alt 审批通过 SA->>WP: POST /api/workflow/approve WP->>UA: ExecuteUserManagement(action, payload) UA->>UA: 执行对应操作(update/enable/disable/delete) UA-->>WP: success WP->>Operator: 通知:管理操作已通过 else 审批打回 SA->>WP: POST /api/workflow/return WP->>Operator: 通知:请重新提交 end ``` ### 7.3 管理工单业务载荷 ```go // ManagementWorkflowPayload 管理工单业务载荷 type ManagementWorkflowPayload struct { TargetUserID int64 `json:"target_user_id"` // 目标用户ID TargetUsername string `json:"target_username"` // 目标用户名 ActionType string `json:"action_type"` // 操作类型 OperatorID int64 `json:"operator_id"` // 操作人ID OperatorName string `json:"operator_name"` // 操作人姓名 OriginalData map[string]interface{} `json:"original_data"` // 原始数据快照 ModifiedData map[string]interface{} `json:"modified_data"` // 修改后数据 Reason string `json:"reason"` // 操作原因 } ``` ### 7.4 管理操作执行器 ```go // UserManagementExecutor 用户管理执行器 type UserManagementExecutor interface { // UpdateUserInfo 更新用户信息 UpdateUserInfo(userID int64, payload map[string]interface{}) error // EnableUser 启用用户 EnableUser(userID int64) error // DisableUser 禁用用户 DisableUser(userID int64) error // DeleteUser 删除用户 DeleteUser(userID int64) error // ResetPassword 重置密码 ResetPassword(userID int64) error // ExtendValidity 延长有效期 ExtendValidity(userID int64, newExpiresAt time.Time) error } ``` --- ## 8. 权限模型 ### 8.1 统一权限架构 RMDC 系统采用**专用权限表**的设计模式,针对不同业务场景使用独立的权限表结构,以满足复杂的权限控制需求。同时定义统一的权限模块枚举,便于扩展和维护。 #### 8.1.1 权限模块枚举 (PermissionModule) ```go // PermissionModule 权限模块枚举 type PermissionModule string const ( // 用户模块权限 ModuleUserRegister PermissionModule = "user_register" // 用户注册 ModuleUserManage PermissionModule = "user_manage" // 用户管理 ModuleUserPermission PermissionModule = "user_permission" // 用户权限管理 // 项目模块权限 ModuleProjectCreate PermissionModule = "project_create" // 项目创建 ModuleProjectView PermissionModule = "project_view" // 项目查看 ModuleProjectEdit PermissionModule = "project_edit" // 项目编辑 ModuleProjectExport PermissionModule = "project_export" // 项目导出 ModuleProjectAuth PermissionModule = "project_auth" // 项目授权管理 // Jenkins 模块权限 ModuleJenkinsView PermissionModule = "jenkins_view" // Jenkins 查看 ModuleJenkinsBuild PermissionModule = "jenkins_build" // Jenkins 构建 ModuleJenkinsManage PermissionModule = "jenkins_manage" // Jenkins 权限管理 // 微服务更新模块权限 ModuleDeliveryView PermissionModule = "delivery_view" // 微服务查看 ModuleDeliveryUpdate PermissionModule = "delivery_update" // 微服务更新 // 工单模块权限 ModuleWorkflowView PermissionModule = "workflow_view" // 工单查看 ModuleWorkflowApprove PermissionModule = "workflow_approve" // 工单审批 ) // PermissionModuleInfo 模块信息 type PermissionModuleInfo struct { Code PermissionModule `json:"code"` // 模块代码 Name string `json:"name"` // 模块名称 Description string `json:"description"` // 模块描述 ACLTable string `json:"acl_table"` // 关联的ACL表 } // 模块注册表 var PermissionModules = map[PermissionModule]PermissionModuleInfo{ ModuleJenkinsView: {Code: ModuleJenkinsView, Name: "Jenkins查看", ACLTable: "jenkins_acls"}, ModuleJenkinsBuild: {Code: ModuleJenkinsBuild, Name: "Jenkins构建", ACLTable: "jenkins_acls"}, ModuleProjectView: {Code: ModuleProjectView, Name: "项目查看", ACLTable: "project_acls"}, ModuleProjectEdit: {Code: ModuleProjectEdit, Name: "项目编辑", ACLTable: "project_acls"}, // ... 其他模块 } ``` #### 8.1.2 权限表概览 | 权限类型 | 权限表 | 权限粒度 | 说明 | |:---|:---|:---|:---| | **Jenkins 权限** | `jenkins_acls` | Org/Repo/Branch 层级 | 支持层级继承的 CI/CD 权限 | | **项目权限** | `project_acls` | 项目模块级 | 项目信息访问权限 | | **用户权限缓存** | `user_permission_caches` | 用户维度 | 用户所有权限的 L2 缓存树 | #### 8.1.3 权限检查通用规则 ```go // 权限检查通用规则: // 1. SuperAdmin 拥有所有权限,直接放行 // 2. 根据 PermissionModule 分流到对应的 ACL 表进行检查 // 3. 权限检查结果存入 L1 内存缓存和 L2 DB 缓存,提升性能 // 4. 权限变更时同时清除 L1 和 L2 缓存 ``` ### 8.2 Jenkins 层级权限 (jenkins_acls) #### 8.2.1 层级结构 ``` Organization (组织) └── Repository (仓库) └── Branch (分支) ``` #### 8.2.2 设计原则 - **层级继承**:上级权限可覆盖下级(如 Org 级权限覆盖其下所有 Repo/Branch) - **存储最小化**:一条记录可覆盖子层级,减少数据冗余 - **权限类型**:`can_view`(查看,对应 `jenkins_view`)、`can_build`(构建,对应 `jenkins_build`) #### 8.2.3 权限表设计 (jenkins_acls) | 字段 | 说明 | |:---|:---| | `user_id` | 用户 ID | | `organization_folder` | 组织文件夹(必填) | | `repository_name` | 仓库名称(可空,空表示 Org 级权限) | | `branch_name` | 分支名称(可空,空表示 Repo 级权限) | | `permission_level` | 权限层级:org/repo/branch | | `can_view` | 是否可查看 | | `can_build` | 是否可构建 | | `granted_by` | 授权人 ID | | `granted_at` | 授权时间 | #### 8.2.4 权限缓存机制 - **L1 内存缓存**:`permissionCache`,进程内高速缓存 - **L2 DB 缓存**:`user_permission_caches` 表,存储用户所有权限的缓存树 JSON - **懒加载接口**:按 organizations → repositories → branches 逐级加载 - **缓存失效**:权限变更时同时清除 L1 和 L2 缓存 #### 8.2.5 权限检查逻辑 ```go // CheckHierarchicalPermission 检查层级权限 // 1. 先检查 Branch 级权限 // 2. 若无则检查 Repo 级权限 // 3. 若无则检查 Org 级权限 // 4. 支持 can_build 需求判断(build 需要 view + build 两个权限) ``` ### 8.3 BusinessInfoRegistry 注册中心 权限模块需要查询业务模块信息(如项目填写人),但不应直接依赖具体业务模块。采用**统一注册机制**解决模块依赖。 ```mermaid graph TB subgraph rmdc_core["rmdc-core (入口层)"] INIT[模块初始化] end subgraph rmdc_user_auth["rmdc-user-auth (权限层)"] REG[BusinessInfoRegistry
业务信息注册中心] PS[ProjectPermissionService] JS[JenkinsPermissionService] end subgraph business["业务模块层"] PM[rmdc-project-management] JB[rmdc-jenkins-branch-dac] end INIT -->|注册业务查询器| REG INIT -->|注入权限检查器| PM INIT -->|注入权限检查器| JB PS --> REG JS --> REG REG -.->|查询业务信息| PM REG -.->|查询Jenkins信息| JB ``` #### 8.3.1 注册接口定义 ```go // BusinessInfoQuerier 业务信息查询接口(通用基类) type BusinessInfoQuerier interface { GetModuleCode() string } // ProjectInfoQuerier 项目信息查询接口 type ProjectInfoQuerier interface { BusinessInfoQuerier GetProjectFillerID(ctx context.Context, projectID string) (int64, error) } // JenkinsInfoQuerier Jenkins 信息查询接口 type JenkinsInfoQuerier interface { BusinessInfoQuerier GetOrganizations(ctx context.Context) ([]string, error) GetRepositories(ctx context.Context, org string) ([]string, error) GetBranches(ctx context.Context, org, repo string) ([]string, error) } // ModulePermissionChecker 权限检查器接口(通用) type ModulePermissionChecker interface { CheckPermission(ctx context.Context, userID int64, userRole string, resourceID, resourceType, permissionType string) (bool, error) GetAccessibleResourceIDs(ctx context.Context, userID int64, userRole string, resourceType string) ([]string, error) } ``` ### 8.4 项目权限(ProjectACL) #### 8.4.1 设计原则 - 权限粒度:**模块级**(basic_info/business_info/environment_info/middleware_info/authorization_info) - SuperAdmin 默认拥有所有权限,无需存储 ACL 记录 - 项目填写人自动获得非授权模块的 view 权限 #### 8.4.2 模块代码与 JSONB 映射 | 模块代码 | JSONB 字段 | 说明 | |:---|:---|:---| | `basic_info` | `projects.basic_info` | 省份、城市、联系人等 | | `business_info` | `projects.deploy_business` | 部署人、版本、入口等 | | `environment_info` | `projects.deploy_env` | 主机、网络、管理方式等 | | `middleware_info` | `projects.deploy_middleware` | MySQL/Redis/EMQX 等 | | `authorization_info` | `project_auth_configs.*` | TOTP 授权(仅 SuperAdmin) | #### 8.4.3 权限检查规则 ```go // CheckProjectModulePermission 规则: // 1. SuperAdmin 拥有所有权限 // 2. authorization_info 模块仅 SuperAdmin 可访问 // 3. 项目填写人自动拥有非授权模块的 view 权限 // 4. 其他用户查询 project_acls 表 ``` --- ## 9. 数据模型 ### 9.1 核心表概览 | 表 | 作用 | 关键字段 | |:---|:---|:---| | `users` | 账户信息 | username, english_username, password_hash, role, status, registered_by_id, password_expires_at, account_expires_at, must_change_password, failed_login_attempts, locked_until | | `rsa_keypairs` | RSA 密钥对 | public_key/ private_key (PEM), expires_at | | `jenkins_acls` | Jenkins 层级权限 | user_id, organization_folder, repository_name?, branch_name?, permission_level, can_view, can_build, granted_by | | `project_acls` | 项目模块级权限 | user_id, project_id, module_code, can_view, can_export, granted_by | | `user_permission_caches` | 用户权限 L2 缓存 | user_id, permission_tree (JSON), updated_at | | `system_configs` | 系统配置 | key, value, description | ### 9.2 用户表 DDL (users) ```go // User 用户表 type User struct { ID int64 `gorm:"primaryKey;autoIncrement" json:"id"` Username string `gorm:"uniqueIndex;not null;size:50" json:"username"` // 中文真实姓名 EnglishUsername string `gorm:"size:100" json:"english_username"` // 英文用户名(昵称) PasswordHash string `gorm:"not null;size:255" json:"-"` // 加密后的密码 AvatarID string `gorm:"size:50;default:'default_1'" json:"avatar_id"` // 头像ID AvatarFrameID string `gorm:"size:50;default:'default'" json:"avatar_frame_id"` // 头像框ID Gender string `gorm:"size:10;default:'male'" json:"gender"` // 性别: male/female Email string `gorm:"uniqueIndex;size:100" json:"email"` // 邮箱 Phone string `gorm:"size:20" json:"phone"` // 手机号 ShortNumber string `gorm:"size:10" json:"short_number"` // 短号 WorkID string `gorm:"size:50" json:"work_id"` // 工号 GroupName string `gorm:"size:100" json:"group_name"` // 所属小组 Company string `gorm:"size:100" json:"company"` // 公司名称 DevRole string `gorm:"size:50;default:'unknown'" json:"dev_role"` // 开发角色 // 注册关系 RegisteredByID int64 `json:"registered_by_id"` // 注册人ID RegisteredByName string `gorm:"size:64" json:"registered_by_name"` // 注册人姓名(冗余) // 角色与状态 Role string `gorm:"not null;size:20;default:'normal'" json:"role"` // 系统角色 Status string `gorm:"not null;size:20;default:'disabled'" json:"status"` // 状态 // 密码策略 PasswordExpiresAt *time.Time `json:"password_expires_at"` // 密码过期时间 MustChangePassword bool `gorm:"default:true" json:"must_change_password"` // 是否需要强制改密 // 账户有效期(新增) AccountExpiresAt *time.Time `json:"account_expires_at"` // 账户有效期 // 登录锁定 FailedLoginAttempts int `gorm:"default:0" json:"failed_login_attempts"` LockedUntil *time.Time `json:"locked_until"` // MFA MFASecret string `gorm:"size:100" json:"-"` // 审计字段 CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` DeletedAt *time.Time `gorm:"index" json:"deleted_at,omitempty"` LastLoginAt *time.Time `json:"last_login_at"` } ``` ### 9.3 用户表新增字段说明 | 字段 | 类型 | 说明 | 默认值 | |:---|:---|:---|:---| | `registered_by_name` | varchar(64) | 注册人姓名(冗余存储,便于展示) | NULL | | `must_change_password` | bool | 是否需要强制修改密码 | true | | `account_expires_at` | datetime | 账户有效期,NULL表示永久有效 | NULL | ### 9.4 RSA 密钥表(rsa_keypairs) - 存储 PEM 文本及过期时间;`RSAService` 负责加载、轮换、缓存与过期清理。 ### 9.5 Jenkins 权限表(jenkins_acls) - 层级列可空实现覆盖:org=不空,repo/branch 为空;repo 级:branch 空;branch 级:三列全填。 - `permission_level` 归档实际层级,便于查询。 - 详见 [8.2 Jenkins 层级权限](#82-jenkins-层级权限-jenkins_acls)。 ### 9.6 项目权限表(project_acls) - 模块级权限控制:user_id + project_id + module_code 组合唯一。 - 权限类型:can_view(查看)、can_export(导出)。 - 索引:`idx_project_acl_user`(用户维度)、`idx_project_acl_project`(项目+模块维度)。 - SuperAdmin 不存储记录,权限检查时直接放行。 --- ## 10. 接口设计 (API) ### 10.1 认证 | 方法 | 路径 | 说明 | 鉴权 | |:---|:---|:---|:---| | GET | `/api/auth/rsa/public-key` | 获取 RSA 公钥 | 公共 | | POST | `/api/auth/login` | RSA 加密密码登录,返回 JWT | 公共 | | POST | `/api/auth/register` | 自助注册(创建 disabled 用户) | 公共 | ### 10.2 用户管理 | 方法 | 路径 | 说明 | 鉴权 | |:---|:---|:---|:---| | GET | `/api/users` | 列表,支持角色/状态/组/搜索/Scope | JWT | | GET | `/api/users/:id` | 用户详情 + 权限 | JWT | | POST | `/api/users` | 创建用户(自动创建注册工单) | JWT + Admin | | PUT | `/api/users/:id` | 更新用户(仅用于保存草稿,正式修改需工单) | JWT + Admin | | DELETE | `/api/users/:id` | 删除用户(仅SuperAdmin可直接删除) | JWT + SuperAdmin | | PUT | `/api/user/profile` | 更新本人资料(头像/密码) | JWT | | PUT | `/api/user/password` | 本人改密(校验旧密码) | JWT | | PUT | `/api/user/password/force-change` | 首次登录强制改密 | JWT | ### 10.3 权限(Jenkins) | 方法 | 路径 | 说明 | 鉴权 | |:---|:---|:---|:---| | GET | `/api/permissions/jenkins/my-tree/organizations` | 我的组织列表 | JWT | | POST | `/api/permissions/jenkins/my-tree/repositories` | 我的仓库(按 org) | JWT | | POST | `/api/permissions/jenkins/my-tree/branches` | 我的分支(按 org/repo) | JWT | | GET | `/api/permissions/jenkins/my-tree/full` | 我的权限树(缓存/重建) | JWT | | GET | `/api/permissions/jenkins/check/:organization/:branch` | 检查分支权限 | JWT | | GET | `/api/permissions/jenkins/tree` | 全量权限树(Admin) | JWT + Admin | | GET | `/api/permissions/jenkins/users/role/:role` | 按角色查用户 | JWT + Admin | | GET | `/api/permissions/jenkins/:userId` | 获取用户 Jenkins 权限 | JWT + Admin | | POST | `/api/permissions/jenkins/assign` | 分配权限(层级覆盖) | JWT + Admin | | POST | `/api/permissions/jenkins/copy` | 拷贝权限 | JWT + Admin | | GET | `/api/permissions/jenkins/user-tree/:userId/organizations` | 懒加载组织 | JWT + Admin | | GET | `/api/permissions/jenkins/user-tree/:userId/organizations/:org/repositories` | 懒加载仓库 | JWT + Admin | | GET | `/api/permissions/jenkins/user-tree/:userId/organizations/:org/repositories/:repo/branches` | 懒加载分支 | JWT + Admin | ### 10.4 项目权限接口 | 方法 | 路径 | 说明 | 鉴权 | |:---|:---|:---|:---| | GET | `/api/permissions/projects/user/:userId/summary` | 获取用户项目权限摘要 | JWT + Admin | | POST | `/api/permissions/projects/grant` | 授予项目模块权限 | JWT + Admin | | POST | `/api/permissions/projects/revoke` | 撤销项目模块权限 | JWT + Admin | > **注意**:前端不允许直接调用创建工单接口,用户注册/管理工单通过用户管理接口(如 `POST /api/users`、`PUT /api/users/:id`)内部自动创建。 ### 10.5 系统配置 | 方法 | 路径 | 说明 | 鉴权 | |:---|:---|:---|:---| | GET | `/api/user/system-config` | 获取配置(为空时返回默认值) | JWT | | PUT | `/api/user/system-config` | 更新配置 | JWT | --- ## 11. 业务流程 ### 11.1 登录流程 ```mermaid sequenceDiagram participant FE as 前端 participant UA as rmdc-user-auth FE->>UA: GET /api/auth/rsa/public-key UA-->>FE: 公钥 FE->>UA: POST /api/auth/login (encrypted_password) UA->>UA: RSA 解密 + bcrypt 校验 UA->>UA: 检查账户状态/有效期/密码过期 UA->>UA: 生成 JWT(4h) UA-->>FE: token + userDTO + 附加标识 Note over FE,UA: 附加标识:
must_change_password
password_expire_days
account_expire_days alt must_change_password = true FE->>FE: 跳转强制改密页面 FE->>UA: PUT /api/user/password/force-change UA->>UA: 更新密码,重置过期时间 UA-->>FE: 改密成功 end ``` ### 11.2 用户注册工单 ```mermaid sequenceDiagram participant User as 已登录用户 participant UA as rmdc-user-auth participant WP as rmdc-work-procedure participant SA as SuperAdmin User->>UA: POST /api/users (创建用户) UA->>UA: 权限检查:可注册该角色? UA->>UA: 创建用户(status=disabled, 默认密码) UA->>UA: 设置 account_expires_at UA->>UA: 设置 must_change_password = true UA->>WP: CreateWorkflow(user_registration, pending_review) WP-->>UA: workflow_id UA-->>User: 返回成功 WP->>SA: 通知待审批 alt 审批通过 SA->>WP: approve WP->>UA: ActivateUser UA->>UA: status = active else 打回 SA->>WP: return WP->>User: 通知修改 User->>UA: PUT /api/users/:id User->>WP: resubmit else 撤销 User->>WP: revoke WP->>UA: DeletePendingUser UA->>UA: DELETE (status=disabled) end ``` ### 11.3 用户管理工单 > **重要**:前端不允许直接调用创建工单接口,工单由用户管理接口内部自动创建。 ```mermaid sequenceDiagram participant Operator as 操作人 participant UA as rmdc-user-auth participant WP as rmdc-work-procedure participant SA as SuperAdmin Operator->>UA: PUT /api/users/:id (修改用户) Note right of Operator: 或 POST /api/users/:id/enable|disable|delete UA->>UA: CheckManagementPermission UA->>UA: 记录原始数据快照 UA->>WP: CreateWorkflow(user_management) WP-->>UA: workflow_id UA-->>Operator: 返回成功 WP->>SA: 通知待审批 alt 审批通过 SA->>WP: approve WP->>UA: ExecuteUserManagement UA->>UA: 执行操作(update/enable/disable/delete) else 打回 SA->>WP: return WP->>Operator: 通知修改后重新提交 end ``` --- ## 12. 安全与合规 - **传输安全**:登录密码必须使用 RSA-OAEP(SHA-256, 2048) 加密;禁止明文密码传输。 - **存储安全**:密码使用 bcrypt;RSA 私钥仅存 DB,不下发前端;敏感字段不外露。 - **账户状态**:仅 active 用户可通过 JWT 校验;locked/disabled 一律拒绝。 - **密码策略**: - 默认 3 个月过期;修改/创建均刷新过期时间 - 注册返回 disabled,需审批激活 - 首次登录或密码重置后强制修改密码 - **账户有效期**:非 SuperAdmin 创建的用户必须设置有效期,过期后无法登录 - **Token**:HS256,4h 过期;无刷新,需重登;超时后自动失效。 - **权限检查**:SuperAdmin 全通;Admin 只能管理/授权 normal/third;权限分配需校验授予者是否具备权限。 - **"谁注册谁管理"**:非 SuperAdmin 只能管理自己注册的用户 - **TODO**:登录失败次数与锁定策略尚未实现;Watchdog 权限检查待补全。 --- ## 13. 相关文档 | 文档 | 说明 | |:---|:---| | [用户认证PRD](1-user-auth-PRD.md) | 产品需求文档 | | [用户权限设计](权限设计部分/3-用户部分-权限设计.md) | 用户注册管理权限设计 | | [项目管理DDS](../4-rmdc-project-management/2-rmdc-project-management-DDS.md) | 参考文档结构(项目工单流程) | | [工单模块DDS](../7-rmdc-work-procedure/1-rmdc-work-procedure-DDS.md) | 工单流程设计 |