feat: 审批/执行角色权限校验 + LDAP用户禁止重置密码
- ticket.go: ApproveTicket 前置角色检查(admin/dba/auditor),ExecuteTicket 前置角色检查(admin/dba) - ticket.go: 创建工单时自动从 instance.workflow_id 读取关联审批流程 - UsersPage.tsx: LDAP 用户重置密码按钮置灰(disabled+opacity-30+提示文案) - 权限模型: 审核=管理员/DBA/审核员, 执行=管理员/DBA, 提交=所有角色
This commit is contained in:
1 parent
b4c982d565
commit
bef2f98f28
2 files changed
+38
-22
No files matched your search
@@ -218,6 +218,14 @@ func CreateTicket(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Auto-fill workflow_id from instance if not provided
|
||||
if input.WorkflowID == nil || *input.WorkflowID == 0 {
|
||||
var inst model.Instance
|
||||
if model.DB.First(&inst, input.InstanceID).Error == nil && inst.WorkflowID != nil {
|
||||
input.WorkflowID = inst.WorkflowID
|
||||
}
|
||||
}
|
||||
|
||||
status := "pending"
|
||||
priority := "medium"
|
||||
riskLevel := "low"
|
||||
@@ -348,7 +356,13 @@ func CreateTicket(c *gin.Context) {
|
||||
// POST /api/v1/tickets/:id/approve
|
||||
func ApproveTicket(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
userID, _, _ := middleware.GetCurrentUser(c)
|
||||
userID, userRole, _ := middleware.GetCurrentUser(c)
|
||||
|
||||
// Role check: only admin/dba/auditor can approve
|
||||
if userRole != "admin" && userRole != "dba" && userRole != "auditor" {
|
||||
c.JSON(http.StatusForbidden, gin.H{"detail": "权限不足:审核操作需要管理员、DBA 或审核员角色"})
|
||||
return
|
||||
}
|
||||
|
||||
var ticket model.Ticket
|
||||
if err := model.DB.First(&ticket, id).Error; err != nil {
|
||||
@@ -370,25 +384,19 @@ func ApproveTicket(c *gin.Context) {
|
||||
// Update approval record — auto-create if missing (legacy tickets)
|
||||
var approval model.TicketApproval
|
||||
if err := model.DB.Where("ticket_id = ? AND approver_id = ? AND action IS NULL", id, userID).First(&approval).Error; err != nil {
|
||||
// No approval record — check if user is authorized to review
|
||||
_, userRole, _ := middleware.GetCurrentUser(c)
|
||||
if userRole == "admin" || userRole == "dba" {
|
||||
stepName := "审核"
|
||||
stepType := "audit"
|
||||
approverRole := userRole
|
||||
approval = model.TicketApproval{
|
||||
TicketID: ticket.ID,
|
||||
StepNumber: 1,
|
||||
StepName: &stepName,
|
||||
StepType: &stepType,
|
||||
ApproverID: &userID,
|
||||
ApproverRole: &approverRole,
|
||||
}
|
||||
model.DB.Create(&approval)
|
||||
} else {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "No pending approval for you"})
|
||||
return
|
||||
// No approval record — authorized role can create one
|
||||
stepName := "审核"
|
||||
stepType := "audit"
|
||||
approverRole := userRole
|
||||
approval = model.TicketApproval{
|
||||
TicketID: ticket.ID,
|
||||
StepNumber: 1,
|
||||
StepName: &stepName,
|
||||
StepType: &stepType,
|
||||
ApproverID: &userID,
|
||||
ApproverRole: &approverRole,
|
||||
}
|
||||
model.DB.Create(&approval)
|
||||
}
|
||||
|
||||
approval.Action = &input.Action
|
||||
@@ -421,6 +429,13 @@ func ApproveTicket(c *gin.Context) {
|
||||
func ExecuteTicket(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
// Role check: only admin/dba can execute
|
||||
_, userRole, _ := middleware.GetCurrentUser(c)
|
||||
if userRole != "admin" && userRole != "dba" {
|
||||
c.JSON(http.StatusForbidden, gin.H{"detail": "权限不足:执行操作需要管理员或 DBA 角色"})
|
||||
return
|
||||
}
|
||||
|
||||
var ticket model.Ticket
|
||||
if err := model.DB.First(&ticket, id).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"detail": "Ticket not found"})
|
||||
|
||||
@@ -487,9 +487,10 @@ export default function UsersPage() {
|
||||
<Edit2 className="w-4 h-4" />
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowResetPwd(user)}
|
||||
className="p-1.5 rounded-md hover:bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-muted)] hover:text-yellow-400 transition-colors"
|
||||
title="重置密码"
|
||||
onClick={() => user.auth_source !== 'ldap' && setShowResetPwd(user)}
|
||||
className={`p-1.5 rounded-md transition-colors ${user.auth_source === 'ldap' ? 'opacity-30 cursor-not-allowed' : 'hover:bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-muted)] hover:text-yellow-400'}`}
|
||||
title={user.auth_source === 'ldap' ? 'LDAP 用户密码由 LDAP 服务器管理' : '重置密码'}
|
||||
disabled={user.auth_source === 'ldap'}
|
||||
>
|
||||
<KeyRound className="w-4 h-4" />
|
||||
</button>
|
||||
|
||||
Reference in new issue
Block a user