Skip to content

Commit

Permalink
feat: active inactive user phase 2 (#4624)
Browse files Browse the repository at this point in the history
* listing user and group changes

* default value chnage

* group listing optimisation

* wire_gen

* order by in group

* default values

* discard

* updated on

* case insensitive

* script number change

* specs

* review chnages

* sql update

* id for user

* script number chnage

* review comments-1

* review comments

* review comments

* rest handler remove methods

* validation for delete

* delete user handling

* review comments

* review comments

* bulk delete user and permission group

* legacy code fix from loop in query to bulk query

* export csv filters support

* Revert "export csv filters support"

This reverts commit 4448c9e.

* export csv filters

* bulk delete support with filters

* validation

* method break

* refactor the method

* condition

* open api  specs

* specs

* refactoring filters in bulk delete rolegroup

* comments

* comments

* group listing

* review comments

* review comments

* review comments

* review comments

* user delete self-review

* error handling

* renaming helpers

* commets

* checks and renaming
  • Loading branch information
Shivam-nagar23 committed Feb 20, 2024
1 parent c2e7964 commit c44db71
Show file tree
Hide file tree
Showing 16 changed files with 812 additions and 103 deletions.
108 changes: 102 additions & 6 deletions api/auth/user/UserRestHandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type UserRestHandler interface {
GetAllV2(w http.ResponseWriter, r *http.Request)
DeleteUser(w http.ResponseWriter, r *http.Request)
GetAllDetailedUsers(w http.ResponseWriter, r *http.Request)
BulkDeleteUsers(w http.ResponseWriter, r *http.Request)
FetchRoleGroupById(w http.ResponseWriter, r *http.Request)
CreateRoleGroup(w http.ResponseWriter, r *http.Request)
UpdateRoleGroup(w http.ResponseWriter, r *http.Request)
Expand All @@ -56,6 +57,7 @@ type UserRestHandler interface {
FetchDetailedRoleGroups(w http.ResponseWriter, r *http.Request)
FetchRoleGroupsByName(w http.ResponseWriter, r *http.Request)
DeleteRoleGroup(w http.ResponseWriter, r *http.Request)
BulkDeleteRoleGroups(w http.ResponseWriter, r *http.Request)
CheckUserRoles(w http.ResponseWriter, r *http.Request)
SyncOrchestratorToCasbin(w http.ResponseWriter, r *http.Request)
UpdateTriggerPolicyForTerminalAccess(w http.ResponseWriter, r *http.Request)
Expand Down Expand Up @@ -360,7 +362,7 @@ func (handler UserRestHandlerImpl) GetAllV2(w http.ResponseWriter, r *http.Reque
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
req := &bean.FetchListingRequest{}
req := &bean.ListingRequest{}
err = decoder.Decode(req, r.URL.Query())
if err != nil {
handler.logger.Errorw("request err, GetAll", "err", err, "payload", req)
Expand Down Expand Up @@ -519,8 +521,8 @@ func (handler UserRestHandlerImpl) DeleteUser(w http.ResponseWriter, r *http.Req
}
//RBAC enforcer Ends
//validation
validated := helper.CheckIfUserDevtronManaged(int32(id))
if !validated {
validated := helper.IsSystemOrAdminUser(int32(id))
if validated {
err = &util.ApiError{Code: "400", HttpStatusCode: 400, UserMessage: "cannot delete system or admin user"}
handler.logger.Errorw("request err, DeleteUser, validation failed", "id", id, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
Expand All @@ -537,6 +539,56 @@ func (handler UserRestHandlerImpl) DeleteUser(w http.ResponseWriter, r *http.Req
common.WriteJsonResp(w, err, res, http.StatusOK)
}

func (handler UserRestHandlerImpl) BulkDeleteUsers(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
decoder := json.NewDecoder(r.Body)
// request decoding
var request *bean.BulkDeleteRequest
err = decoder.Decode(&request)
if err != nil {
handler.logger.Errorw("request err, BulkDeleteUsers", "payload", request, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
handler.logger.Debugw("request payload, BulkDeleteUsers", "payload", request)
// setting logged in user Id for audit logs
request.LoggedInUserId = userId

// validations for system and admin user
err = helper.CheckValidationForAdminAndSystemUserId(request.Ids)
if err != nil {
handler.logger.Errorw("request err, BulkDeleteUsers, validation failed", "payload", request, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

// RBAC enforcer applying
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}
// struct validation
err = handler.validator.Struct(request)
if err != nil {
handler.logger.Errorw("validation err, BulkDeleteUsers", "payload", request, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
// service call
res, err := handler.userService.BulkDeleteUsers(request)
if err != nil {
handler.logger.Errorw("service err, BulkDeleteUsers", "payload", request, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, res, http.StatusOK)
}

func (handler UserRestHandlerImpl) FetchRoleGroupById(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
/* #nosec */
Expand Down Expand Up @@ -769,7 +821,7 @@ func (handler UserRestHandlerImpl) FetchRoleGroupsV2(w http.ResponseWriter, r *h
return
}

req := &bean.FetchListingRequest{}
req := &bean.ListingRequest{}
err = decoder.Decode(req, r.URL.Query())
if err != nil {
handler.logger.Errorw("request err, FetchRoleGroups", "err", err, "payload", req)
Expand Down Expand Up @@ -863,8 +915,8 @@ func (handler UserRestHandlerImpl) FetchDetailedRoleGroups(w http.ResponseWriter
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}

res, err := handler.roleGroupService.FetchDetailedRoleGroups()
req := &bean.ListingRequest{ShowAll: true}
res, err := handler.roleGroupService.FetchDetailedRoleGroups(req)
if err != nil {
handler.logger.Errorw("service err, FetchRoleGroups", "err", err)
common.WriteJsonResp(w, err, "", http.StatusInternalServerError)
Expand Down Expand Up @@ -950,6 +1002,50 @@ func (handler UserRestHandlerImpl) DeleteRoleGroup(w http.ResponseWriter, r *htt
common.WriteJsonResp(w, err, res, http.StatusOK)
}

func (handler UserRestHandlerImpl) BulkDeleteRoleGroups(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized)
return
}
decoder := json.NewDecoder(r.Body)
// request decoding
var request *bean.BulkDeleteRequest
err = decoder.Decode(&request)
if err != nil {
handler.logger.Errorw("request err, BulkDeleteRoleGroups", "payload", request, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}
handler.logger.Debugw("request payload, BulkDeleteRoleGroups", "payload", request)
// setting logged in user Id for audit logs
request.LoggedInUserId = userId

// struct validation
err = handler.validator.Struct(request)
if err != nil {
handler.logger.Errorw("validation err, BulkDeleteRoleGroups", "payload", request, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
return
}

// RBAC enforcer applying
token := r.Header.Get("token")
if ok := handler.enforcer.Enforce(token, casbin.ResourceGlobal, casbin.ActionGet, "*"); !ok {
common.WriteJsonResp(w, errors.New("unauthorized"), nil, http.StatusForbidden)
return
}

// service call
res, err := handler.roleGroupService.BulkDeleteRoleGroups(request)
if err != nil {
handler.logger.Errorw("service err, BulkDeleteRoleGroups", "payload", request, "err", err)
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
return
}
common.WriteJsonResp(w, nil, res, http.StatusOK)
}

func (handler UserRestHandlerImpl) CheckUserRoles(w http.ResponseWriter, r *http.Request) {
userId, err := handler.userService.GetLoggedInUser(r)
if userId == 0 || err != nil {
Expand Down
4 changes: 4 additions & 0 deletions api/auth/user/UserRouter.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ func (router UserRouterImpl) InitUserRouter(userAuthRouter *mux.Router) {
HandlerFunc(router.userRestHandler.GetAll).Methods("GET")
userAuthRouter.Path("").
HandlerFunc(router.userRestHandler.UpdateUser).Methods("PUT")
userAuthRouter.Path("/bulk").
HandlerFunc(router.userRestHandler.BulkDeleteUsers).Methods("DELETE")
userAuthRouter.Path("/{id}").
HandlerFunc(router.userRestHandler.DeleteUser).Methods("DELETE")
userAuthRouter.Path("/detail/get").
Expand All @@ -68,6 +70,8 @@ func (router UserRouterImpl) InitUserRouter(userAuthRouter *mux.Router) {
userAuthRouter.Path("/role/group/search").
Queries("name", "{name}").
HandlerFunc(router.userRestHandler.FetchRoleGroupsByName).Methods("GET")
userAuthRouter.Path("/role/group/bulk").
HandlerFunc(router.userRestHandler.BulkDeleteRoleGroups).Methods("DELETE")
userAuthRouter.Path("/role/group/{id}").
HandlerFunc(router.userRestHandler.DeleteRoleGroup).Methods("DELETE")

Expand Down
2 changes: 0 additions & 2 deletions api/auth/user/wire_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ import (
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
user2 "github.com/devtron-labs/devtron/pkg/auth/user"
repository2 "github.com/devtron-labs/devtron/pkg/auth/user/repository"
"github.com/devtron-labs/devtron/pkg/auth/user/repository/helper"
"github.com/google/wire"
)

//depends on sql,validate,logger

var UserWireSet = wire.NewSet(
UserAuditWireSet,
helper.NewUserRepositoryQueryBuilder,
NewUserAuthRouterImpl,
wire.Bind(new(UserAuthRouter), new(*UserAuthRouterImpl)),
NewUserAuthHandlerImpl,
Expand Down
8 changes: 7 additions & 1 deletion api/bean/UserRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ type RoleGroupListingResponse struct {
TotalCount int `json:"totalCount"`
}

type FetchListingRequest struct {
type ListingRequest struct {
SearchKey string `json:"searchKey"`
SortOrder bean.SortOrder `json:"sortOrder"`
SortBy bean.SortBy `json:"sortBy"`
Expand All @@ -139,3 +139,9 @@ type FetchListingRequest struct {
ShowAll bool `json:"showAll"`
CountCheck bool `json:"-"`
}

type BulkDeleteRequest struct {
Ids []int32 `json:"ids"`
ListingRequest *ListingRequest `json:"listingRequest,omitempty"`
LoggedInUserId int32 `json:"-"`
}
6 changes: 2 additions & 4 deletions cmd/external-app/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c44db71

Please sign in to comment.