Skip to content

Commit

Permalink
wrap errors for easier handling in external services (#221)
Browse files Browse the repository at this point in the history
Services wanting to check if the error returned was an auth error or
some other error could get a number of auth related errors.

This wraps the permissions and auth errors into easily comparable root
errors for easier checks.

Additionally this corrects the incorrectly returned echo errors which
were missing for PermissionDenied errors which resulted in 500 errors.

Signed-off-by: Mike Mason <[email protected]>
  • Loading branch information
mikemrm authored Mar 15, 2024
1 parent b57c0b4 commit 97f201e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
26 changes: 20 additions & 6 deletions pkg/permissions/errors.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
package permissions

import "errors"
import (
"errors"
"fmt"

"github.com/labstack/echo/v4"
)

var (
// Error is the root error for all permissions related errors.
Error = errors.New("permissions error")

// AuthError is the root error all auth related errors stem from.
AuthError = fmt.Errorf("%w: auth", Error) //nolint:revive,stylecheck // not returned directly, but used as a root error.

// ErrNoAuthToken is the error returned when there is no auth token provided for the API request
ErrNoAuthToken = errors.New("no auth token provided for client")
ErrNoAuthToken = echo.ErrBadRequest.WithInternal(fmt.Errorf("%w: no auth token provided for client", AuthError))

// ErrInvalidAuthToken is the error returned when the auth token is not the expected value
ErrInvalidAuthToken = errors.New("invalid auth token")
ErrInvalidAuthToken = echo.ErrBadRequest.WithInternal(fmt.Errorf("%w: invalid auth token", AuthError))

// ErrPermissionDenied is the error returned when permission is denied to a call
ErrPermissionDenied = errors.New("subject doesn't have access")
ErrPermissionDenied = echo.ErrUnauthorized.WithInternal(fmt.Errorf("%w: subject doesn't have access", AuthError))

// ErrBadResponse is the error returned when we receive a bad response from the server
ErrBadResponse = errors.New("bad response from server")
ErrBadResponse = fmt.Errorf("%w: bad response from server", Error)

// ErrCheckerNotFound is the error returned when CheckAccess does not find the appropriate checker context
ErrCheckerNotFound = errors.New("no checker found in context")
ErrCheckerNotFound = fmt.Errorf("%w: no checker found in context", Error)

// ErrPermissionsMiddlewareMissing is returned when a permissions method has been called but the middleware is missing.
ErrPermissionsMiddlewareMissing = fmt.Errorf("%w: permissions middleware missing", Error)
)
9 changes: 3 additions & 6 deletions pkg/permissions/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ var (
}

tracer = otel.GetTracerProvider().Tracer("go.infratographer.com/permissions-api/pkg/permissions")

// ErrPermissionsMiddlewareMissing is returned when a permissions method has been called but the middleware is missing.
ErrPermissionsMiddlewareMissing = errors.New("permissions middleware missing")
)

// Permissions handles supporting authorization checks
Expand Down Expand Up @@ -71,17 +68,17 @@ func (p *Permissions) Middleware() echo.MiddlewareFunc {

actor := echojwtx.Actor(c)
if actor == "" {
return echo.ErrUnauthorized.WithInternal(ErrNoAuthToken)
return ErrNoAuthToken
}

authHeader := strings.TrimSpace(c.Request().Header.Get(echo.HeaderAuthorization))

if len(authHeader) <= len(bearerPrefix) {
return echo.ErrUnauthorized.WithInternal(ErrInvalidAuthToken)
return ErrInvalidAuthToken
}

if !strings.EqualFold(authHeader[:len(bearerPrefix)], bearerPrefix) {
return echo.ErrUnauthorized.WithInternal(ErrInvalidAuthToken)
return ErrInvalidAuthToken
}

token := authHeader[len(bearerPrefix):]
Expand Down

0 comments on commit 97f201e

Please sign in to comment.