diff --git a/internal/api/guard/error.go b/internal/api/guard/error.go index bc86a31d8..5cf156aa5 100644 --- a/internal/api/guard/error.go +++ b/internal/api/guard/error.go @@ -12,45 +12,38 @@ import ( ) type notAuthenticatedError struct { - msg string -} - -func IsNotAuthenticatedError(err error) bool { - _, ok := err.(*notAuthenticatedError) - return ok -} - -func newNotAuthenticatedError(permission enum.Permission, resource *types.Resource) *notAuthenticatedError { - return ¬AuthenticatedError{ - msg: fmt.Sprintf("Operation %s on resource %v requires authentication.", permission, resource), - } + resource *types.Resource + permission enum.Permission } func (e *notAuthenticatedError) Error() string { - return e.msg + return fmt.Sprintf("Operation %s on resource %v requires authentication.", e.permission, e.resource) } -type notAuthorizedError struct { - msg string -} - -func IsNotAuthorizedError(err error) bool { - _, ok := err.(*notAuthorizedError) +func (e *notAuthenticatedError) Is(target error) bool { + _, ok := target.(*notAuthenticatedError) return ok } -func newNotAuthorizedError(user *types.User, scope *types.Scope, resource *types.Resource, permission enum.Permission) *notAuthorizedError { - return ¬AuthorizedError{ - msg: fmt.Sprintf( - "User '%s' (%s) is not authorized to execute %s on resource %v in scope %v.", - user.Name, - user.Email, - permission, - resource, - scope), - } +type notAuthorizedError struct { + user *types.User + scope *types.Scope + resource *types.Resource + permission enum.Permission } func (e *notAuthorizedError) Error() string { - return e.msg + // ASSUMPTION: user is never nil at this point (type is not exported) + return fmt.Sprintf( + "User '%s' (%s) is not authorized to execute %s on resource %v in scope %v.", + e.user.Name, + e.user.Email, + e.permission, + e.resource, + e.scope) +} + +func (e *notAuthorizedError) Is(target error) bool { + _, ok := target.(*notAuthorizedError) + return ok } diff --git a/internal/api/guard/guard.go b/internal/api/guard/guard.go index fe518820b..3143db64a 100644 --- a/internal/api/guard/guard.go +++ b/internal/api/guard/guard.go @@ -68,9 +68,9 @@ func (g *Guard) EnforceAuthenticated(next http.Handler) http.Handler { func (g *Guard) Enforce(w http.ResponseWriter, r *http.Request, scope *types.Scope, resource *types.Resource, permission enum.Permission) bool { err := g.Check(r, scope, resource, permission) - if IsNotAuthenticatedError(err) { + if errors.Is(err, ¬AuthenticatedError{}) { render.Unauthorized(w, err) - } else if IsNotAuthorizedError(err) { + } else if errors.Is(err, ¬AuthorizedError{}) { render.Forbidden(w, err) } else if err != nil { render.InternalError(w, err) @@ -87,7 +87,7 @@ func (g *Guard) Enforce(w http.ResponseWriter, r *http.Request, scope *types.Sco func (g *Guard) Check(r *http.Request, scope *types.Scope, resource *types.Resource, permission enum.Permission) error { u, present := request.UserFrom(r.Context()) if !present { - return newNotAuthenticatedError(permission, resource) + return ¬AuthenticatedError{resource, permission} } // TODO: don't hardcode principal type USER @@ -102,7 +102,7 @@ func (g *Guard) Check(r *http.Request, scope *types.Scope, resource *types.Resou } if !authorized { - return newNotAuthorizedError(u, scope, resource, permission) + return ¬AuthorizedError{u, scope, resource, permission} } return nil