Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wrap errors for easier handling in external services #221

Merged
merged 1 commit into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrapping these makes sense, but is this the right place for it? The permissions client and Echo middleware aren't really the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrNoAuthToken is only used by the echo middleware portion of this package.

Not all errors are wrapped in echo errors, such as ErrPermissionsMiddlewareMissing is used with events.

Echo already handles errors which are not echo http errors as 500 by default, so I only wrapped errors which we return in the echo middleware which we want something other than a 500 for.


// 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
Loading