fix(projectinstance): resolve author_only duties in ABAC gates
Use ResolveDocTaskDuty so normalized author-only plans (author ID only) are treated as full A/A/A for access, stage visibility, and readiness. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -63,7 +63,8 @@ func classifyAccess(dt DocTaskPlan, action string, userID int64, isCreator bool,
|
||||
if !dt.Enabled {
|
||||
return DocAccessDecision{Allowed: false, Code: AccessCodeDocTaskDisabled, Message: "该文档已被创建者禁用"}
|
||||
}
|
||||
switch classifyDocDuty(dt.Duties) {
|
||||
mode, effective, _ := ResolveDocTaskDuty(dt)
|
||||
switch mode {
|
||||
case DutyModeNone:
|
||||
switch action {
|
||||
case DocAccessActionRun, DocAccessActionEdit:
|
||||
@@ -90,7 +91,7 @@ func classifyAccess(dt DocTaskPlan, action string, userID int64, isCreator bool,
|
||||
}
|
||||
case DutyModeFull:
|
||||
role := requiredDutyRole(action)
|
||||
if userHoldsDuty(dt.Duties, userID, role) {
|
||||
if userHoldsDuty(effective, userID, role) {
|
||||
return allow
|
||||
}
|
||||
return DocAccessDecision{
|
||||
|
||||
@@ -25,7 +25,8 @@ func evaluateStageReadiness(
|
||||
continue
|
||||
}
|
||||
td, hasDef := taskDefMap[dt.TaskKey]
|
||||
approvalManaged := classifyDocDuty(dt.Duties) != DutyModeNone
|
||||
mode, _, _ := ResolveDocTaskDuty(dt)
|
||||
approvalManaged := mode != DutyModeNone
|
||||
required := approvalManaged && (!hasDef || td.BlocksWhenEnabled())
|
||||
state := docStates[dt.TaskKey]
|
||||
if state == "" {
|
||||
|
||||
@@ -83,7 +83,7 @@ func (s *Service) ResolveStageAccess(ctx context.Context, projectID int64, userI
|
||||
if !dt.Enabled {
|
||||
continue
|
||||
}
|
||||
if docTaskDutyForUser(dt, userID) || (isCreator && classifyDocDuty(dt.Duties) == DutyModeNone) {
|
||||
if docTaskDutyForUser(dt, userID) || (isCreator && docTaskDutyMode(dt) == DutyModeNone) {
|
||||
out.AllowedTaskKeys[dt.TaskKey] = true
|
||||
}
|
||||
}
|
||||
@@ -100,18 +100,24 @@ func stageDutyForUser(st StagePlan, userID int64) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func docTaskDutyMode(dt DocTaskPlan) DutyMode {
|
||||
mode, _, _ := ResolveDocTaskDuty(dt)
|
||||
return mode
|
||||
}
|
||||
|
||||
func docTaskDutyForUser(dt DocTaskPlan, userID int64) bool {
|
||||
if classifyDocDuty(dt.Duties) != DutyModeFull {
|
||||
mode, effective, _ := ResolveDocTaskDuty(dt)
|
||||
if mode != DutyModeFull {
|
||||
return false
|
||||
}
|
||||
return dt.Duties.AuthorUserID == userID ||
|
||||
dt.Duties.ReviewerUserID == userID ||
|
||||
dt.Duties.ApproverUserID == userID
|
||||
return effective.AuthorUserID == userID ||
|
||||
effective.ReviewerUserID == userID ||
|
||||
effective.ApproverUserID == userID
|
||||
}
|
||||
|
||||
func stageHasUnmanagedDoc(st StagePlan) bool {
|
||||
for _, dt := range st.DocTasks {
|
||||
if dt.Enabled && classifyDocDuty(dt.Duties) == DutyModeNone {
|
||||
if dt.Enabled && docTaskDutyMode(dt) == DutyModeNone {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user