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
|
@ -103,6 +103,16 @@ func AuthorizedTeamManagement(teamID portainer.TeamID, context *RestrictedReques
|
|||
return false
|
||||
}
|
||||
|
||||
// AuthorizedIsTeamLeader ensure that the user is an admin or a team leader
|
||||
func AuthorizedIsTeamLeader(context *RestrictedRequestContext) bool {
|
||||
return context.IsAdmin || context.IsTeamLeader
|
||||
}
|
||||
|
||||
// AuthorizedIsAdmin ensure that the user is an admin
|
||||
func AuthorizedIsAdmin(context *RestrictedRequestContext) bool {
|
||||
return context.IsAdmin
|
||||
}
|
||||
|
||||
// authorizedEndpointAccess ensure that the user can access the specified environment(endpoint).
|
||||
// It will check if the user is part of the authorized users or part of a team that is
|
||||
// listed in the authorized teams of the environment(endpoint) and the associated group.
|
||||
|
|
|
@ -78,6 +78,19 @@ func (bouncer *RequestBouncer) RestrictedAccess(h http.Handler) http.Handler {
|
|||
return h
|
||||
}
|
||||
|
||||
// TeamLeaderAccess defines a security check for APIs require team leader privilege
|
||||
//
|
||||
// Bouncer operations are applied backwards:
|
||||
// - Parse the JWT from the request and stored in context, user has to be authenticated
|
||||
// - Upgrade to the restricted request
|
||||
// - User is admin or team leader
|
||||
func (bouncer *RequestBouncer) TeamLeaderAccess(h http.Handler) http.Handler {
|
||||
h = bouncer.mwIsTeamLeader(h)
|
||||
h = bouncer.mwUpgradeToRestrictedRequest(h)
|
||||
h = bouncer.mwAuthenticatedUser(h)
|
||||
return h
|
||||
}
|
||||
|
||||
// AuthenticatedAccess defines a security check for restricted API environments(endpoints).
|
||||
// Authentication is required to access these environments(endpoints).
|
||||
// The request context will be enhanced with a RestrictedRequestContext object
|
||||
|
@ -219,6 +232,24 @@ func (bouncer *RequestBouncer) mwUpgradeToRestrictedRequest(next http.Handler) h
|
|||
})
|
||||
}
|
||||
|
||||
// mwIsTeamLeader will verify that the user is an admin or a team leader
|
||||
func (bouncer *RequestBouncer) mwIsTeamLeader(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
securityContext, err := RetrieveRestrictedRequestContext(r)
|
||||
if err != nil {
|
||||
httperror.WriteError(w, http.StatusInternalServerError, "Unable to retrieve restricted request context ", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !securityContext.IsAdmin && !securityContext.IsTeamLeader {
|
||||
httperror.WriteError(w, http.StatusForbidden, "Access denied", httperrors.ErrUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// mwAuthenticateFirst authenticates a request an auth token.
|
||||
// A result of a first succeded token lookup would be used for the authentication.
|
||||
func (bouncer *RequestBouncer) mwAuthenticateFirst(tokenLookups []tokenLookup, next http.Handler) http.Handler {
|
||||
|
|
|
@ -81,11 +81,11 @@ func FilterRegistries(registries []portainer.Registry, user *portainer.User, tea
|
|||
}
|
||||
|
||||
// FilterEndpoints filters environments(endpoints) based on user role and team memberships.
|
||||
// Non administrator users only have access to authorized environments(endpoints) (can be inherited via endpoint groups).
|
||||
// Non administrator and non-team-leader only have access to authorized environments(endpoints) (can be inherited via endpoint groups).
|
||||
func FilterEndpoints(endpoints []portainer.Endpoint, groups []portainer.EndpointGroup, context *RestrictedRequestContext) []portainer.Endpoint {
|
||||
filteredEndpoints := endpoints
|
||||
|
||||
if !context.IsAdmin {
|
||||
if !context.IsAdmin && !context.IsTeamLeader {
|
||||
filteredEndpoints = make([]portainer.Endpoint, 0)
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
|
@ -101,11 +101,11 @@ func FilterEndpoints(endpoints []portainer.Endpoint, groups []portainer.Endpoint
|
|||
}
|
||||
|
||||
// FilterEndpointGroups filters environment(endpoint) groups based on user role and team memberships.
|
||||
// Non administrator users only have access to authorized environment(endpoint) groups.
|
||||
// Non administrator users and Non-team-leaders only have access to authorized environment(endpoint) groups.
|
||||
func FilterEndpointGroups(endpointGroups []portainer.EndpointGroup, context *RestrictedRequestContext) []portainer.EndpointGroup {
|
||||
filteredEndpointGroups := endpointGroups
|
||||
|
||||
if !context.IsAdmin {
|
||||
if !context.IsAdmin && !context.IsTeamLeader {
|
||||
filteredEndpointGroups = make([]portainer.EndpointGroup, 0)
|
||||
|
||||
for _, group := range endpointGroups {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue