Files
ProjectAGiPrompt/8-CMII-RMDC/9-rmdc-user-auth/2-user-auth-DDS.md
2026-02-02 15:06:28 +08:00

38 KiB
Raw Blame History

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 模块依赖关系

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-dacJenkins 资源)、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_handleruser_handlerpermission_handler 注册 HTTP 路由。
  • Service 层:AuthServiceRSAServiceUserServiceJenkinsPermissionServiceSystemConfigService、注册/管理工单服务。
  • DAO 层:UserDaoRSAKeypairDaoJenkinsPermissionDaoBasePermissionDaoSystemConfigDaoJenkinsDao
  • 公共接口: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默认有效期 4hClaims 包含用户基础信息与 status
  5. 返回 Token 与用户信息,并返回以下标识:
    • must_change_password: 首次登录或密码重置后需强制修改密码
    • password_expire_days: 密码剩余有效天数7 天内提示)
    • account_expire_days: 账户剩余有效天数7 天内提示)

3.2 密钥与密码策略

  • RSA 密钥:rsa_keypairs 表存储 PEM对外只暴露公钥过期自动生成新对异步清理过期数据。
  • 密码哈希bcrypt 默认成本;密码有效期 3 个月(注册/重置/直改都会刷新过期时间)。
  • 账户状态active/locked/disabledJWT 校验时必须 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 有效期检查逻辑

  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 密码过期时间线

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 工单流程概述

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 注册接口设计要点

  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)内部自动创建。

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/usersPUT /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) 加密;禁止明文密码传输。
  • 存储安全:密码使用 bcryptRSA 私钥仅存 DB不下发前端敏感字段不外露。
  • 账户状态:仅 active 用户可通过 JWT 校验locked/disabled 一律拒绝。
  • 密码策略
    • 默认 3 个月过期;修改/创建均刷新过期时间
    • 注册返回 disabled需审批激活
    • 首次登录或密码重置后强制修改密码
  • 账户有效期:非 SuperAdmin 创建的用户必须设置有效期,过期后无法登录
  • TokenHS2564h 过期;无刷新,需重登;超时后自动失效。
  • 权限检查SuperAdmin 全通Admin 只能管理/授权 normal/third权限分配需校验授予者是否具备权限。
  • "谁注册谁管理":非 SuperAdmin 只能管理自己注册的用户
  • TODO登录失败次数与锁定策略尚未实现Watchdog 权限检查待补全。

13. 相关文档

文档 说明
用户认证PRD 产品需求文档
用户权限设计 用户注册管理权限设计
项目管理DDS 参考文档结构(项目工单流程)
工单模块DDS 工单流程设计