Skip to content

Commit 6dc494f

Browse files
committed
Merge branch 'main' into develop-oss
2 parents 6d97706 + 8cd7ab0 commit 6dc494f

29 files changed

+411
-134
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ RUN apt install git gcc musl-dev make -y
66
RUN go install github.com/google/wire/cmd/wire@latest
77
WORKDIR /go/src/github.com/devtron-labs/devtron
88
ADD . /go/src/github.com/devtron-labs/devtron/
9+
ADD ./vendor/github.com/Microsoft/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/microsoft/
910
RUN GOOS=linux make build-all
1011

1112
# uncomment this post build arg

DockerfileEA

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ RUN apt install git gcc musl-dev make -y
66
RUN go install github.com/google/wire/cmd/wire@latest
77
WORKDIR /go/src/github.com/devtron-labs/devtron
88
ADD . /go/src/github.com/devtron-labs/devtron/
9+
ADD ./vendor/github.com/Microsoft/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/microsoft/
910
RUN GOOS=linux make build-all
1011

1112
FROM ubuntu:22.04@sha256:1b8d8ff4777f36f19bfe73ee4df61e3a0b789caeff29caa019539ec7c9a57f95 as devtron-ea

api/appStore/deployment/CommonDeploymentRestHandler.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ func (handler *CommonDeploymentRestHandlerImpl) getAppOfferingMode(installedAppI
9292
err = &util.ApiError{HttpStatusCode: http.StatusBadRequest, UserMessage: "invalid app id"}
9393
return appOfferingMode, installedAppDto, err
9494
}
95-
uniqueAppName := appIdentifier.GetUniqueAppNameIdentifier()
96-
installedAppDto, err = handler.installedAppService.GetInstalledAppByClusterNamespaceAndName(appIdentifier.ClusterId, appIdentifier.Namespace, uniqueAppName)
95+
installedAppDto, err = handler.installedAppService.GetInstalledAppByClusterNamespaceAndName(appIdentifier)
9796
if err != nil {
9897
err = &util.ApiError{HttpStatusCode: http.StatusBadRequest, UserMessage: "unable to find app in database"}
9998
return appOfferingMode, installedAppDto, err

api/auth/user/UserRestHandler.go

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ func (handler UserRestHandlerImpl) CreateUser(w http.ResponseWriter, r *http.Req
142142
//RBAC enforcer Ends
143143
//In create req, we also check if any email exists already. If yes, then in that case we go on and merge existing roles and groups with the ones in request
144144
//but rbac is only checked on create request roles and groups as existing roles and groups are assumed to be checked when created/updated before
145-
res, err := handler.userService.CreateUser(&userInfo)
145+
res, err := handler.userService.CreateUser(&userInfo, token, handler.CheckManagerAuth)
146146
if err != nil {
147147
handler.logger.Errorw("service err, CreateUser", "err", err, "payload", userInfo)
148148
if _, ok := err.(*util.ApiError); ok {
@@ -192,7 +192,7 @@ func (handler UserRestHandlerImpl) UpdateUser(w http.ResponseWriter, r *http.Req
192192
return
193193
}
194194

195-
res, err := handler.userService.UpdateUser(&userInfo, token, handler.checkRBACForUserUpdate)
195+
res, err := handler.userService.UpdateUser(&userInfo, token, handler.checkRBACForUserUpdate, handler.CheckManagerAuth)
196196
if err != nil {
197197
handler.logger.Errorw("service err, UpdateUser", "err", err, "payload", userInfo)
198198
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
@@ -243,18 +243,9 @@ func (handler UserRestHandlerImpl) GetById(w http.ResponseWriter, r *http.Reques
243243
// RBAC enforcer applying
244244
filteredRoleFilter := make([]bean.RoleFilter, 0)
245245
if res.RoleFilters != nil && len(res.RoleFilters) > 0 {
246+
isUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*")
246247
for _, filter := range res.RoleFilters {
247-
authPass := true
248-
if len(filter.Team) > 0 {
249-
if ok := handler.enforcer.Enforce(token, casbin.ResourceUser, casbin.ActionGet, filter.Team); !ok {
250-
authPass = false
251-
}
252-
}
253-
if filter.Entity == bean2.CLUSTER_ENTITIY {
254-
if ok := handler.userCommonService.CheckRbacForClusterEntity(filter.Cluster, filter.Namespace, filter.Group, filter.Kind, filter.Resource, token, handler.CheckManagerAuth); !ok {
255-
authPass = false
256-
}
257-
}
248+
authPass := handler.checkRbacForFilter(token, filter, isUserSuperAdmin)
258249
if authPass {
259250
filteredRoleFilter = append(filteredRoleFilter, filter)
260251
}
@@ -578,18 +569,9 @@ func (handler UserRestHandlerImpl) FetchRoleGroupById(w http.ResponseWriter, r *
578569
token := r.Header.Get("token")
579570
filteredRoleFilter := make([]bean.RoleFilter, 0)
580571
if res.RoleFilters != nil && len(res.RoleFilters) > 0 {
572+
isUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*")
581573
for _, filter := range res.RoleFilters {
582-
authPass := true
583-
if len(filter.Team) > 0 {
584-
if ok := handler.enforcer.Enforce(token, casbin.ResourceUser, casbin.ActionGet, filter.Team); !ok {
585-
authPass = false
586-
}
587-
}
588-
if filter.Entity == bean2.CLUSTER_ENTITIY {
589-
if isValidAuth := handler.userCommonService.CheckRbacForClusterEntity(filter.Cluster, filter.Namespace, filter.Group, filter.Kind, filter.Resource, token, handler.CheckManagerAuth); !isValidAuth {
590-
authPass = false
591-
}
592-
}
574+
authPass := handler.checkRbacForFilter(token, filter, isUserSuperAdmin)
593575
if authPass {
594576
filteredRoleFilter = append(filteredRoleFilter, filter)
595577
}
@@ -610,6 +592,35 @@ func (handler UserRestHandlerImpl) FetchRoleGroupById(w http.ResponseWriter, r *
610592
common.WriteJsonResp(w, err, res, http.StatusOK)
611593
}
612594

595+
func (handler UserRestHandlerImpl) checkRbacForFilter(token string, filter bean.RoleFilter, isUserSuperAdmin bool) bool {
596+
isAuthorised := true
597+
switch {
598+
case isUserSuperAdmin:
599+
isAuthorised = true
600+
case filter.AccessType == bean2.APP_ACCESS_TYPE_HELM || filter.Entity == bean2.EntityJobs:
601+
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
602+
isAuthorised = false
603+
}
604+
605+
case len(filter.Team) > 0:
606+
// this is case of devtron app
607+
if ok := handler.enforcer.Enforce(token, casbin.ResourceUser, casbin.ActionGet, filter.Team); !ok {
608+
isAuthorised = false
609+
}
610+
611+
case filter.Entity == bean.CLUSTER_ENTITIY:
612+
isValidAuth := handler.userCommonService.CheckRbacForClusterEntity(filter.Cluster, filter.Namespace, filter.Group, filter.Kind, filter.Resource, token, handler.CheckManagerAuth)
613+
if !isValidAuth {
614+
isAuthorised = false
615+
}
616+
case filter.Entity == bean.CHART_GROUP_ENTITY:
617+
isAuthorised = true
618+
default:
619+
isAuthorised = false
620+
}
621+
return isAuthorised
622+
}
623+
613624
func (handler UserRestHandlerImpl) CreateRoleGroup(w http.ResponseWriter, r *http.Request) {
614625
decoder := json.NewDecoder(r.Body)
615626
userId, err := handler.userService.GetLoggedInUser(r)
@@ -698,7 +709,7 @@ func (handler UserRestHandlerImpl) UpdateRoleGroup(w http.ResponseWriter, r *htt
698709
return
699710
}
700711

701-
res, err := handler.roleGroupService.UpdateRoleGroup(&request, token, handler.checkRBACForRoleGroupUpdate)
712+
res, err := handler.roleGroupService.UpdateRoleGroup(&request, token, handler.checkRBACForRoleGroupUpdate, handler.CheckManagerAuth)
702713
if err != nil {
703714
handler.logger.Errorw("service err, UpdateRoleGroup", "err", err, "payload", request)
704715
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
@@ -908,7 +919,7 @@ func (handler UserRestHandlerImpl) DeleteRoleGroup(w http.ResponseWriter, r *htt
908919
return
909920
}
910921
token := r.Header.Get("token")
911-
isAuthorised, err := handler.checkRBACForRoleGroupDelete(token, userGroup.RoleFilters)
922+
isAuthorised, err := handler.checkRBACForRoleGroupDelete(token, userGroup)
912923
if err != nil {
913924
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
914925
return
@@ -1138,7 +1149,7 @@ func (handler UserRestHandlerImpl) checkRBACForUserCreate(token string, requestS
11381149
isAuthorised = false
11391150
}
11401151
if !isAuthorised {
1141-
break
1152+
return false, nil
11421153
}
11431154
}
11441155
}
@@ -1167,7 +1178,7 @@ func (handler UserRestHandlerImpl) checkRBACForUserCreate(token string, requestS
11671178
isAuthorised = false
11681179
}
11691180
if !isAuthorised {
1170-
break
1181+
return false, nil
11711182
}
11721183
}
11731184
} else {
@@ -1206,7 +1217,7 @@ func (handler UserRestHandlerImpl) checkRBACForUserUpdate(token string, userInfo
12061217
isAuthorised = false
12071218
}
12081219
if !isAuthorised {
1209-
break
1220+
return false, nil
12101221
}
12111222
}
12121223
}
@@ -1225,7 +1236,7 @@ func (handler UserRestHandlerImpl) checkRBACForUserUpdate(token string, userInfo
12251236
isAuthorised = false
12261237
}
12271238
if !isAuthorised {
1228-
break
1239+
return false, nil
12291240
}
12301241
}
12311242
}
@@ -1252,7 +1263,7 @@ func (handler UserRestHandlerImpl) checkRBACForUserUpdate(token string, userInfo
12521263
isAuthorised = false
12531264
}
12541265
if !isAuthorised {
1255-
break
1266+
return false, nil
12561267
}
12571268
}
12581269
} else {
@@ -1263,11 +1274,10 @@ func (handler UserRestHandlerImpl) checkRBACForUserUpdate(token string, userInfo
12631274
return isAuthorised, nil
12641275
}
12651276

1266-
func (handler UserRestHandlerImpl) checkRBACForRoleGroupUpdate(token string, groupInfo *bean.RoleGroup,
1267-
eliminatedRoleFilters []*repository.RoleModel) (isAuthorised bool, err error) {
1277+
func (handler UserRestHandlerImpl) checkRBACForRoleGroupUpdate(token string, groupInfo *bean.RoleGroup, eliminatedRoleFilters []*repository.RoleModel, isRoleGroupAlreadySuperAdmin bool) (isAuthorised bool, err error) {
12681278
isActionUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*")
12691279
requestSuperAdmin := groupInfo.SuperAdmin
1270-
if requestSuperAdmin && !isActionUserSuperAdmin {
1280+
if (requestSuperAdmin || isRoleGroupAlreadySuperAdmin) && !isActionUserSuperAdmin {
12711281
//if user is going to be provided with super-admin access or already a super-admin then the action user should be a super-admin
12721282
return false, nil
12731283
}
@@ -1290,7 +1300,7 @@ func (handler UserRestHandlerImpl) checkRBACForRoleGroupUpdate(token string, gro
12901300
isAuthorised = false
12911301
}
12921302
if !isAuthorised {
1293-
break
1303+
return false, nil
12941304
}
12951305
}
12961306
}
@@ -1309,20 +1319,23 @@ func (handler UserRestHandlerImpl) checkRBACForRoleGroupUpdate(token string, gro
13091319
isAuthorised = false
13101320
}
13111321
if !isAuthorised {
1312-
break
1322+
return false, nil
13131323
}
13141324
}
13151325
}
13161326
}
13171327
return isAuthorised, nil
13181328
}
13191329

1320-
func (handler UserRestHandlerImpl) checkRBACForRoleGroupDelete(token string, groupRoles []bean.RoleFilter) (isAuthorised bool, err error) {
1330+
func (handler UserRestHandlerImpl) checkRBACForRoleGroupDelete(token string, userGroup *bean.RoleGroup) (isAuthorised bool, err error) {
13211331
isActionUserSuperAdmin := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*")
1332+
if userGroup.SuperAdmin && !isActionUserSuperAdmin {
1333+
return false, nil
1334+
}
13221335
isAuthorised = isActionUserSuperAdmin
13231336
if !isAuthorised {
1324-
if groupRoles != nil && len(groupRoles) > 0 { //auth check inside roleFilters
1325-
for _, filter := range groupRoles {
1337+
if userGroup.RoleFilters != nil && len(userGroup.RoleFilters) > 0 { //auth check inside roleFilters
1338+
for _, filter := range userGroup.RoleFilters {
13261339
switch {
13271340
case filter.Action == bean.ACTION_SUPERADMIN:
13281341
isAuthorised = isActionUserSuperAdmin
@@ -1338,7 +1351,7 @@ func (handler UserRestHandlerImpl) checkRBACForRoleGroupDelete(token string, gro
13381351
isAuthorised = false
13391352
}
13401353
if !isAuthorised {
1341-
break
1354+
return false, nil
13421355
}
13431356
}
13441357
}

api/helm-app/HelmAppRestHandler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func (handler *HelmAppRestHandlerImpl) GetApplicationDetail(w http.ResponseWrite
159159
return
160160
}
161161

162-
installedApp, err := handler.installedAppService.GetInstalledAppByClusterNamespaceAndName(appIdentifier.ClusterId, appIdentifier.Namespace, appIdentifier.ReleaseName)
162+
installedApp, err := handler.installedAppService.GetInstalledAppByClusterNamespaceAndName(appIdentifier)
163163
if err != nil {
164164
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
165165
return

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,17 +714,33 @@ func (handler *PipelineConfigRestHandlerImpl) TriggerCiPipeline(w http.ResponseW
714714
return
715715
}
716716
cdPipelineRbacObjects := make([]string, len(cdPipelines))
717+
rbacObjectCdTriggerTypeMap := make(map[string]pipelineConfig.TriggerType, len(cdPipelines))
717718
for i, cdPipeline := range cdPipelines {
718719
envObject := handler.enforcerUtil.GetAppRBACByAppIdAndPipelineId(cdPipeline.AppId, cdPipeline.Id)
719720
cdPipelineRbacObjects[i] = envObject
721+
rbacObjectCdTriggerTypeMap[envObject] = cdPipeline.TriggerType
720722
}
721-
envRbacResultMap := handler.enforcer.EnforceInBatch(token, casbin.ResourceEnvironment, casbin.ActionTrigger, cdPipelineRbacObjects)
722-
for _, rbacResultOk := range envRbacResultMap {
723-
if !rbacResultOk {
723+
724+
hasAnyEnvTriggerAccess := len(cdPipelines) == 0 //if no pipelines then appAccess is enough. For jobs also, this will be true
725+
if !hasAnyEnvTriggerAccess {
726+
//cdPipelines present, to check access for cd trigger
727+
envRbacResultMap := handler.enforcer.EnforceInBatch(token, casbin.ResourceEnvironment, casbin.ActionTrigger, cdPipelineRbacObjects)
728+
for rbacObject, rbacResultOk := range envRbacResultMap {
729+
if rbacObjectCdTriggerTypeMap[rbacObject] == pipelineConfig.TRIGGER_TYPE_AUTOMATIC && !rbacResultOk {
730+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
731+
return
732+
}
733+
if rbacResultOk { //this flow will come if pipeline is automatic and has access or if pipeline is manual,
734+
// by which we can ensure if there are no automatic pipelines then atleast access on one manual is present
735+
hasAnyEnvTriggerAccess = true
736+
}
737+
}
738+
if !hasAnyEnvTriggerAccess {
724739
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusForbidden)
725740
return
726741
}
727742
}
743+
728744
//RBAC ENDS
729745
response := make(map[string]string)
730746
resp, err := handler.ciHandler.HandleCIManual(ciTriggerRequest)

cmd/external-app/wire_gen.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/sql/repository/dockerRegistry/DockerArtifactStoreRepository.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@ type DockerArtifactStore struct {
6666
sql.AuditLog
6767
}
6868

69-
type DockerArtifactStoreExt struct {
70-
*DockerArtifactStore
71-
DeploymentCount int `sql:"deployment_count" json:"deploymentCount"`
72-
}
73-
7469
type ChartDeploymentCount struct {
7570
OCIChartName string `sql:"oci_chart_name" json:"ociChartName"`
7671
DeploymentCount int `sql:"deployment_count" json:"deploymentCount"`
@@ -94,7 +89,7 @@ type DockerArtifactStoreRepository interface {
9489
FindAllDockerArtifactCount() (int, error)
9590
FindAllChartProviders() ([]DockerArtifactStore, error)
9691
FindOne(storeId string) (*DockerArtifactStore, error)
97-
FindOneWithDeploymentCount(storeId string) (*DockerArtifactStoreExt, error)
92+
FindDeploymentCount(storeId string) (int, error)
9893
FindOneWithChartDeploymentCount(storeId, chartName string) (*ChartDeploymentCount, error)
9994
FindOneInactive(storeId string) (*DockerArtifactStore, error)
10095
Update(artifactStore *DockerArtifactStore, tx *pg.Tx) error
@@ -205,14 +200,14 @@ func (impl DockerArtifactStoreRepositoryImpl) FindOne(storeId string) (*DockerAr
205200
return &provider, err
206201
}
207202

208-
func (impl DockerArtifactStoreRepositoryImpl) FindOneWithDeploymentCount(storeId string) (*DockerArtifactStoreExt, error) {
209-
var provider DockerArtifactStoreExt
210-
query := "SELECT docker_artifact_store.*, count(jq.ia_id) as deployment_count FROM docker_artifact_store" +
203+
func (impl DockerArtifactStoreRepositoryImpl) FindDeploymentCount(storeId string) (int, error) {
204+
var DeploymentCount int
205+
query := "SELECT count(jq.ia_id) as deployment_count FROM docker_artifact_store" +
211206
fmt.Sprintf(" LEFT JOIN oci_registry_config orc on (docker_artifact_store.id = orc.docker_artifact_store_id and orc.is_chart_pull_active = true and orc.deleted = false and orc.repository_type = '%s' and (orc.repository_action = '%s' or orc.repository_action = '%s'))", OCI_REGISRTY_REPO_TYPE_CHART, STORAGE_ACTION_TYPE_PULL, STORAGE_ACTION_TYPE_PULL_AND_PUSH) +
212207
" LEFT JOIN (SELECT aps.docker_artifact_store_id as das_id ,ia.id as ia_id FROM installed_app_versions iav INNER JOIN installed_apps ia on iav.installed_app_id = ia.id INNER JOIN app_store_application_version asav on iav.app_store_application_version_id = asav.id INNER JOIN app_store aps on asav.app_store_id = aps.id WHERE ia.active=true and iav.active=true) jq on jq.das_id = docker_artifact_store.id" +
213208
" WHERE docker_artifact_store.id = ? and docker_artifact_store.active = true Group by docker_artifact_store.id;"
214-
_, err := impl.dbConnection.Query(&provider, query, storeId)
215-
return &provider, err
209+
_, err := impl.dbConnection.Query(&DeploymentCount, query, storeId)
210+
return DeploymentCount, err
216211
}
217212

218213
func (impl DockerArtifactStoreRepositoryImpl) FindOneWithChartDeploymentCount(storeId, chartName string) (*ChartDeploymentCount, error) {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package cdWorkflow
2+
3+
import (
4+
"errors"
5+
"github.com/devtron-labs/common-lib/utils/k8s/health"
6+
"github.com/devtron-labs/devtron/client/argocdServer/bean"
7+
)
8+
9+
var WfrTerminalStatusList = []string{WorkflowAborted, WorkflowFailed, WorkflowSucceeded, bean.HIBERNATING, string(health.HealthStatusHealthy), string(health.HealthStatusDegraded)}
10+
11+
type WorkflowStatus int
12+
13+
const (
14+
WF_UNKNOWN WorkflowStatus = iota
15+
REQUEST_ACCEPTED
16+
ENQUEUED
17+
QUE_ERROR
18+
WF_STARTED
19+
DROPPED_STALE
20+
DEQUE_ERROR
21+
TRIGGER_ERROR
22+
)
23+
24+
const (
25+
WorkflowStarting = "Starting"
26+
WorkflowInQueue = "Queued"
27+
WorkflowInitiated = "Initiating"
28+
WorkflowInProgress = "Progressing"
29+
WorkflowAborted = "Aborted"
30+
WorkflowFailed = "Failed"
31+
WorkflowSucceeded = "Succeeded"
32+
WorkflowTimedOut = "TimedOut"
33+
WorkflowUnableToFetchState = "UnableToFetch"
34+
WorkflowTypeDeploy = "DEPLOY"
35+
WorkflowTypePre = "PRE"
36+
WorkflowTypePost = "POST"
37+
)
38+
39+
func (a WorkflowStatus) String() string {
40+
return [...]string{"WF_UNKNOWN", "REQUEST_ACCEPTED", "ENQUEUED", "QUE_ERROR", "WF_STARTED", "DROPPED_STALE", "DEQUE_ERROR", "TRIGGER_ERROR"}[a]
41+
}
42+
43+
var ErrorDeploymentSuperseded = errors.New(NEW_DEPLOYMENT_INITIATED)
44+
45+
const (
46+
WORKFLOW_EXECUTOR_TYPE_AWF = "AWF"
47+
WORKFLOW_EXECUTOR_TYPE_SYSTEM = "SYSTEM"
48+
NEW_DEPLOYMENT_INITIATED = "A new deployment was initiated before this deployment completed!"
49+
PIPELINE_DELETED = "The pipeline has been deleted!"
50+
FOUND_VULNERABILITY = "Found vulnerability on image"
51+
GITOPS_REPO_NOT_CONFIGURED = "GitOps repository is not configured for the app"
52+
)
53+
54+
type WorkflowExecutorType string

0 commit comments

Comments
 (0)