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

refactor(errors): reorganize errors (#3938)

* refactor(bolt): move ErrObjectNotFound to bolt

* refactor(http): move ErrUnauthorized to http package

* refactor(http): move ErrResourceAccessDenied to http errors

* refactor(http): move security errors to package

* refactor(users): move user errors to users package

* refactor(errors): move single errors to their package

* refactor(schedules): move schedule error to package

* refactor(http): move endpoint error to http package

* refactor(docker): move docker errors to package

* refactor(filesystem): move filesystem errors to package

* refactor(errors): remove portainer.Error

* style(chisel): reorder imports

* fix(stacks): remove portainer.Error
This commit is contained in:
Chaim Lev-Ari 2020-07-08 00:57:52 +03:00 committed by GitHub
parent e82833a363
commit db4a5292be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
121 changed files with 550 additions and 477 deletions

View file

@ -2,12 +2,13 @@ package security
import (
"errors"
"net/http"
"strings"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/portainer/api"
"net/http"
"strings"
bolterrors "github.com/portainer/portainer/api/bolt/errors"
httperrors "github.com/portainer/portainer/api/http/errors"
)
type (
@ -110,13 +111,13 @@ func (bouncer *RequestBouncer) AuthorizedEndpointOperation(r *http.Request, endp
}
if !authorizedEndpointAccess(endpoint, group, tokenData.ID, memberships) {
return portainer.ErrEndpointAccessDenied
return httperrors.ErrEndpointAccessDenied
}
if authorizationCheck {
err = bouncer.checkEndpointOperationAuthorization(r, endpoint)
if err != nil {
return portainer.ErrAuthorizationRequired
return ErrAuthorizationRequired
}
}
@ -152,7 +153,7 @@ func (bouncer *RequestBouncer) checkEndpointOperationAuthorization(r *http.Reque
}
extension, err := bouncer.dataStore.Extension().Extension(portainer.RBACExtension)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
return nil
} else if err != nil {
return err
@ -192,7 +193,7 @@ func (bouncer *RequestBouncer) RegistryAccess(r *http.Request, registry *portain
}
if !AuthorizedRegistryAccess(registry, tokenData.ID, memberships) {
return portainer.ErrEndpointAccessDenied
return httperrors.ErrEndpointAccessDenied
}
return nil
@ -213,7 +214,7 @@ func (bouncer *RequestBouncer) mwCheckPortainerAuthorizations(next http.Handler,
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tokenData, err := RetrieveTokenData(r)
if err != nil {
httperror.WriteError(w, http.StatusForbidden, "Access denied", portainer.ErrUnauthorized)
httperror.WriteError(w, http.StatusForbidden, "Access denied", httperrors.ErrUnauthorized)
return
}
@ -223,9 +224,9 @@ func (bouncer *RequestBouncer) mwCheckPortainerAuthorizations(next http.Handler,
}
extension, err := bouncer.dataStore.Extension().Extension(portainer.RBACExtension)
if err == portainer.ErrObjectNotFound {
if err == bolterrors.ErrObjectNotFound {
if administratorOnly {
httperror.WriteError(w, http.StatusForbidden, "Access denied", portainer.ErrUnauthorized)
httperror.WriteError(w, http.StatusForbidden, "Access denied", httperrors.ErrUnauthorized)
return
}
@ -237,8 +238,8 @@ func (bouncer *RequestBouncer) mwCheckPortainerAuthorizations(next http.Handler,
}
user, err := bouncer.dataStore.User().User(tokenData.ID)
if err != nil && err == portainer.ErrObjectNotFound {
httperror.WriteError(w, http.StatusUnauthorized, "Unauthorized", portainer.ErrUnauthorized)
if err != nil && err == bolterrors.ErrObjectNotFound {
httperror.WriteError(w, http.StatusUnauthorized, "Unauthorized", httperrors.ErrUnauthorized)
return
} else if err != nil {
httperror.WriteError(w, http.StatusInternalServerError, "Unable to retrieve user details from the database", err)
@ -254,7 +255,7 @@ func (bouncer *RequestBouncer) mwCheckPortainerAuthorizations(next http.Handler,
bouncer.rbacExtensionClient.setLicenseKey(extension.License.LicenseKey)
err = bouncer.rbacExtensionClient.checkAuthorization(apiOperation)
if err != nil {
httperror.WriteError(w, http.StatusForbidden, "Access denied", portainer.ErrAuthorizationRequired)
httperror.WriteError(w, http.StatusForbidden, "Access denied", ErrAuthorizationRequired)
return
}
@ -268,7 +269,7 @@ func (bouncer *RequestBouncer) mwUpgradeToRestrictedRequest(next http.Handler) h
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tokenData, err := RetrieveTokenData(r)
if err != nil {
httperror.WriteError(w, http.StatusForbidden, "Access denied", portainer.ErrResourceAccessDenied)
httperror.WriteError(w, http.StatusForbidden, "Access denied", httperrors.ErrResourceAccessDenied)
return
}
@ -301,7 +302,7 @@ func (bouncer *RequestBouncer) mwCheckAuthentication(next http.Handler) http.Han
}
if token == "" {
httperror.WriteError(w, http.StatusUnauthorized, "Unauthorized", portainer.ErrUnauthorized)
httperror.WriteError(w, http.StatusUnauthorized, "Unauthorized", httperrors.ErrUnauthorized)
return
}
@ -313,8 +314,8 @@ func (bouncer *RequestBouncer) mwCheckAuthentication(next http.Handler) http.Han
}
_, err = bouncer.dataStore.User().User(tokenData.ID)
if err != nil && err == portainer.ErrObjectNotFound {
httperror.WriteError(w, http.StatusUnauthorized, "Unauthorized", portainer.ErrUnauthorized)
if err != nil && err == bolterrors.ErrObjectNotFound {
httperror.WriteError(w, http.StatusUnauthorized, "Unauthorized", httperrors.ErrUnauthorized)
return
} else if err != nil {
httperror.WriteError(w, http.StatusInternalServerError, "Unable to retrieve user details from the database", err)

View file

@ -2,6 +2,7 @@ package security
import (
"context"
"errors"
"net/http"
"github.com/portainer/portainer/api"
@ -25,7 +26,7 @@ func storeTokenData(request *http.Request, tokenData *portainer.TokenData) conte
func RetrieveTokenData(request *http.Request) (*portainer.TokenData, error) {
contextData := request.Context().Value(contextAuthenticationKey)
if contextData == nil {
return nil, portainer.ErrMissingContextData
return nil, errors.New("Unable to find JWT data in request context")
}
tokenData := contextData.(*portainer.TokenData)
@ -42,7 +43,7 @@ func storeRestrictedRequestContext(request *http.Request, requestContext *Restri
func RetrieveRestrictedRequestContext(request *http.Request) (*RestrictedRequestContext, error) {
contextData := request.Context().Value(contextRestrictedRequest)
if contextData == nil {
return nil, portainer.ErrMissingSecurityContext
return nil, errors.New("Unable to find security details in request context")
}
requestContext := contextData.(*RestrictedRequestContext)

View file

@ -0,0 +1,7 @@
package security
import "errors"
var (
ErrAuthorizationRequired = errors.New("Authorization required for this operation")
)

View file

@ -7,7 +7,7 @@ import (
"github.com/g07cha/defender"
httperror "github.com/portainer/libhttp/error"
"github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/http/errors"
)
// RateLimiter represents an entity that manages request rate limiting
@ -30,7 +30,7 @@ func (limiter *RateLimiter) LimitAccess(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ip := StripAddrPort(r.RemoteAddr)
if banned := limiter.Inc(ip); banned == true {
httperror.WriteError(w, http.StatusForbidden, "Access denied", portainer.ErrResourceAccessDenied)
httperror.WriteError(w, http.StatusForbidden, "Access denied", errors.ErrResourceAccessDenied)
return
}
next.ServeHTTP(w, r)

View file

@ -52,7 +52,7 @@ func (client *rbacExtensionClient) checkAuthorization(authRequest *portainer.API
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
return portainer.ErrAuthorizationRequired
return ErrAuthorizationRequired
}
return nil