diff --git a/hwsauth/authenticator.go b/hwsauth/authenticator.go index 3d1a5dd..d88203d 100644 --- a/hwsauth/authenticator.go +++ b/hwsauth/authenticator.go @@ -9,6 +9,7 @@ import ( "git.haelnorr.com/h/golib/hlog" "git.haelnorr.com/h/golib/hws" "git.haelnorr.com/h/golib/jwt" + "github.com/gobwas/glob" "github.com/pkg/errors" ) @@ -16,7 +17,7 @@ type Authenticator[T Model, TX DBTransaction] struct { tokenGenerator *jwt.TokenGenerator load LoadFunc[T, TX] beginTx BeginTX - ignoredPaths []string + ignoredPaths []glob.Glob logger *hlog.Logger server *hws.Server errorPage hws.ErrorPageFunc diff --git a/hwsauth/go.mod b/hwsauth/go.mod index 2142c93..3cb438d 100644 --- a/hwsauth/go.mod +++ b/hwsauth/go.mod @@ -16,6 +16,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.3 // indirect + github.com/gobwas/glob v0.2.3 github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/google/uuid v1.6.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect diff --git a/hwsauth/go.sum b/hwsauth/go.sum index bc0fdef..a60e947 100644 --- a/hwsauth/go.sum +++ b/hwsauth/go.sum @@ -15,6 +15,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= diff --git a/hwsauth/ignorepaths.go b/hwsauth/ignorepaths.go index cd00fe3..e01b8bc 100644 --- a/hwsauth/ignorepaths.go +++ b/hwsauth/ignorepaths.go @@ -3,6 +3,8 @@ package hwsauth import ( "fmt" "net/url" + + "github.com/gobwas/glob" ) // IgnorePaths excludes specified paths from authentication middleware. @@ -25,6 +27,19 @@ func (auth *Authenticator[T, TX]) IgnorePaths(paths ...string) error { return fmt.Errorf("Invalid path: '%s'", path) } } - auth.ignoredPaths = paths + auth.ignoredPaths = prepareGlobs(paths) return nil } + +func prepareGlobs(paths []string) []glob.Glob { + compiledGlobs := make([]glob.Glob, 0, len(paths)) + for _, pattern := range paths { + g, err := glob.Compile(pattern) + if err != nil { + // If pattern fails to compile, skip it + continue + } + compiledGlobs = append(compiledGlobs, g) + } + return compiledGlobs +} diff --git a/hwsauth/middleware.go b/hwsauth/middleware.go index 5a87892..c576654 100644 --- a/hwsauth/middleware.go +++ b/hwsauth/middleware.go @@ -3,10 +3,10 @@ package hwsauth import ( "context" "net/http" - "slices" "time" "git.haelnorr.com/h/golib/hws" + "github.com/gobwas/glob" "github.com/pkg/errors" ) @@ -23,7 +23,7 @@ func (auth *Authenticator[T, TX]) Authenticate() hws.Middleware { func (auth *Authenticator[T, TX]) authenticate() hws.MiddlewareFunc { return func(w http.ResponseWriter, r *http.Request) (*http.Request, *hws.HWSError) { - if slices.Contains(auth.ignoredPaths, r.URL.Path) { + if globTest(r.URL.Path, auth.ignoredPaths) { return r, nil } ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) @@ -38,6 +38,7 @@ func (auth *Authenticator[T, TX]) authenticate() hws.MiddlewareFunc { Error: errors.Wrap(err, "auth.beginTx"), } } + defer tx.Rollback() // Type assert to TX - safe because user's beginTx should return their TX type txTyped, ok := tx.(TX) if !ok { @@ -49,7 +50,14 @@ func (auth *Authenticator[T, TX]) authenticate() hws.MiddlewareFunc { } model, err := auth.getAuthenticatedUser(txTyped, w, r) if err != nil { - tx.Rollback() + rberr := tx.Rollback() + if rberr != nil { + return nil, &hws.HWSError{ + Message: "Failed rolling back after error", + StatusCode: http.StatusInternalServerError, + Error: errors.Wrap(err, "tx.Rollback"), + } + } auth.logger.Debug(). Str("remote_addr", r.RemoteAddr). Err(err). @@ -62,3 +70,12 @@ func (auth *Authenticator[T, TX]) authenticate() hws.MiddlewareFunc { return newReq, nil } } + +func globTest(testPath string, globs []glob.Glob) bool { + for _, g := range globs { + if g.Match(testPath) { + return true + } + } + return false +}