# 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) | 工单流程设计 |