diff --git a/server/internal/api/api.go b/server/internal/api/api.go index 0e6ee04e..f72743b1 100644 --- a/server/internal/api/api.go +++ b/server/internal/api/api.go @@ -3,14 +3,11 @@ package api import ( "github.com/gin-gonic/gin" "github.com/shroff/phylum/server/internal/api/auth" - "github.com/shroff/phylum/server/internal/api/errors" "github.com/shroff/phylum/server/internal/api/routes" "github.com/shroff/phylum/server/internal/core" ) func Setup(r *gin.RouterGroup, a *core.App) { - r.Use(handleApiError) - // Unauthenticated routes routes.SetupAuthRoutes(r, a) @@ -18,16 +15,3 @@ func Setup(r *gin.RouterGroup, a *core.App) { r.Use(auth.CreateBearerAuthHandler(a)) routes.SetupResourceRoutes(r) } - -func handleApiError(c *gin.Context) { - defer func() { - if err := recover(); err != nil { - if e, ok := err.(*errors.Err); ok { - c.AbortWithStatusJSON(e.Status, e) - } else { - panic(err) - } - } - }() - c.Next() -} diff --git a/server/internal/api/auth/auth_bearer.go b/server/internal/api/auth/auth_bearer.go index 1551c5fd..60dbe38e 100644 --- a/server/internal/api/auth/auth_bearer.go +++ b/server/internal/api/auth/auth_bearer.go @@ -18,20 +18,20 @@ func CreateBearerAuthHandler(a *core.App) func(c *gin.Context) { ctx := c.Request.Context() authHeader := c.GetHeader("Authorization") if authHeader == "" { - panic(errors.Err{Status: 401, Code: errCodeAuthRequred}) + panic(errors.ApiErr{Status: 401, Code: errCodeAuthRequred}) } authParts := strings.Split(authHeader, " ") if len(authParts) != 2 { - panic(errors.Err{Status: 401, Code: errCodeAuthRequred}) + panic(errors.ApiErr{Status: 401, Code: errCodeAuthRequred}) } if authParts[0] != "bearer" { - panic(errors.Err{Status: 401, Code: errCodeAuthRequred}) + panic(errors.ApiErr{Status: 401, Code: errCodeAuthRequred}) } userID, err := a.VerifyAccessToken(ctx, authParts[1]) if err != nil { if errors.Is(err, core.ErrTokenExpired) || errors.Is(err, core.ErrTokenInvalid) { - panic(errors.Err{Status: 401, Code: errCodeTokenInvalid}) + panic(errors.ApiErr{Status: 401, Code: errCodeTokenInvalid}) } panic(err) } diff --git a/server/internal/api/errors/errors.go b/server/internal/api/errors/errors.go index 34a829c0..15f35db1 100644 --- a/server/internal/api/errors/errors.go +++ b/server/internal/api/errors/errors.go @@ -3,26 +3,41 @@ package errors import ( "errors" "fmt" + + "github.com/gin-gonic/gin" ) -type Err struct { +type ApiErr struct { Status int `json:"status"` Code string `json:"code"` Details string `json:"details"` } func New(httpStatus int, code, details string) error { - return &Err{ + return &ApiErr{ Status: httpStatus, Code: code, Details: details, } } -func (e *Err) Error() string { +func (e *ApiErr) Error() string { return fmt.Sprintf("%d %s (%s)", e.Status, e.Code, e.Details) } func Is(err, target error) bool { return errors.Is(err, target) } + +func RecoverApiError(c *gin.Context) { + defer func() { + if err := recover(); err != nil { + if e, ok := err.(*ApiErr); ok { + c.AbortWithStatusJSON(e.Status, e) + } else { + panic(err) + } + } + }() + c.Next() +} diff --git a/server/internal/command/appcmd/serve.go b/server/internal/command/appcmd/serve.go index 9dc432be..81a659fb 100644 --- a/server/internal/command/appcmd/serve.go +++ b/server/internal/command/appcmd/serve.go @@ -8,6 +8,7 @@ import ( "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "github.com/shroff/phylum/server/internal/api" + "github.com/shroff/phylum/server/internal/api/errors" "github.com/shroff/phylum/server/internal/core" "github.com/shroff/phylum/server/internal/webdav" "github.com/sirupsen/logrus" @@ -22,6 +23,7 @@ func setupServeCommand() *cobra.Command { Run: func(cmd *cobra.Command, args []string) { config := viper.GetViper() engine := createEngine(config.GetBool("log_body"), config.GetBool("cors_enabled"), config.GetStringSlice("cors_origins")) + engine.Use(errors.RecoverApiError) webdav.SetupHandler(engine.Group(config.GetString("webdav_prefix")), core.Default) diff --git a/server/internal/command/appcmd/user.go b/server/internal/command/appcmd/user.go index 50011a48..2f4023fe 100644 --- a/server/internal/command/appcmd/user.go +++ b/server/internal/command/appcmd/user.go @@ -85,7 +85,7 @@ func setupUserChrootCommand() *cobra.Command { logrus.Fatal(err) } else { var res core.Resource - if id, err := uuid.Parse(idOrPath); err != nil { + if id, err := uuid.Parse(idOrPath); err == nil { if res, err = core.Default.Rootfs.ResourceByID(id); err != nil { logrus.Fatal(err) } diff --git a/server/internal/webdav/auth_basic.go b/server/internal/webdav/auth_basic.go index a5ec369b..a63c61b7 100644 --- a/server/internal/webdav/auth_basic.go +++ b/server/internal/webdav/auth_basic.go @@ -14,6 +14,8 @@ const keyFileSystem = "filesystem" func createBasicAuthHandler(a *core.App) func(c *gin.Context) { return func(c *gin.Context) { if username, pass, ok := c.Request.BasicAuth(); !ok { + c.Header("WWW-Authenticate", "Basic realm=\"Phylum WebDAV\"") + c.AbortWithStatus(http.StatusUnauthorized) } else if user, err := a.VerifyUserPassword(c.Request.Context(), username, pass); err != nil { if errors.Is(err, core.ErrCredentialsInvalid) { c.Header("WWW-Authenticate", "Basic realm=\"Phylum WebDAV\"")