Skip to content

Commit 37b07f1

Browse files
authored
feat: auto assign permission group (#6923)
* feat: auto-assign role groups * fix: sync claims with casbin policy * feat: file re-structuring for ent oss sync * feat: global auth apis * sync file name with oss
1 parent e3ddc14 commit 37b07f1

20 files changed

Lines changed: 1342 additions & 172 deletions

Wire.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
appStoreDiscover "github.com/devtron-labs/devtron/api/appStore/discover"
3434
appStoreValues "github.com/devtron-labs/devtron/api/appStore/values"
3535
"github.com/devtron-labs/devtron/api/argoApplication"
36+
"github.com/devtron-labs/devtron/api/auth/authorisation/globalConfig"
3637
"github.com/devtron-labs/devtron/api/auth/sso"
3738
"github.com/devtron-labs/devtron/api/auth/user"
3839
chartRepo "github.com/devtron-labs/devtron/api/chartRepo"
@@ -192,6 +193,7 @@ func InitializeApp() (*App, error) {
192193
externalLink.ExternalLinkWireSet,
193194
team.TeamsWireSet,
194195
AuthWireSet,
196+
globalConfig.GlobalConfigWireSet,
195197
util4.GetRuntimeConfig,
196198
util4.NewK8sUtil,
197199
wire.Bind(new(util4.K8sService), new(*util4.K8sServiceImpl)),
@@ -993,7 +995,7 @@ func InitializeApp() (*App, error) {
993995

994996
router.NewOverviewRouterImpl,
995997
wire.Bind(new(router.OverviewRouter), new(*router.OverviewRouterImpl)),
996-
998+
997999
restHandler.NewInfraOverviewRestHandlerImpl,
9981000
wire.Bind(new(restHandler.InfraOverviewRestHandler), new(*restHandler.InfraOverviewRestHandlerImpl)),
9991001

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2024. Devtron Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package globalConfig
18+
19+
import "github.com/gorilla/mux"
20+
21+
type AuthorisationConfigRouter interface {
22+
InitAuthorisationConfigRouter(router *mux.Router)
23+
}
24+
25+
type AuthorisationConfigRouterImpl struct {
26+
handler AuthorisationConfigRestHandler
27+
}
28+
29+
func NewGlobalConfigAuthorisationRouterImpl(handler AuthorisationConfigRestHandler) *AuthorisationConfigRouterImpl {
30+
return &AuthorisationConfigRouterImpl{handler: handler}
31+
}
32+
33+
func (router *AuthorisationConfigRouterImpl) InitAuthorisationConfigRouter(authorisationConfigRouter *mux.Router) {
34+
authorisationConfigRouter.Path("/global-config").
35+
HandlerFunc(router.handler.CreateOrUpdateAuthorisationConfig).Methods("POST")
36+
authorisationConfigRouter.Path("/global-config").
37+
HandlerFunc(router.handler.GetAllActiveAuthorisationConfig).Methods("GET")
38+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (c) 2024. Devtron Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package globalConfig
18+
19+
import (
20+
"encoding/json"
21+
"errors"
22+
"net/http"
23+
24+
"github.com/devtron-labs/devtron/api/restHandler/common"
25+
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
26+
auth "github.com/devtron-labs/devtron/pkg/auth/authorisation/globalConfig"
27+
"github.com/devtron-labs/devtron/pkg/auth/authorisation/globalConfig/bean"
28+
"github.com/devtron-labs/devtron/pkg/auth/user"
29+
"github.com/devtron-labs/devtron/util/commonEnforcementFunctionsUtil"
30+
"go.uber.org/zap"
31+
"gopkg.in/go-playground/validator.v9"
32+
)
33+
34+
type AuthorisationConfigRestHandler interface {
35+
CreateOrUpdateAuthorisationConfig(w http.ResponseWriter, r *http.Request)
36+
GetAllActiveAuthorisationConfig(w http.ResponseWriter, r *http.Request)
37+
}
38+
39+
type AuthorisationConfigRestHandlerImpl struct {
40+
validator *validator.Validate
41+
logger *zap.SugaredLogger
42+
enforcer casbin.Enforcer
43+
userService user.UserService
44+
userCommonService user.UserCommonService
45+
globalAuthorisationConfigService auth.GlobalAuthorisationConfigService
46+
rbacEnforcementUtil commonEnforcementFunctionsUtil.CommonEnforcementUtil
47+
}
48+
49+
func NewGlobalAuthorisationConfigRestHandlerImpl(validator *validator.Validate,
50+
logger *zap.SugaredLogger, enforcer casbin.Enforcer,
51+
userService user.UserService,
52+
globalAuthorisationConfigService auth.GlobalAuthorisationConfigService,
53+
userCommonService user.UserCommonService,
54+
rbacEnforcementUtil commonEnforcementFunctionsUtil.CommonEnforcementUtil,
55+
) *AuthorisationConfigRestHandlerImpl {
56+
return &AuthorisationConfigRestHandlerImpl{
57+
validator: validator,
58+
logger: logger,
59+
enforcer: enforcer,
60+
userService: userService,
61+
globalAuthorisationConfigService: globalAuthorisationConfigService,
62+
userCommonService: userCommonService,
63+
rbacEnforcementUtil: rbacEnforcementUtil,
64+
}
65+
}
66+
67+
func (handler *AuthorisationConfigRestHandlerImpl) CreateOrUpdateAuthorisationConfig(w http.ResponseWriter, r *http.Request) {
68+
userId, err := handler.userService.GetLoggedInUser(r)
69+
if userId == 0 || err != nil {
70+
common.HandleUnauthorized(w, r)
71+
return
72+
}
73+
decoder := json.NewDecoder(r.Body)
74+
var globalConfigPayload bean.GlobalAuthorisationConfig
75+
err = decoder.Decode(&globalConfigPayload)
76+
if err != nil {
77+
handler.logger.Errorw("request err, CreateOrUpdateAuthorisationConfig", "err", err, "payload", globalConfigPayload)
78+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
79+
return
80+
}
81+
token := r.Header.Get("token")
82+
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionCreate, "*"); !ok {
83+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
84+
return
85+
}
86+
isValidationError, err := handler.validateGlobalAuthorisationConfigPayload(globalConfigPayload)
87+
if err != nil {
88+
handler.logger.Errorw("error, validateGlobalAuthorisationConfigPayload", "payload", globalConfigPayload, "err", err)
89+
if isValidationError {
90+
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
91+
return
92+
}
93+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
94+
return
95+
}
96+
globalConfigPayload.UserId = userId
97+
resp, err := handler.globalAuthorisationConfigService.CreateOrUpdateGlobalAuthConfig(globalConfigPayload, nil)
98+
if err != nil {
99+
handler.logger.Errorw("service error, CreateOrUpdateAuthorisationConfig", "err", err, "payload", globalConfigPayload)
100+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
101+
return
102+
}
103+
common.WriteJsonResp(w, nil, resp, http.StatusOK)
104+
}
105+
106+
func (handler *AuthorisationConfigRestHandlerImpl) GetAllActiveAuthorisationConfig(w http.ResponseWriter, r *http.Request) {
107+
userId, err := handler.userService.GetLoggedInUser(r)
108+
if userId == 0 || err != nil {
109+
common.HandleUnauthorized(w, r)
110+
return
111+
}
112+
token := r.Header.Get("token")
113+
isAuthorised, err := handler.rbacEnforcementUtil.CheckRbacForMangerAndAboveAccess(token, userId)
114+
if err != nil {
115+
handler.logger.Errorw("error, GetAllActiveAuthorisationConfig", "err", err)
116+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
117+
return
118+
}
119+
if !isAuthorised {
120+
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
121+
return
122+
}
123+
resp, err := handler.globalAuthorisationConfigService.GetAllActiveAuthorisationConfig()
124+
if err != nil {
125+
handler.logger.Errorw("service error, GetAllActiveAuthorisationConfig", "err", err)
126+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
127+
return
128+
}
129+
common.WriteJsonResp(w, nil, resp, http.StatusOK)
130+
}
131+
132+
func (handler *AuthorisationConfigRestHandlerImpl) validateGlobalAuthorisationConfigPayload(globalConfigPayload bean.GlobalAuthorisationConfig) (bool, error) {
133+
err := handler.validator.Struct(globalConfigPayload)
134+
if err != nil {
135+
handler.logger.Errorw("err, validateGlobalAuthorisationConfigPayload", "payload", globalConfigPayload, "err", err)
136+
return true, err
137+
}
138+
if len(globalConfigPayload.ConfigTypes) == 0 {
139+
handler.logger.Errorw("err, validation failed on validateGlobalAuthorisationConfigPayload due to no configType provided", "payload", globalConfigPayload)
140+
return true, errors.New("no configTypes provided in request")
141+
}
142+
return false, nil
143+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2024. Devtron Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package globalConfig
18+
19+
import "github.com/google/wire"
20+
21+
// GlobalConfigWireSet wires the REST handler and router for the authorisation global-config API.
22+
// NOTE: GlobalAuthorisationConfigRepository and GlobalAuthorisationConfigService are already
23+
// provided by UserWireSet (api/auth/user/wire_user.go) and must not be re-declared here.
24+
var GlobalConfigWireSet = wire.NewSet(
25+
NewGlobalAuthorisationConfigRestHandlerImpl,
26+
wire.Bind(new(AuthorisationConfigRestHandler), new(*AuthorisationConfigRestHandlerImpl)),
27+
NewGlobalConfigAuthorisationRouterImpl,
28+
wire.Bind(new(AuthorisationConfigRouter), new(*AuthorisationConfigRouterImpl)),
29+
)

api/auth/user/wire_selfRegistration.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
//depends on sql,
2626
//TODO integrate user auth module
2727

28+
// SelfRegistrationWireSet depends on GlobalAuthorisationConfigService which is provided by UserWireSet
2829
var SelfRegistrationWireSet = wire.NewSet(
2930
repository.NewSelfRegistrationRolesRepositoryImpl,
3031
wire.Bind(new(repository.SelfRegistrationRolesRepository), new(*repository.SelfRegistrationRolesRepositoryImpl)),

api/auth/user/wire_user.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package user
1919
import (
2020
"github.com/devtron-labs/devtron/pkg/auth/authentication"
2121
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
22+
globalConfig "github.com/devtron-labs/devtron/pkg/auth/authorisation/globalConfig"
23+
globalConfigRepo "github.com/devtron-labs/devtron/pkg/auth/authorisation/globalConfig/repository"
2224
user2 "github.com/devtron-labs/devtron/pkg/auth/user"
2325
repository2 "github.com/devtron-labs/devtron/pkg/auth/user/repository"
2426
"github.com/google/wire"
@@ -77,4 +79,13 @@ var UserWireSet = wire.NewSet(
7779
wire.Bind(new(RbacRoleRestHandler), new(*RbacRoleRestHandlerImpl)),
7880
user2.NewRbacRoleServiceImpl,
7981
wire.Bind(new(user2.RbacRoleService), new(*user2.RbacRoleServiceImpl)),
82+
83+
repository2.NewUserAutoAssignGroupMapRepositoryImpl,
84+
wire.Bind(new(repository2.UserAutoAssignGroupMapRepository), new(*repository2.UserAutoAssignGroupMapRepositoryImpl)),
85+
86+
globalConfigRepo.NewGlobalAuthorisationConfigRepositoryImpl,
87+
wire.Bind(new(globalConfigRepo.GlobalAuthorisationConfigRepository), new(*globalConfigRepo.GlobalAuthorisationConfigRepositoryImpl)),
88+
89+
globalConfig.NewGlobalAuthorisationConfigServiceImpl,
90+
wire.Bind(new(globalConfig.GlobalAuthorisationConfigService), new(*globalConfig.GlobalAuthorisationConfigServiceImpl)),
8091
)

api/router/router.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/devtron-labs/devtron/api/appStore/chartGroup"
2626
appStoreDeployment "github.com/devtron-labs/devtron/api/appStore/deployment"
2727
"github.com/devtron-labs/devtron/api/argoApplication"
28+
"github.com/devtron-labs/devtron/api/auth/authorisation/globalConfig"
2829
"github.com/devtron-labs/devtron/api/auth/sso"
2930
"github.com/devtron-labs/devtron/api/auth/user"
3031
"github.com/devtron-labs/devtron/api/chartRepo"
@@ -126,6 +127,7 @@ type MuxRouter struct {
126127
scanningResultRouter resourceScan.ScanningResultRouter
127128
userResourceRouter userResource.Router
128129
overviewRouter OverviewRouter
130+
globalAuthorisationConfigRouter globalConfig.AuthorisationConfigRouter
129131
}
130132

131133
func NewMuxRouter(logger *zap.SugaredLogger,
@@ -162,6 +164,7 @@ func NewMuxRouter(logger *zap.SugaredLogger,
162164
scanningResultRouter resourceScan.ScanningResultRouter,
163165
userResourceRouter userResource.Router,
164166
overviewRouter OverviewRouter,
167+
globalAuthorisationConfigRouter globalConfig.AuthorisationConfigRouter,
165168
) *MuxRouter {
166169
r := &MuxRouter{
167170
Router: mux.NewRouter(),
@@ -230,6 +233,7 @@ func NewMuxRouter(logger *zap.SugaredLogger,
230233
scanningResultRouter: scanningResultRouter,
231234
userResourceRouter: userResourceRouter,
232235
overviewRouter: overviewRouter,
236+
globalAuthorisationConfigRouter: globalAuthorisationConfigRouter,
233237
}
234238
return r
235239
}
@@ -306,6 +310,9 @@ func (r MuxRouter) Init() {
306310
userRouter := r.Router.PathPrefix("/orchestrator/user").Subrouter()
307311
r.UserRouter.InitUserRouter(userRouter)
308312

313+
authorisationConfigRouter := r.Router.PathPrefix("/orchestrator/authorisation").Subrouter()
314+
r.globalAuthorisationConfigRouter.InitAuthorisationConfigRouter(authorisationConfigRouter)
315+
309316
chartRefRouter := r.Router.PathPrefix("/orchestrator/chartref").Subrouter()
310317
r.ChartRefRouter.initChartRefRouter(chartRefRouter)
311318

0 commit comments

Comments
 (0)