Skip to content

Commit 7a24161

Browse files
committed
Merge branch 'main' into bug-linked-ci
2 parents fc93d7e + f88c542 commit 7a24161

26 files changed

+567
-79
lines changed

.gitbook.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,10 @@ redirects:
7070
user-guide/use-cases/connect-django-with-mysql-database: resources/use-cases/connect-django-with-mysql-database
7171
user-guide/telemetry: resources/telemetry
7272
getting-started/global-configurations/container-registries: user-guide/global-configurations/container-registries.md
73-
getting-started/global-configurations/sso-login: user-guide/global-configurations/sso-login.md
73+
getting-started/global-configurations/sso-login: user-guide/global-configurations/sso-login.md
74+
getting-started/global-configurations/docker-registries: user-guide/global-configurations/container-registries.md
75+
global-configurations/sso-login: user-guide/global-configurations/sso-login.md
76+
user-guide/use-cases/untitled-3: user-guide/use-cases/connect-django-with-mysql-database.md
77+
global-configurations/api-token: user-guide/global-configurations/authorization/api-tokens.md
78+
user-guide/creating-application/workflow/ci-pipeline2: user-guide/creating-application/workflow/ci-pipeline.md
79+

api/argoApplication/ArgoApplicationRestHandler.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package argoApplication
22

33
import (
4+
"errors"
45
"github.com/devtron-labs/devtron/api/restHandler/common"
56
"github.com/devtron-labs/devtron/pkg/argoApplication"
7+
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
68
"go.uber.org/zap"
79
"net/http"
810
"strconv"
@@ -17,18 +19,26 @@ type ArgoApplicationRestHandler interface {
1719
type ArgoApplicationRestHandlerImpl struct {
1820
argoApplicationService argoApplication.ArgoApplicationService
1921
logger *zap.SugaredLogger
22+
enforcer casbin.Enforcer
2023
}
2124

2225
func NewArgoApplicationRestHandlerImpl(argoApplicationService argoApplication.ArgoApplicationService,
23-
logger *zap.SugaredLogger) *ArgoApplicationRestHandlerImpl {
26+
logger *zap.SugaredLogger, enforcer casbin.Enforcer) *ArgoApplicationRestHandlerImpl {
2427
return &ArgoApplicationRestHandlerImpl{
2528
argoApplicationService: argoApplicationService,
2629
logger: logger,
30+
enforcer: enforcer,
2731
}
2832

2933
}
3034

3135
func (handler *ArgoApplicationRestHandlerImpl) ListApplications(w http.ResponseWriter, r *http.Request) {
36+
// handle super-admin RBAC
37+
token := r.Header.Get("token")
38+
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
39+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
40+
return
41+
}
3242
v := r.URL.Query()
3343
clusterIdString := v.Get("clusterIds")
3444
var clusterIds []int
@@ -54,6 +64,12 @@ func (handler *ArgoApplicationRestHandlerImpl) ListApplications(w http.ResponseW
5464
}
5565

5666
func (handler *ArgoApplicationRestHandlerImpl) GetApplicationDetail(w http.ResponseWriter, r *http.Request) {
67+
// handle super-admin RBAC
68+
token := r.Header.Get("token")
69+
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
70+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
71+
return
72+
}
5773
var err error
5874
v := r.URL.Query()
5975
resourceName := v.Get("name")

api/auth/user/UserRestHandler.go

Lines changed: 182 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,15 @@ type UserRestHandler interface {
4545
UpdateUser(w http.ResponseWriter, r *http.Request)
4646
GetById(w http.ResponseWriter, r *http.Request)
4747
GetAll(w http.ResponseWriter, r *http.Request)
48+
GetAllV2(w http.ResponseWriter, r *http.Request)
4849
DeleteUser(w http.ResponseWriter, r *http.Request)
50+
GetAllDetailedUsers(w http.ResponseWriter, r *http.Request)
4951
FetchRoleGroupById(w http.ResponseWriter, r *http.Request)
5052
CreateRoleGroup(w http.ResponseWriter, r *http.Request)
5153
UpdateRoleGroup(w http.ResponseWriter, r *http.Request)
5254
FetchRoleGroups(w http.ResponseWriter, r *http.Request)
55+
FetchRoleGroupsV2(w http.ResponseWriter, r *http.Request)
56+
FetchDetailedRoleGroups(w http.ResponseWriter, r *http.Request)
5357
FetchRoleGroupsByName(w http.ResponseWriter, r *http.Request)
5458
DeleteRoleGroup(w http.ResponseWriter, r *http.Request)
5559
CheckUserRoles(w http.ResponseWriter, r *http.Request)
@@ -301,7 +305,7 @@ func (handler UserRestHandlerImpl) GetById(w http.ResponseWriter, r *http.Reques
301305
common.WriteJsonResp(w, err, res, http.StatusOK)
302306
}
303307

304-
func (handler UserRestHandlerImpl) GetAll(w http.ResponseWriter, r *http.Request) {
308+
func (handler UserRestHandlerImpl) GetAllV2(w http.ResponseWriter, r *http.Request) {
305309
var decoder = schema.NewDecoder()
306310
userId, err := handler.userService.GetLoggedInUser(r)
307311
if userId == 0 || err != nil {
@@ -372,7 +376,95 @@ func (handler UserRestHandlerImpl) GetAll(w http.ResponseWriter, r *http.Request
372376

373377
common.WriteJsonResp(w, err, res, http.StatusOK)
374378
}
379+
func (handler UserRestHandlerImpl) GetAll(w http.ResponseWriter, r *http.Request) {
380+
userId, err := handler.userService.GetLoggedInUser(r)
381+
if userId == 0 || err != nil {
382+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
383+
return
384+
}
375385

386+
// RBAC enforcer applying
387+
token := r.Header.Get("token")
388+
//checking superAdmin access
389+
isAuthorised := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*")
390+
if !isAuthorised {
391+
user, err := handler.userService.GetById(userId)
392+
if err != nil {
393+
handler.logger.Errorw("error in getting user by id", "err", err)
394+
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
395+
return
396+
}
397+
var roleFilters []bean.RoleFilter
398+
if len(user.Groups) > 0 {
399+
groupRoleFilters, err := handler.userService.GetRoleFiltersByGroupNames(user.Groups)
400+
if err != nil {
401+
handler.logger.Errorw("Error in getting role filters by group names", "err", err, "groupNames", user.Groups)
402+
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
403+
return
404+
}
405+
if len(groupRoleFilters) > 0 {
406+
roleFilters = append(roleFilters, groupRoleFilters...)
407+
}
408+
}
409+
if user.RoleFilters != nil && len(user.RoleFilters) > 0 {
410+
roleFilters = append(roleFilters, user.RoleFilters...)
411+
}
412+
if len(roleFilters) > 0 {
413+
for _, filter := range roleFilters {
414+
if len(filter.Team) > 0 {
415+
if ok := handler.enforcer.Enforce(token, casbin.ResourceUser, casbin.ActionGet, filter.Team); ok {
416+
isAuthorised = true
417+
break
418+
}
419+
}
420+
if filter.Entity == bean.CLUSTER_ENTITIY {
421+
if ok := handler.userCommonService.CheckRbacForClusterEntity(filter.Cluster, filter.Namespace, filter.Group, filter.Kind, filter.Resource, token, handler.CheckManagerAuth); ok {
422+
isAuthorised = true
423+
break
424+
}
425+
}
426+
}
427+
}
428+
}
429+
if !isAuthorised {
430+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
431+
return
432+
}
433+
res, err := handler.userService.GetAll()
434+
if err != nil {
435+
handler.logger.Errorw("service err, GetAll", "err", err)
436+
common.WriteJsonResp(w, err, "Failed to Get", http.StatusInternalServerError)
437+
return
438+
}
439+
440+
common.WriteJsonResp(w, err, res, http.StatusOK)
441+
}
442+
443+
func (handler UserRestHandlerImpl) GetAllDetailedUsers(w http.ResponseWriter, r *http.Request) {
444+
userId, err := handler.userService.GetLoggedInUser(r)
445+
if userId == 0 || err != nil {
446+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
447+
return
448+
}
449+
450+
token := r.Header.Get("token")
451+
isActionUserSuperAdmin := false
452+
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); ok {
453+
isActionUserSuperAdmin = true
454+
}
455+
if !isActionUserSuperAdmin {
456+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
457+
return
458+
}
459+
res, err := handler.userService.GetAllDetailedUsers()
460+
if err != nil {
461+
handler.logger.Errorw("service err, GetAllDetailedUsers", "err", err)
462+
common.WriteJsonResp(w, err, "Failed to Get", http.StatusInternalServerError)
463+
return
464+
}
465+
466+
common.WriteJsonResp(w, err, res, http.StatusOK)
467+
}
376468
func (handler UserRestHandlerImpl) DeleteUser(w http.ResponseWriter, r *http.Request) {
377469
userId, err := handler.userService.GetLoggedInUser(r)
378470
if userId == 0 || err != nil {
@@ -621,7 +713,7 @@ func (handler UserRestHandlerImpl) UpdateRoleGroup(w http.ResponseWriter, r *htt
621713
common.WriteJsonResp(w, err, res, http.StatusOK)
622714
}
623715

624-
func (handler UserRestHandlerImpl) FetchRoleGroups(w http.ResponseWriter, r *http.Request) {
716+
func (handler UserRestHandlerImpl) FetchRoleGroupsV2(w http.ResponseWriter, r *http.Request) {
625717
var decoder = schema.NewDecoder()
626718
userId, err := handler.userService.GetLoggedInUser(r)
627719
if userId == 0 || err != nil {
@@ -693,6 +785,94 @@ func (handler UserRestHandlerImpl) FetchRoleGroups(w http.ResponseWriter, r *htt
693785
common.WriteJsonResp(w, err, res, http.StatusOK)
694786
}
695787

788+
func (handler UserRestHandlerImpl) FetchRoleGroups(w http.ResponseWriter, r *http.Request) {
789+
userId, err := handler.userService.GetLoggedInUser(r)
790+
if userId == 0 || err != nil {
791+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
792+
return
793+
}
794+
// RBAC enforcer applying
795+
token := r.Header.Get("token")
796+
//checking superAdmin access
797+
isAuthorised := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*")
798+
if !isAuthorised {
799+
user, err := handler.userService.GetById(userId)
800+
if err != nil {
801+
handler.logger.Errorw("error in getting user by id", "err", err)
802+
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
803+
return
804+
}
805+
var roleFilters []bean.RoleFilter
806+
if len(user.Groups) > 0 {
807+
groupRoleFilters, err := handler.userService.GetRoleFiltersByGroupNames(user.Groups)
808+
if err != nil {
809+
handler.logger.Errorw("Error in getting role filters by group names", "err", err, "groupNames", user.Groups)
810+
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
811+
return
812+
}
813+
if len(groupRoleFilters) > 0 {
814+
roleFilters = append(roleFilters, groupRoleFilters...)
815+
}
816+
}
817+
if user.RoleFilters != nil && len(user.RoleFilters) > 0 {
818+
roleFilters = append(roleFilters, user.RoleFilters...)
819+
}
820+
if len(roleFilters) > 0 {
821+
for _, filter := range roleFilters {
822+
if len(filter.Team) > 0 {
823+
if ok := handler.enforcer.Enforce(token, casbin.ResourceUser, casbin.ActionGet, filter.Team); ok {
824+
isAuthorised = true
825+
break
826+
}
827+
}
828+
if filter.Entity == bean.CLUSTER_ENTITIY {
829+
if isValidAuth := handler.userCommonService.CheckRbacForClusterEntity(filter.Cluster, filter.Namespace, filter.Group, filter.Kind, filter.Resource, token, handler.CheckManagerAuth); isValidAuth {
830+
isAuthorised = true
831+
break
832+
}
833+
}
834+
835+
}
836+
}
837+
}
838+
if !isAuthorised {
839+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
840+
return
841+
}
842+
res, err := handler.roleGroupService.FetchRoleGroups()
843+
if err != nil {
844+
handler.logger.Errorw("service err, FetchRoleGroups", "err", err)
845+
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
846+
return
847+
}
848+
common.WriteJsonResp(w, err, res, http.StatusOK)
849+
}
850+
851+
func (handler UserRestHandlerImpl) FetchDetailedRoleGroups(w http.ResponseWriter, r *http.Request) {
852+
userId, err := handler.userService.GetLoggedInUser(r)
853+
if userId == 0 || err != nil {
854+
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
855+
return
856+
}
857+
token := r.Header.Get("token")
858+
isActionUserSuperAdmin := false
859+
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); ok {
860+
isActionUserSuperAdmin = true
861+
}
862+
if !isActionUserSuperAdmin {
863+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
864+
return
865+
}
866+
867+
res, err := handler.roleGroupService.FetchDetailedRoleGroups()
868+
if err != nil {
869+
handler.logger.Errorw("service err, FetchRoleGroups", "err", err)
870+
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
871+
return
872+
}
873+
common.WriteJsonResp(w, err, res, http.StatusOK)
874+
}
875+
696876
func (handler UserRestHandlerImpl) FetchRoleGroupsByName(w http.ResponseWriter, r *http.Request) {
697877
userId, err := handler.userService.GetLoggedInUser(r)
698878
if userId == 0 || err != nil {

api/auth/user/UserRouter.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ func NewUserRouterImpl(userRestHandler UserRestHandler) *UserRouterImpl {
3838

3939
func (router UserRouterImpl) InitUserRouter(userAuthRouter *mux.Router) {
4040
//User management
41+
userAuthRouter.Path("/v2").
42+
HandlerFunc(router.userRestHandler.GetAllV2).Methods("GET")
4143
userAuthRouter.Path("/{id}").
4244
HandlerFunc(router.userRestHandler.GetById).Methods("GET")
4345
userAuthRouter.Path("").
@@ -48,7 +50,11 @@ func (router UserRouterImpl) InitUserRouter(userAuthRouter *mux.Router) {
4850
HandlerFunc(router.userRestHandler.UpdateUser).Methods("PUT")
4951
userAuthRouter.Path("/{id}").
5052
HandlerFunc(router.userRestHandler.DeleteUser).Methods("DELETE")
53+
userAuthRouter.Path("/detail/get").
54+
HandlerFunc(router.userRestHandler.GetAllDetailedUsers).Methods("GET")
5155

56+
userAuthRouter.Path("/role/group/v2").
57+
HandlerFunc(router.userRestHandler.FetchRoleGroupsV2).Methods("GET")
5258
userAuthRouter.Path("/role/group/{id}").
5359
HandlerFunc(router.userRestHandler.FetchRoleGroupById).Methods("GET")
5460
userAuthRouter.Path("/role/group").
@@ -57,6 +63,8 @@ func (router UserRouterImpl) InitUserRouter(userAuthRouter *mux.Router) {
5763
HandlerFunc(router.userRestHandler.UpdateRoleGroup).Methods("PUT")
5864
userAuthRouter.Path("/role/group").
5965
HandlerFunc(router.userRestHandler.FetchRoleGroups).Methods("GET")
66+
userAuthRouter.Path("/role/group/detailed/get").
67+
HandlerFunc(router.userRestHandler.FetchDetailedRoleGroups).Methods("GET")
6068
userAuthRouter.Path("/role/group/search").
6169
Queries("name", "{name}").
6270
HandlerFunc(router.userRestHandler.FetchRoleGroupsByName).Methods("GET")

api/bean/UserRequest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type UserRole struct {
3131

3232
type UserInfo struct {
3333
Id int32 `json:"id" validate:"number,not-system-admin-userid"`
34-
EmailId string `json:"emailId" validate:"required,not-system-admin-user"`
34+
EmailId string `json:"email_id" validate:"required,not-system-admin-user"` // TODO : have to migrate json key to emailId and also handle backward compatibility
3535
Roles []string `json:"roles,omitempty"`
3636
AccessToken string `json:"access_token,omitempty"`
3737
RoleFilters []RoleFilter `json:"roleFilters"`

api/restHandler/app/pipeline/status/PipelineStatusTimelineRestHandler.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,18 @@ type PipelineStatusTimelineRestHandlerImpl struct {
3333
}
3434

3535
func NewPipelineStatusTimelineRestHandlerImpl(logger *zap.SugaredLogger,
36+
userService user.UserService,
3637
pipelineStatusTimelineService status.PipelineStatusTimelineService, enforcerUtil rbac.EnforcerUtil,
37-
enforcer casbin.Enforcer) *PipelineStatusTimelineRestHandlerImpl {
38+
enforcer casbin.Enforcer, cdApplicationStatusUpdateHandler cron.CdApplicationStatusUpdateHandler,
39+
pipeline pipeline.PipelineBuilder) *PipelineStatusTimelineRestHandlerImpl {
3840
return &PipelineStatusTimelineRestHandlerImpl{
39-
logger: logger,
40-
pipelineStatusTimelineService: pipelineStatusTimelineService,
41-
enforcerUtil: enforcerUtil,
42-
enforcer: enforcer,
41+
logger: logger,
42+
userService: userService,
43+
pipelineStatusTimelineService: pipelineStatusTimelineService,
44+
enforcerUtil: enforcerUtil,
45+
enforcer: enforcer,
46+
cdApplicationStatusUpdateHandler: cdApplicationStatusUpdateHandler,
47+
pipeline: pipeline,
4348
}
4449
}
4550

docs/FAQs/devtron-troubleshoot.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,4 +521,23 @@ kubectl delete pod -n devtroncd -l app=devtron
521521

522522
This command deletes the Devtron pod in the `devtroncd` namespace with the label `app=devtron`.
523523

524-
Following these steps should allow you to refresh the ArgoCD certificates when they have expired.
524+
Following these steps should allow you to refresh the ArgoCD certificates when they have expired.
525+
526+
527+
### 26. Not able to see commits, throwing exit status 128
528+
1. **Save the Git Repository Again**
529+
Wait for few minutes and check the build pipeline if commits are visible or not
530+
531+
2. **Check git sensor pod logs**
532+
533+
```yaml
534+
kubectl logs -n devtroncd -l app=git-sensor
535+
```
536+
If you still get the same issue, try to bounce the pod and save the git repository again
537+
```yaml
538+
kubectl delete po -n devtroncd -l app=git-sensor
539+
```
540+
541+
3. **Try to clone the git repository with the token you have added for Git Account**
542+
543+
In case the cloning fails, you can generate the token, update the Git account in Global Configurations, and try to save the git repository again.

docs/README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,3 @@ Get updates on Devtron's development and chat with the project maintainers, cont
8181
## Vulnerability Reporting
8282

8383
We, at Devtron, take security and our users' trust very seriously. If you believe you have found a security issue in Devtron, please responsibly disclose it by contacting us at **security@devtron.ai**.
84-
85-
## License
86-
87-
Devtron is available under the [Apache License, Version 2.0](https://github.com/devtron-labs/devtron/blob/main/LICENSE).

docs/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
* [Scoped Variables](user-guide/global-configurations/scoped-variables.md)
4545
* [Tags Policy](user-guide/global-configurations/tags-policy.md)
4646
* [Filter Condition](user-guide/global-configurations/filter-condition.md)
47+
* [Build Infra](user-guide/global-configurations/build-infra.md)
4748
* [Devtron Upgrade](setup/upgrade/README.md)
4849
* [Update Devtron from Devtron UI](setup/upgrade/upgrade-devtron-ui.md)
4950
* [0.5.x-0.6.x](setup/upgrade/devtron-upgrade-0.5.x-0.6.x.md)

0 commit comments

Comments
 (0)