diff --git a/auth/handlers/routes.go b/auth/handlers/routes.go index 94a3897e1..d1763e2f9 100644 --- a/auth/handlers/routes.go +++ b/auth/handlers/routes.go @@ -14,13 +14,6 @@ func (h *AuthHandlers) MountHttpRoutes(r chi.Router) { l = GetLinks() ) - r.Use(func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := actionlog.RequestOriginToContext(r.Context(), actionlog.RequestOrigin_Auth) - next.ServeHTTP(w, r.WithContext(ctx)) - }) - }) - if h.Opt.DevelopmentMode { r.Get("/auth/dev", h.handle(h.devView)) r.Get("/auth/dev/scenarios", h.devSceneView) @@ -28,6 +21,13 @@ func (h *AuthHandlers) MountHttpRoutes(r chi.Router) { r.Handle("/auth/", http.RedirectHandler("/auth", http.StatusSeeOther)) r.Group(func(r chi.Router) { + r.Use(func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := actionlog.RequestOriginToContext(r.Context(), actionlog.RequestOrigin_Auth) + next.ServeHTTP(w, r.WithContext(ctx)) + }) + }) + if h.Opt.RequestRateLimit > 0 { r.Use(httprate.LimitByIP(h.Opt.RequestRateLimit, h.Opt.RequestRateWindowLength)) // @todo make configurable } diff --git a/pkg/auth/middleware.go b/pkg/auth/middleware.go index 5a025f1e3..e7bef4ae4 100644 --- a/pkg/auth/middleware.go +++ b/pkg/auth/middleware.go @@ -1,8 +1,7 @@ package auth import ( - "errors" - "github.com/cortezaproject/corteza-server/pkg/api" + "github.com/cortezaproject/corteza-server/pkg/errors" "net/http" ) @@ -17,15 +16,13 @@ func AccessTokenCheck(scope ...string) func(http.Handler) http.Handler { for _, s := range scope { if !CheckScope(ctx.Value(scopeCtxKey{}), s) { - w.WriteHeader(http.StatusUnauthorized) - api.Send(w, r, errors.New("unauthorized scope")) + errors.ProperlyServeHTTP(w, r, errors.Unauthorized("unauthorized scope"), false) return } } if !GetIdentityFromContext(ctx).Valid() { - w.WriteHeader(http.StatusUnauthorized) - api.Send(w, r, errors.New("unauthorized")) + errors.ProperlyServeHTTP(w, r, errors.Unauthorized("unauthorized"), false) return } diff --git a/pkg/errors/http.go b/pkg/errors/http.go index a5f163c18..7e7554c75 100644 --- a/pkg/errors/http.go +++ b/pkg/errors/http.go @@ -12,23 +12,34 @@ import ( // ServeHTTP Prepares and encodes given error for HTTP transport // // mask arg hides extra/debug info +// +// Proper HTTP status codes are generally not used in the API due to compatibility issues +// This should be addressed in the future versions when/if we restructure the API func ServeHTTP(w http.ResponseWriter, r *http.Request, err error, mask bool) { + // due to backward compatibility, + // custom HTTP statuses are disabled for now. + serveHTTP(w, r, http.StatusOK, err, mask) +} + +// ProperlyServeHTTP Prepares and encodes given error for HTTP transport, same as ServeHTTP but with proper status codes +func ProperlyServeHTTP(w http.ResponseWriter, r *http.Request, err error, mask bool) { + var ( + code = http.StatusInternalServerError + ) + + if e, is := err.(*Error); is { + code = e.kind.httpStatus() + } + + serveHTTP(w, r, code, err, mask) +} + +func serveHTTP(w http.ResponseWriter, r *http.Request, code int, err error, mask bool) { var ( // Very naive approach on parsing accept headers acceptsJson = strings.Contains(r.Header.Get("accept"), "application/json") - - // due to backward compatibility, - // proper use of HTTP statuses is disabled for now. - code = http.StatusOK - //code = http.StatusInternalServerError ) - // due to backward compatibility, - // custom HTTP statuses are disabled for now. - //if e, is := err.(*Error); is { - // code = e.kind.httpStatus() - //} - if !mask && !acceptsJson { // Prettify error for plain text debug output w.Header().Set("Content-Type", "plain/text")