Skip to content

Commit cf5d60c

Browse files
fix: ci patch rbac fixes (#5461)
* fix: ci patch rbac fixes * fix: rbac optimisation * fix: refactoring --------- Co-authored-by: Asutosh Das <asutosh2000ad@gmail.com>
1 parent 5c20f35 commit cf5d60c

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

api/restHandler/app/pipeline/configure/BuildPipelineRestHandler.go

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"encoding/json"
2222
"errors"
2323
"fmt"
24+
"golang.org/x/exp/maps"
2425
"io"
2526
"net/http"
2627
"strconv"
@@ -416,12 +417,19 @@ func (handler *PipelineConfigRestHandlerImpl) PatchCiPipelines(w http.ResponseWr
416417
}
417418
resourceName := handler.enforcerUtil.GetAppRBACName(app.AppName)
418419
workflowResourceName := handler.enforcerUtil.GetRbacObjectNameByAppAndWorkflow(app.AppName, appWorkflowName)
419-
var ok bool
420-
ok = handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionCreate, resourceName)
421-
if !ok {
422-
ok = handler.enforcer.Enforce(token, casbin.ResourceJobs, casbin.ActionCreate, resourceName) && handler.enforcer.Enforce(token, casbin.ResourceWorkflow, casbin.ActionCreate, workflowResourceName)
420+
421+
cdPipelines, err := handler.pipelineRepository.FindByCiPipelineId(patchRequest.CiPipeline.Id)
422+
if err != nil && err != pg.ErrNoRows {
423+
handler.Logger.Errorw("error in finding ccd cdPipelines by ciPipelineId", "ciPipelineId", patchRequest.CiPipeline.Id, "err", err)
424+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
425+
return
423426
}
424-
if !ok {
427+
428+
haveCiPatchAccess := handler.checkCiPatchAccess(token, resourceName, cdPipelines)
429+
if !haveCiPatchAccess {
430+
haveCiPatchAccess = handler.enforcer.Enforce(token, casbin.ResourceJobs, casbin.ActionCreate, resourceName) && handler.enforcer.Enforce(token, casbin.ResourceWorkflow, casbin.ActionCreate, workflowResourceName)
431+
}
432+
if !haveCiPatchAccess {
425433
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
426434
return
427435
}
@@ -470,6 +478,33 @@ func (handler *PipelineConfigRestHandlerImpl) PatchCiPipelines(w http.ResponseWr
470478
common.WriteJsonResp(w, err, createResp, http.StatusOK)
471479
}
472480

481+
// checkCiPatchAccess assumes all the cdPipelines belong to same app
482+
func (handler *PipelineConfigRestHandlerImpl) checkCiPatchAccess(token string, resourceName string, cdPipelines []*pipelineConfig.Pipeline) bool {
483+
484+
if len(cdPipelines) == 0 {
485+
// no cd pipelines are present , so user can edit if he has app admin access
486+
return handler.enforcer.Enforce(token, casbin.ResourceApplications, casbin.ActionCreate, resourceName)
487+
}
488+
489+
appId := 0
490+
envIds := make([]int, len(cdPipelines))
491+
for _, cdPipeline := range cdPipelines {
492+
envIds = append(envIds, cdPipeline.EnvironmentId)
493+
appId = cdPipeline.AppId
494+
}
495+
496+
rbacObjectsMap, _ := handler.enforcerUtil.GetRbacObjectsByEnvIdsAndAppId(envIds, appId)
497+
envRbacResultMap := handler.enforcer.EnforceInBatch(token, casbin.ResourceEnvironment, casbin.ActionUpdate, maps.Values(rbacObjectsMap))
498+
499+
for _, hasAccess := range envRbacResultMap {
500+
if hasAccess {
501+
return true
502+
}
503+
}
504+
505+
return false
506+
}
507+
473508
func (handler *PipelineConfigRestHandlerImpl) GetCiPipeline(w http.ResponseWriter, r *http.Request) {
474509
vars := mux.Vars(r)
475510
appId, err := strconv.Atoi(vars["appId"])

0 commit comments

Comments
 (0)