@@ -28,6 +28,7 @@ import (
28
28
util3 "github.com/devtron-labs/devtron/pkg/appStore/util"
29
29
"github.com/devtron-labs/devtron/pkg/bean"
30
30
"net/http"
31
+ "reflect"
31
32
"strconv"
32
33
"strings"
33
34
"time"
@@ -363,6 +364,8 @@ func (handler *InstalledAppRestHandlerImpl) DeployBulk(w http.ResponseWriter, r
363
364
common .WriteJsonResp (w , fmt .Errorf ("unauthorized user" ), nil , http .StatusForbidden )
364
365
return
365
366
}
367
+ charts , authRes := handler .checkForHelmDeployAuth (request , token )
368
+ request .ChartGroupInstallChartRequest = charts
366
369
//RBAC block ends here
367
370
368
371
visited := make (map [string ]bool )
@@ -391,10 +394,116 @@ func (handler *InstalledAppRestHandlerImpl) DeployBulk(w http.ResponseWriter, r
391
394
handler .Logger .Errorw ("service err, DeployBulk" , "err" , err , "payload" , request )
392
395
common .WriteJsonResp (w , err , nil , http .StatusInternalServerError )
393
396
return
397
+ } else {
398
+ res = authRes
394
399
}
395
400
common .WriteJsonResp (w , err , res , http .StatusOK )
396
401
}
397
402
403
+ func (handler * InstalledAppRestHandlerImpl ) checkForHelmDeployAuth (request chartGroup.ChartGroupInstallRequest , token string ) ([]* chartGroup.ChartGroupInstallChartRequest , * chartGroup.ChartGroupInstallAppRes ) {
404
+ //the value of this map is array of integer because the GetHelmObjectByProjectIdAndEnvId method may return "//" for error cases
405
+ //so different environments may contain same object, to handle that we are using (map[string] []int)
406
+ rbacObjectToEnvIdMap1 := make (map [string ][]int )
407
+ rbacObjectToEnvIdMap2 := make (map [string ][]int )
408
+
409
+ rbacObjectArray1 := make ([]string , 0 )
410
+ rbacObjectArray2 := make ([]string , 0 )
411
+
412
+ envIdToChartGroupInstallChartRequest := make (map [int ][]* chartGroup.ChartGroupInstallChartRequest )
413
+
414
+ for _ , chartGroupInstall := range request .ChartGroupInstallChartRequest {
415
+ envIdToChartGroupInstallChartRequest [chartGroupInstall .EnvironmentId ] = append (envIdToChartGroupInstallChartRequest [chartGroupInstall .EnvironmentId ], chartGroupInstall )
416
+ rbacObject1 , rbacObject2 := handler .enforcerUtil .GetHelmObjectByProjectIdAndEnvId (request .ProjectId , chartGroupInstall .EnvironmentId )
417
+ _ , ok := rbacObjectToEnvIdMap1 [rbacObject1 ]
418
+ if ! ok {
419
+ rbacObjectToEnvIdMap1 [rbacObject1 ] = make ([]int , 0 )
420
+ }
421
+ rbacObjectToEnvIdMap1 [rbacObject1 ] = append (rbacObjectToEnvIdMap1 [rbacObject1 ], chartGroupInstall .EnvironmentId )
422
+ rbacObjectArray1 = append (rbacObjectArray1 , rbacObject1 )
423
+ _ , ok = rbacObjectToEnvIdMap2 [rbacObject2 ]
424
+ if ! ok {
425
+ rbacObjectToEnvIdMap2 [rbacObject2 ] = make ([]int , 0 )
426
+ }
427
+ rbacObjectToEnvIdMap2 [rbacObject2 ] = append (rbacObjectToEnvIdMap2 [rbacObject2 ], chartGroupInstall .EnvironmentId )
428
+ rbacObjectArray2 = append (rbacObjectArray2 , rbacObject2 )
429
+ }
430
+ resultObjectMap1 := handler .enforcer .EnforceInBatch (token , casbin .ResourceHelmApp , casbin .ActionCreate , rbacObjectArray1 )
431
+ resultObjectMap2 := handler .enforcer .EnforceInBatch (token , casbin .ResourceHelmApp , casbin .ActionCreate , rbacObjectArray2 )
432
+
433
+ authorizedEnvIdSet := make (map [int ]bool )
434
+
435
+ //O(n) time loop , at max we will only iterate through all the envs
436
+ for obj , ok := range resultObjectMap1 {
437
+ if ok {
438
+ envIds := rbacObjectToEnvIdMap1 [obj ]
439
+ for _ , envId := range envIds {
440
+ authorizedEnvIdSet [envId ] = true
441
+ }
442
+ }
443
+ }
444
+ for obj , ok := range resultObjectMap2 {
445
+ if ok {
446
+ envIds := rbacObjectToEnvIdMap2 [obj ]
447
+ for _ , envId := range envIds {
448
+ authorizedEnvIdSet [envId ] = true
449
+ }
450
+ }
451
+ }
452
+ authorizedChartGroupInstallRequests := make ([]* chartGroup.ChartGroupInstallChartRequest , 0 )
453
+ for envId , _ := range authorizedEnvIdSet {
454
+ authorizedChartGroupInstall := envIdToChartGroupInstallChartRequest [envId ]
455
+ for _ , authChartGroup := range authorizedChartGroupInstall {
456
+ authorizedChartGroupInstallRequests = append (authorizedChartGroupInstallRequests , authChartGroup )
457
+ }
458
+ }
459
+ unauthorizedChartGroupInstallRequests := make ([]* chartGroup.ChartGroupInstallChartRequest , 0 )
460
+
461
+ for _ , req := range request .ChartGroupInstallChartRequest {
462
+ isAuthorized := false
463
+ for _ , authReq := range authorizedChartGroupInstallRequests {
464
+ if reflect .DeepEqual (req , authReq ) {
465
+ isAuthorized = true
466
+ break
467
+ }
468
+ }
469
+ if ! isAuthorized {
470
+ unauthorizedChartGroupInstallRequests = append (unauthorizedChartGroupInstallRequests , req )
471
+ }
472
+ }
473
+
474
+ // Create slices for ChartGroupInstallMetadata
475
+ authorizedMetadata := make ([]chartGroup.ChartGroupInstallMetadata , 0 )
476
+ unauthorizedMetadata := make ([]chartGroup.ChartGroupInstallMetadata , 0 )
477
+
478
+ for _ , req := range authorizedChartGroupInstallRequests {
479
+ metadata := handler .getChartGroupInstallMetadata (req , string (chartGroup .StatusSuccess ), string (chartGroup .ReasonTriggered ))
480
+ authorizedMetadata = append (authorizedMetadata , metadata )
481
+ }
482
+
483
+ for _ , req := range unauthorizedChartGroupInstallRequests {
484
+ metadata := handler .getChartGroupInstallMetadata (req , string (chartGroup .StatusFailed ), string (chartGroup .ReasonNotAuthorize ))
485
+ unauthorizedMetadata = append (unauthorizedMetadata , metadata )
486
+ }
487
+ unauthorizeCount := len (unauthorizedChartGroupInstallRequests )
488
+ totalCount := len (request .ChartGroupInstallChartRequest )
489
+ // Combine all metadata into a single ChartGroupInstallAppRes
490
+ chartGroupInstallAppRes := & chartGroup.ChartGroupInstallAppRes {
491
+ ChartGroupInstallMetadata : append (authorizedMetadata , unauthorizedMetadata ... ),
492
+ Summary : fmt .Sprintf (chartGroup .FAILED_TO_TRIGGER , unauthorizeCount , totalCount ),
493
+ }
494
+ return authorizedChartGroupInstallRequests , chartGroupInstallAppRes
495
+ }
496
+
497
+ func (handler * InstalledAppRestHandlerImpl ) getChartGroupInstallMetadata (req * chartGroup.ChartGroupInstallChartRequest , triggerStatus string , reason string ) chartGroup.ChartGroupInstallMetadata {
498
+ metadata := chartGroup.ChartGroupInstallMetadata {
499
+ AppName : req .AppName ,
500
+ EnvironmentId : req .EnvironmentId ,
501
+ TriggerStatus : triggerStatus ,
502
+ Reason : reason ,
503
+ }
504
+ return metadata
505
+ }
506
+
398
507
func (handler * InstalledAppRestHandlerImpl ) CheckAppExists (w http.ResponseWriter , r * http.Request ) {
399
508
userId , err := handler .userAuthService .GetLoggedInUser (r )
400
509
if userId == 0 || err != nil {
0 commit comments