mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
fix(kubernetes): clear user token from kube token cache on logout + update cluster rolebindings for user on change of team/user authorization [EE-6298] (#10598)
* clear user token from kube token cache on logoug + updates cluster role bindings for service accounts on change user/teams authorizations
This commit is contained in:
parent
e761a00098
commit
e73b7fe0fd
13 changed files with 149 additions and 22 deletions
|
@ -24,6 +24,7 @@ type Handler struct {
|
|||
ProxyManager *proxy.Manager
|
||||
KubernetesTokenCacheManager *kubernetes.TokenCacheManager
|
||||
passwordStrengthChecker security.PasswordStrengthChecker
|
||||
bouncer security.BouncerService
|
||||
}
|
||||
|
||||
// NewHandler creates a handler to manage authentication operations.
|
||||
|
@ -31,6 +32,7 @@ func NewHandler(bouncer security.BouncerService, rateLimiter *security.RateLimit
|
|||
h := &Handler{
|
||||
Router: mux.NewRouter(),
|
||||
passwordStrengthChecker: passwordStrengthChecker,
|
||||
bouncer: bouncer,
|
||||
}
|
||||
|
||||
h.Handle("/auth/oauth/validate",
|
||||
|
@ -39,6 +41,5 @@ func NewHandler(bouncer security.BouncerService, rateLimiter *security.RateLimit
|
|||
rateLimiter.LimitAccess(bouncer.PublicAccess(httperror.LoggerHandler(h.authenticate)))).Methods(http.MethodPost)
|
||||
h.Handle("/auth/logout",
|
||||
bouncer.PublicAccess(httperror.LoggerHandler(h.logout))).Methods(http.MethodPost)
|
||||
|
||||
return h
|
||||
}
|
||||
|
|
|
@ -3,11 +3,9 @@ package auth
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/internal/logoutcontext"
|
||||
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
||||
"github.com/portainer/portainer/pkg/libhttp/response"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// @id Logout
|
||||
|
@ -21,10 +19,7 @@ import (
|
|||
// @router /auth/logout [post]
|
||||
|
||||
func (handler *Handler) logout(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
tokenData, err := security.RetrieveTokenData(r)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Msg("unable to retrieve user details from authentication token")
|
||||
}
|
||||
tokenData := handler.bouncer.JWTAuthLookup(r)
|
||||
|
||||
if tokenData != nil {
|
||||
handler.KubernetesTokenCacheManager.RemoveUserFromCache(tokenData.ID)
|
||||
|
|
|
@ -3,9 +3,13 @@ package teammemberships
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
"github.com/portainer/portainer/api/kubernetes/cli"
|
||||
httperror "github.com/portainer/portainer/pkg/libhttp/error"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
@ -13,7 +17,8 @@ import (
|
|||
// Handler is the HTTP handler used to handle team membership operations.
|
||||
type Handler struct {
|
||||
*mux.Router
|
||||
DataStore dataservices.DataStore
|
||||
DataStore dataservices.DataStore
|
||||
K8sClientFactory *cli.ClientFactory
|
||||
}
|
||||
|
||||
// NewHandler creates a handler to manage team membership operations.
|
||||
|
@ -31,3 +36,27 @@ func NewHandler(bouncer security.BouncerService) *Handler {
|
|||
|
||||
return h
|
||||
}
|
||||
|
||||
func (handler *Handler) updateUserServiceAccounts(membership *portainer.TeamMembership) {
|
||||
endpoints, err := handler.DataStore.Endpoint().EndpointsByTeamID(membership.TeamID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("failed fetching environments for team %d", membership.TeamID)
|
||||
return
|
||||
}
|
||||
for _, endpoint := range endpoints {
|
||||
restrictDefaultNamespace := endpoint.Kubernetes.Configuration.RestrictDefaultNamespace
|
||||
// update kubernenets service accounts if the team is associated with a kubernetes environment
|
||||
if endpointutils.IsKubernetesEndpoint(&endpoint) {
|
||||
kubecli, err := handler.K8sClientFactory.GetKubeClient(&endpoint)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("failed getting kube client for environment %d", endpoint.ID)
|
||||
continue
|
||||
}
|
||||
teamIDs := []int{int(membership.TeamID)}
|
||||
err = kubecli.SetupUserServiceAccount(int(membership.UserID), teamIDs, restrictDefaultNamespace)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("failed setting-up service account for user %d", membership.UserID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,5 +91,7 @@ func (handler *Handler) teamMembershipCreate(w http.ResponseWriter, r *http.Requ
|
|||
return httperror.InternalServerError("Unable to persist team memberships inside the database", err)
|
||||
}
|
||||
|
||||
defer handler.updateUserServiceAccounts(membership)
|
||||
|
||||
return response.JSON(w, membership)
|
||||
}
|
||||
|
|
|
@ -52,5 +52,7 @@ func (handler *Handler) teamMembershipDelete(w http.ResponseWriter, r *http.Requ
|
|||
return httperror.InternalServerError("Unable to remove the team membership from the database", err)
|
||||
}
|
||||
|
||||
defer handler.updateUserServiceAccounts(membership)
|
||||
|
||||
return response.Empty(w)
|
||||
}
|
||||
|
|
|
@ -90,5 +90,7 @@ func (handler *Handler) teamMembershipUpdate(w http.ResponseWriter, r *http.Requ
|
|||
return httperror.InternalServerError("Unable to persist membership changes inside the database", err)
|
||||
}
|
||||
|
||||
defer handler.updateUserServiceAccounts(membership)
|
||||
|
||||
return response.JSON(w, membership)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue