38 KiB
38 KiB
RMDC 用户认证模块详细设计说明书 (DDS)
产品名称: RMDC 用户认证模块 (rmdc-user-auth)
版本: v2.0
编制日期: 2026-01-27
1. 概述
1.1 模块定位
rmdc-user-auth 提供 RMDC 统一的用户认证、账户生命周期管理与权限服务,支持 RSA 加密登录、JWT 鉴权、密码过期策略,以及通过工单驱动的用户注册/管理审批流程。
1.2 核心职责
- 身份认证:RSA-OAEP 密码加密 + bcrypt 校验,颁发 4h 有效的 JWT。
- 账号管理:用户 CRUD、密码修改、个人资料更新,支持密码过期、首次登录强制改密与状态控制(active/locked/disabled)。
- 审批工作流集成:用户注册/管理通过
rmdc-work-procedure工单审批,遵循"谁注册谁管理"。 - 权限服务:
- Jenkins 分支层级权限(Org/Repo/Branch)权限,对外暴露权限检查接口。
- Project 项目权限(数据权限)权限
- DeliveryUpdate 微服务更新权限
- 系统配置:RSA 密钥对、登录策略、注册开关等配置的存取与缓存。
1.3 版本修订历史
| 版本 | 日期 | 修订内容 |
|---|---|---|
| v1.0 | 2026-01-23 | 基于现有代码首次形成 DDS,覆盖认证、工单、权限与数据模型 |
| v2.0 | 2026-01-27 | 新增用户有效期字段、强制改密机制、用户注册/管理工单流程详细设计、模块依赖关系流程图 |
2. 系统架构
2.1 模块依赖关系
graph TB
subgraph 核心层
Core[rmdc-core<br/>API Gateway]
end
subgraph 用户与权限
UA[rmdc-user-auth<br/>用户认证/权限]
end
subgraph 业务协作
PM[rmdc-project-management<br/>项目管理]
WP[rmdc-work-procedure<br/>工单流程]
JB[rmdc-jenkins-branch-dac<br/>Jenkins分支权限]
end
subgraph 基础设施
CMN[rmdc-common<br/>公共模块]
Aud[rmdc-audit-log<br/>审计日志]
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 用户模块与工单模块依赖关系详图
graph TB
subgraph rmdc_core["rmdc-core (入口层)"]
INIT[模块初始化]
end
subgraph rmdc_user_auth["rmdc-user-auth (用户认证层)"]
UH[UserHandler<br/>用户接口]
UWH[UserWorkflowHandler<br/>用户工单接口]
US[UserService<br/>用户服务]
URS[UserRegistrationService<br/>注册工单服务]
UMS[UserManagementService<br/>管理工单服务]
end
subgraph rmdc_work_procedure["rmdc-work-procedure (工单层)"]
WH[WorkflowHandler<br/>工单接口]
WS[WorkflowService<br/>工单服务]
WC[WorkflowCallbacks<br/>状态回调]
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 工单模块回调用户模块的接口
// 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 用户模块调用工单模块的接口
// 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)
- 前端调用
GET /api/auth/rsa/public-key获取当前有效公钥(30 天有效,过期自动轮换)。 - 前端用 RSA-OAEP(SHA-256, 2048) 加密密码,提交
POST /api/auth/login,字段encrypted_password。 - 后端
RSAService解密,AuthService用 bcrypt 校验users.password_hash。 - 生成 HS256 JWT,默认有效期 4h,Claims 包含用户基础信息与
status。 - 返回 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 用户生命周期状态机
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 有效期字段设计
// 用户表新增字段
AccountExpiresAt *time.Time `json:"account_expires_at"` // 账户有效期
4.3.3 有效期检查逻辑
- 登录时检查:若
account_expires_at不为空且已过期,拒绝登录并返回账户已过期提示 - 接口检查:JWT 中间件校验用户状态时,同时检查账户有效期
- 提前提醒:账户有效期剩余 7 天内,登录时返回提醒信息
4.4 强制修改密码机制
4.4.1 触发条件
| 条件 | 字段标识 | 处理方式 |
|---|---|---|
| 首次登录 | must_change_password = true |
登录成功后跳转改密页面 |
| 密码重置后 | must_change_password = true |
使用临时密码登录后强制改密 |
| 密码过期 | password_expires_at 已过期 |
拒绝登录,提示密码已过期 |
4.4.2 密码过期时间线
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 "谁注册谁管理"原则
- 注册关系记录:用户表中
registered_by_id记录注册人 ID - 权限检查规则:
- SuperAdmin:可管理所有用户
- Admin/Normal:只能管理
registered_by_id == current_user_id的用户
- 审批归属:所有用户注册/管理工单由 SuperAdmin 审批
6. 用户注册工单流程
6.1 工单流程概述
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: 创建用户记录<br/>(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 注册工单业务载荷
// 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 注册接口设计要点
- 不暴露密码设置:注册接口不接收密码参数,后端自动生成默认密码(如
Rmdc@2026) - 必须设置有效期:非 SuperAdmin 创建用户时,必须选择有效期(1个月/3个月/6个月/1年)
- 自动创建工单:用户创建接口内部调用工单模块创建审批工单
- 工单初始状态:直接进入
pending_review,由 SuperAdmin 审批
7. 用户管理工单流程
7.1 管理操作类型
| 操作类型代码 | 操作名称 | 说明 | 需要审批 |
|---|---|---|---|
update |
修改用户信息 | 修改基本信息(姓名、邮箱等) | 是 |
enable |
启用用户 | 将 disabled 用户改为 active | 是 |
disable |
禁用用户 | 将 active 用户改为 disabled | 是 |
delete |
删除用户 | 软删除用户 | 是 |
reset_password |
重置密码 | 重置为默认密码 | 是 |
extend_validity |
延长有效期 | 延长账户有效期 | 是 |
7.2 工单流程
重要:前端不允许直接调用创建工单接口,工单由用户管理接口(如
PUT /api/users/:id)内部自动创建。
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 管理工单业务载荷
// 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 管理操作执行器
// 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)
// 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 权限检查通用规则
// 权限检查通用规则:
// 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 权限检查逻辑
// CheckHierarchicalPermission 检查层级权限
// 1. 先检查 Branch 级权限
// 2. 若无则检查 Repo 级权限
// 3. 若无则检查 Org 级权限
// 4. 支持 can_build 需求判断(build 需要 view + build 两个权限)
8.3 BusinessInfoRegistry 注册中心
权限模块需要查询业务模块信息(如项目填写人),但不应直接依赖具体业务模块。采用统一注册机制解决模块依赖。
graph TB
subgraph rmdc_core["rmdc-core (入口层)"]
INIT[模块初始化]
end
subgraph rmdc_user_auth["rmdc-user-auth (权限层)"]
REG[BusinessInfoRegistry<br/>业务信息注册中心]
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 注册接口定义
// 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 权限检查规则
// 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)
// 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 层级权限。
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 登录流程
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: 附加标识:<br/>must_change_password<br/>password_expire_days<br/>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 用户注册工单
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 用户管理工单
重要:前端不允许直接调用创建工单接口,工单由用户管理接口内部自动创建。
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 | 产品需求文档 |
| 用户权限设计 | 用户注册管理权限设计 |
| 项目管理DDS | 参考文档结构(项目工单流程) |
| 工单模块DDS | 工单流程设计 |