1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-04 21:35:23 +02:00

fix(api): add an authenticated access policy to the websocket endpoint (#1979)

* fix(api): add an authenticated access policy to the websocket endpoint

* refactor(api): centralize EndpointAccess validation

* feat(api): validate id query parameter for the /websocket/exec endpoint
This commit is contained in:
Anthony Lapenna 2018-06-18 11:56:31 +02:00 committed by GitHub
parent f3ce5c25de
commit da5a430b8c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 100 additions and 124 deletions

View file

@ -14,13 +14,12 @@ import (
type Handler struct {
stackCreationMutex *sync.Mutex
stackDeletionMutex *sync.Mutex
requestBouncer *security.RequestBouncer
*mux.Router
FileService portainer.FileService
GitService portainer.GitService
StackService portainer.StackService
EndpointService portainer.EndpointService
EndpointGroupService portainer.EndpointGroupService
TeamMembershipService portainer.TeamMembershipService
ResourceControlService portainer.ResourceControlService
RegistryService portainer.RegistryService
DockerHubService portainer.DockerHubService
@ -34,6 +33,7 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler {
Router: mux.NewRouter(),
stackCreationMutex: &sync.Mutex{},
stackDeletionMutex: &sync.Mutex{},
requestBouncer: bouncer,
}
h.Handle("/stacks",
bouncer.RestrictedAccess(httperror.LoggerHandler(h.stackCreate))).Methods(http.MethodPost)
@ -49,21 +49,3 @@ func NewHandler(bouncer *security.RequestBouncer) *Handler {
bouncer.RestrictedAccess(httperror.LoggerHandler(h.stackFile))).Methods(http.MethodGet)
return h
}
func (handler *Handler) checkEndpointAccess(endpoint *portainer.Endpoint, userID portainer.UserID) error {
memberships, err := handler.TeamMembershipService.TeamMembershipsByUserID(userID)
if err != nil {
return err
}
group, err := handler.EndpointGroupService.EndpointGroup(endpoint.GroupID)
if err != nil {
return err
}
if !security.AuthorizedEndpointAccess(endpoint, group, userID, memberships) {
return portainer.ErrEndpointAccessDenied
}
return nil
}

View file

@ -7,7 +7,6 @@ import (
"github.com/portainer/portainer"
httperror "github.com/portainer/portainer/http/error"
"github.com/portainer/portainer/http/request"
"github.com/portainer/portainer/http/security"
)
func (handler *Handler) cleanUp(stack *portainer.Stack, doCleanUp *bool) error {
@ -47,18 +46,9 @@ func (handler *Handler) stackCreate(w http.ResponseWriter, r *http.Request) *htt
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find an endpoint with the specified identifier inside the database", err}
}
tokenData, err := security.RetrieveTokenData(r)
err = handler.requestBouncer.EndpointAccess(r, endpoint)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err}
}
if tokenData.Role != portainer.AdministratorRole {
err = handler.checkEndpointAccess(endpoint, tokenData.ID)
if err != nil && err == portainer.ErrEndpointAccessDenied {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access endpoint", portainer.ErrEndpointAccessDenied}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify permission to access endpoint", err}
}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access endpoint", portainer.ErrEndpointAccessDenied}
}
switch portainer.StackType(stackType) {

View file

@ -105,18 +105,9 @@ func (handler *Handler) deleteExternalStack(r *http.Request, w http.ResponseWrit
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to find the endpoint associated to the stack inside the database", err}
}
tokenData, err := security.RetrieveTokenData(r)
err = handler.requestBouncer.EndpointAccess(r, endpoint)
if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to retrieve user authentication token", err}
}
if tokenData.Role != portainer.AdministratorRole {
err = handler.checkEndpointAccess(endpoint, tokenData.ID)
if err != nil && err == portainer.ErrEndpointAccessDenied {
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access endpoint", portainer.ErrEndpointAccessDenied}
} else if err != nil {
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to verify permission to access endpoint", err}
}
return &httperror.HandlerError{http.StatusForbidden, "Permission denied to access endpoint", portainer.ErrEndpointAccessDenied}
}
stack = &portainer.Stack{