0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-13 13:16:02 +02:00

permission check when save filters and actions

This commit is contained in:
Lunny Xiao 2025-12-29 18:26:01 -08:00
parent 3d5241a260
commit ce3755483d
No known key found for this signature in database
GPG Key ID: C3B7C91B632F738A
3 changed files with 114 additions and 55 deletions

View File

@ -4,6 +4,7 @@
package projects
import (
stdCtx "context"
"fmt"
"io"
"net/http"
@ -24,23 +25,40 @@ var (
)
// convertFormToFilters converts form filters to WorkflowFilter objects
func convertFormToFilters(formFilters map[string]any) []project_model.WorkflowFilter {
func convertFormToFilters(ctx stdCtx.Context, project *project_model.Project, formFilters map[string]any) []project_model.WorkflowFilter {
filters := make([]project_model.WorkflowFilter, 0)
for key, value := range formFilters {
switch key {
case "labels":
case string(project_model.WorkflowFilterTypeLabels):
// Handle labels array
if labelInterfaces, ok := value.([]any); ok && len(labelInterfaces) > 0 {
for _, labelInterface := range labelInterfaces {
if label, ok := labelInterface.(string); ok && label != "" {
filters = append(filters, project_model.WorkflowFilter{
Type: project_model.WorkflowFilterTypeLabels,
Value: label,
})
labelID, _ := strconv.ParseInt(label, 10, 64)
if project_service.CanProjectAddLabel(ctx, project, labelID) {
filters = append(filters, project_model.WorkflowFilter{
Type: project_model.WorkflowFilterTypeLabels,
Value: label,
})
}
}
}
}
case string(project_model.WorkflowFilterTypeSourceColumn), string(project_model.WorkflowFilterTypeTargetColumn):
if strValue, ok := value.(string); ok && strValue != "" {
strValueInt, _ := strconv.ParseInt(strValue, 10, 64)
if strValueInt > 0 {
col, _ := project_model.GetColumnByProjectIDAndColumnID(ctx, project.ID, strValueInt)
if col == nil {
continue
}
filters = append(filters, project_model.WorkflowFilter{
Type: project_model.WorkflowFilterType(key),
Value: strconv.FormatInt(strValueInt, 10),
})
}
}
default:
// Handle string values (issue_type, column)
if strValue, ok := value.(string); ok && strValue != "" {
@ -56,18 +74,22 @@ func convertFormToFilters(formFilters map[string]any) []project_model.WorkflowFi
}
// convertFormToActions converts form actions to WorkflowAction objects
func convertFormToActions(formActions map[string]any) []project_model.WorkflowAction {
func convertFormToActions(ctx stdCtx.Context, project *project_model.Project, formActions map[string]any) []project_model.WorkflowAction {
actions := make([]project_model.WorkflowAction, 0)
for key, value := range formActions {
switch key {
case string(project_model.WorkflowActionTypeColumn):
if floatValue, ok := value.(string); ok {
floatValueInt, _ := strconv.ParseInt(floatValue, 10, 64)
if floatValueInt > 0 {
if colValue, ok := value.(string); ok {
colValueInt, _ := strconv.ParseInt(colValue, 10, 64)
if colValueInt > 0 {
col, _ := project_model.GetColumnByProjectIDAndColumnID(ctx, project.ID, colValueInt)
if col == nil {
continue
}
actions = append(actions, project_model.WorkflowAction{
Type: project_model.WorkflowActionTypeColumn,
Value: strconv.FormatInt(floatValueInt, 10),
Value: strconv.FormatInt(colValueInt, 10),
})
}
}
@ -76,15 +98,22 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
if labels, ok := value.([]string); ok && len(labels) > 0 {
for _, label := range labels {
if label != "" {
actions = append(actions, project_model.WorkflowAction{
Type: project_model.WorkflowActionTypeAddLabels,
Value: label,
})
labelID, _ := strconv.ParseInt(label, 10, 64)
if project_service.CanProjectAddLabel(ctx, project, labelID) {
actions = append(actions, project_model.WorkflowAction{
Type: project_model.WorkflowActionTypeAddLabels,
Value: label,
})
}
}
}
} else if labelInterfaces, ok := value.([]any); ok && len(labelInterfaces) > 0 {
for _, labelInterface := range labelInterfaces {
if label, ok := labelInterface.(string); ok && label != "" {
labelID, _ := strconv.ParseInt(label, 10, 64)
if !project_service.CanProjectAddLabel(ctx, project, labelID) {
continue
}
actions = append(actions, project_model.WorkflowAction{
Type: project_model.WorkflowActionTypeAddLabels,
Value: label,
@ -97,6 +126,10 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
if labels, ok := value.([]string); ok && len(labels) > 0 {
for _, label := range labels {
if label != "" {
labelID, _ := strconv.ParseInt(label, 10, 64)
if !project_service.CanProjectAddLabel(ctx, project, labelID) {
continue
}
actions = append(actions, project_model.WorkflowAction{
Type: project_model.WorkflowActionTypeRemoveLabels,
Value: label,
@ -106,6 +139,10 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
} else if labelInterfaces, ok := value.([]any); ok && len(labelInterfaces) > 0 {
for _, labelInterface := range labelInterfaces {
if label, ok := labelInterface.(string); ok && label != "" {
labelID, _ := strconv.ParseInt(label, 10, 64)
if !project_service.CanProjectAddLabel(ctx, project, labelID) {
continue
}
actions = append(actions, project_model.WorkflowAction{
Type: project_model.WorkflowActionTypeRemoveLabels,
Value: label,
@ -376,8 +413,8 @@ func WorkflowsPost(ctx *context.Context) {
}
// Convert form data to filters and actions
filters := convertFormToFilters(form.Filters)
actions := convertFormToActions(form.Actions)
filters := convertFormToFilters(ctx, p, form.Filters)
actions := convertFormToActions(ctx, p, form.Actions)
// Validate: at least one action must be configured
if len(actions) == 0 {
@ -420,40 +457,41 @@ func WorkflowsPost(ctx *context.Context) {
Enabled: wf.Enabled,
},
})
} else {
// Update an existing workflow
wf, err := project_model.GetWorkflowByID(ctx, eventID)
if err != nil {
ctx.ServerError("GetWorkflowByID", err)
return
}
if wf.ProjectID != projectID {
ctx.NotFound(nil)
return
}
wf.WorkflowFilters = filters
wf.WorkflowActions = actions
if err := project_model.UpdateWorkflow(ctx, wf); err != nil {
ctx.ServerError("UpdateWorkflow", err)
return
}
// Return the updated workflow with filter summary
workflowSummary := project_service.GetWorkflowSummary(ctx, wf)
ctx.JSON(http.StatusOK, map[string]any{
"success": true,
"workflow": WorkflowConfig{
ID: wf.ID,
EventID: strconv.FormatInt(wf.ID, 10),
DisplayName: string(ctx.Tr(wf.WorkflowEvent.LangKey())),
Filters: wf.WorkflowFilters,
Actions: wf.WorkflowActions,
Summary: workflowSummary,
Enabled: wf.Enabled,
},
})
return
}
// Update an existing workflow
wf, err := project_model.GetWorkflowByID(ctx, eventID)
if err != nil {
ctx.ServerError("GetWorkflowByID", err)
return
}
if wf.ProjectID != projectID {
ctx.NotFound(nil)
return
}
wf.WorkflowFilters = filters
wf.WorkflowActions = actions
if err := project_model.UpdateWorkflow(ctx, wf); err != nil {
ctx.ServerError("UpdateWorkflow", err)
return
}
// Return the updated workflow with filter summary
workflowSummary := project_service.GetWorkflowSummary(ctx, wf)
ctx.JSON(http.StatusOK, map[string]any{
"success": true,
"workflow": WorkflowConfig{
ID: wf.ID,
EventID: strconv.FormatInt(wf.ID, 10),
DisplayName: string(ctx.Tr(wf.WorkflowEvent.LangKey())),
Filters: wf.WorkflowFilters,
Actions: wf.WorkflowActions,
Summary: workflowSummary,
Enabled: wf.Enabled,
},
})
}
func WorkflowsStatus(ctx *context.Context) {

View File

@ -40,3 +40,24 @@ func GetProjectLabels(ctx context.Context, project *project_model.Project) ([]*i
}
return labels, nil
}
func CanProjectAddLabel(ctx context.Context, project *project_model.Project, labelID int64) bool {
switch project.Type {
case project_model.TypeOrganization, project_model.TypeIndividual:
label, _ := issues_model.GetLabelInOrgByID(ctx, project.OwnerID, labelID)
return label != nil
case project_model.TypeRepository:
label, _ := issues_model.GetLabelInRepoByID(ctx, project.RepoID, labelID)
if label != nil {
return true
}
if err := project.LoadRepo(ctx); err != nil {
return false
}
label, _ = issues_model.GetLabelInOrgByID(ctx, project.Repo.OwnerID, labelID)
return label != nil
}
return false
}

View File

@ -345,7 +345,7 @@ func matchWorkflowsFilters(workflow *project_model.Workflow, issue *issues_model
}
func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflow, issue *issues_model.Issue) {
var toAddedLables, toRemovedLables []*issues_model.Label
var toAddedLabels, toRemovedLabels []*issues_model.Label
for _, action := range workflow.WorkflowActions {
switch action.Type {
@ -375,7 +375,7 @@ func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflo
log.Error("GetLabelByID: %v", err)
continue
}
toAddedLables = append(toAddedLables, label)
toAddedLabels = append(toAddedLabels, label)
case project_model.WorkflowActionTypeRemoveLabels:
labelID, _ := strconv.ParseInt(action.Value, 10, 64)
if labelID == 0 {
@ -387,7 +387,7 @@ func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflo
log.Error("GetLabelByID: %v", err)
continue
}
toRemovedLables = append(toRemovedLables, label)
toRemovedLabels = append(toRemovedLabels, label)
case project_model.WorkflowActionTypeIssueState:
if strings.EqualFold(action.Value, "reopen") {
if issue.IsClosed {
@ -409,8 +409,8 @@ func executeWorkflowActions(ctx context.Context, workflow *project_model.Workflo
}
}
if len(toAddedLables)+len(toRemovedLables) > 0 {
if err := issue_service.AddRemoveLabels(ctx, issue, user_model.NewProjectWorkflowsUser(), toAddedLables, toRemovedLables); err != nil {
if len(toAddedLabels)+len(toRemovedLabels) > 0 {
if err := issue_service.AddRemoveLabels(ctx, issue, user_model.NewProjectWorkflowsUser(), toAddedLabels, toRemovedLabels); err != nil {
log.Error("AddRemoveLabels: %v", err)
}
}