mirror of
https://github.com/portainer/portainer.git
synced 2025-08-05 22:05:23 +02:00
feat(teamleader) EE-294 redesign team leader (#6973)
feat(teamleader) EE-294 redesign team leader (#6973)
This commit is contained in:
parent
bca1c6b9cf
commit
0522032515
29 changed files with 223 additions and 135 deletions
|
@ -21,14 +21,13 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler {
|
|||
h := &Handler{
|
||||
Router: mux.NewRouter(),
|
||||
}
|
||||
h.Handle("/team_memberships",
|
||||
bouncer.AdminAccess(httperror.LoggerHandler(h.teamMembershipCreate))).Methods(http.MethodPost)
|
||||
h.Handle("/team_memberships",
|
||||
bouncer.AdminAccess(httperror.LoggerHandler(h.teamMembershipList))).Methods(http.MethodGet)
|
||||
h.Handle("/team_memberships/{id}",
|
||||
bouncer.AdminAccess(httperror.LoggerHandler(h.teamMembershipUpdate))).Methods(http.MethodPut)
|
||||
h.Handle("/team_memberships/{id}",
|
||||
bouncer.AdminAccess(httperror.LoggerHandler(h.teamMembershipDelete))).Methods(http.MethodDelete)
|
||||
|
||||
h.Use(bouncer.TeamLeaderAccess)
|
||||
|
||||
h.Handle("/team_memberships", httperror.LoggerHandler(h.teamMembershipCreate)).Methods(http.MethodPost)
|
||||
h.Handle("/team_memberships", httperror.LoggerHandler(h.teamMembershipList)).Methods(http.MethodGet)
|
||||
h.Handle("/team_memberships/{id}", httperror.LoggerHandler(h.teamMembershipUpdate)).Methods(http.MethodPut)
|
||||
h.Handle("/team_memberships/{id}", httperror.LoggerHandler(h.teamMembershipDelete)).Methods(http.MethodDelete)
|
||||
|
||||
return h
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/response"
|
||||
"github.com/portainer/portainer/api/http/errors"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
)
|
||||
|
||||
// @id TeamMembershipList
|
||||
|
@ -23,15 +21,6 @@ import (
|
|||
// @failure 500 "Server error"
|
||||
// @router /team_memberships [get]
|
||||
func (handler *Handler) teamMembershipList(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
securityContext, err := security.RetrieveRestrictedRequestContext(r)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err}
|
||||
}
|
||||
|
||||
if !securityContext.IsAdmin && !securityContext.IsTeamLeader {
|
||||
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to list team memberships", errors.ErrResourceAccessDenied}
|
||||
}
|
||||
|
||||
memberships, err := handler.DataStore.TeamMembership().TeamMemberships()
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve team memberships from the database", err}
|
||||
|
|
|
@ -36,8 +36,8 @@ func (payload *teamMembershipUpdatePayload) Validate(r *http.Request) error {
|
|||
|
||||
// @id TeamMembershipUpdate
|
||||
// @summary Update a team membership
|
||||
// @description Update a team membership. Access is only available to administrators leaders of the associated team.
|
||||
// @description **Access policy**: administrator
|
||||
// @description Update a team membership. Access is only available to administrators or leaders of the associated team.
|
||||
// @description **Access policy**: administrator or leaders of the associated team
|
||||
// @tags team_memberships
|
||||
// @security ApiKeyAuth
|
||||
// @security jwt
|
||||
|
@ -63,15 +63,6 @@ func (handler *Handler) teamMembershipUpdate(w http.ResponseWriter, r *http.Requ
|
|||
return &httperror.HandlerError{http.StatusBadRequest, "Invalid request payload", err}
|
||||
}
|
||||
|
||||
securityContext, err := security.RetrieveRestrictedRequestContext(r)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err}
|
||||
}
|
||||
|
||||
if !security.AuthorizedTeamManagement(portainer.TeamID(payload.TeamID), securityContext) {
|
||||
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the membership", httperrors.ErrResourceAccessDenied}
|
||||
}
|
||||
|
||||
membership, err := handler.DataStore.TeamMembership().TeamMembership(portainer.TeamMembershipID(membershipID))
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return &httperror.HandlerError{http.StatusNotFound, "Unable to find a team membership with the specified identifier inside the database", err}
|
||||
|
@ -79,8 +70,15 @@ func (handler *Handler) teamMembershipUpdate(w http.ResponseWriter, r *http.Requ
|
|||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find a team membership with the specified identifier inside the database", err}
|
||||
}
|
||||
|
||||
if securityContext.IsTeamLeader && membership.Role != portainer.MembershipRole(payload.Role) {
|
||||
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the role of membership", httperrors.ErrResourceAccessDenied}
|
||||
securityContext, err := security.RetrieveRestrictedRequestContext(r)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve info from request context", err}
|
||||
}
|
||||
|
||||
isLeadingBothTeam := security.AuthorizedTeamManagement(portainer.TeamID(payload.TeamID), securityContext) &&
|
||||
security.AuthorizedTeamManagement(membership.TeamID, securityContext)
|
||||
if !(securityContext.IsAdmin || isLeadingBothTeam) {
|
||||
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to update the membership", httperrors.ErrResourceAccessDenied}
|
||||
}
|
||||
|
||||
membership.UserID = portainer.UserID(payload.UserID)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue