From 0d6031bec59cdb9d3d9b735ce99ed5249fa5651e Mon Sep 17 00:00:00 2001 From: Conrad Hoffmann Date: Thu, 5 Sep 2024 23:30:29 +0200 Subject: [PATCH] server: use routing groups Instead of hardcoding some exceptions in the auth middleware, use a different routing group for routes that do not require auth. Makes the auth middleware more generic and also removes a lot of unneccessary middleware processing from routes that don't need it. For now, the added group is not accessible from outside the module, but if the need arises, this might be an option. --- auth/middleware.go | 12 +----------- server/server.go | 35 ++++++++++++++++++++++------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/auth/middleware.go b/auth/middleware.go index 3ac7315c5beb67a8b0dc5e20b4876e0e9a3efd9f..3dded1bcf62c734e88de5ac6983d4457bea4c37c 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -17,7 +17,6 @@ import ( "sync/atomic" "time" - chimiddleware "github.com/go-chi/chi/v5/middleware" "github.com/vaughan0/go-ini" "github.com/vektah/gqlparser/v2/gqlerror" @@ -698,7 +697,7 @@ func WebhookAuth(ctx context.Context, auth *AuthContext, return context.WithValue(ctx, userCtxKey, &whAuth), nil } -func RequireMiddleware(conf ini.File, apiconf string) func(http.Handler) http.Handler { +func Middleware(conf ini.File, apiconf string) func(http.Handler) http.Handler { var internalNet []*net.IPNet src, ok := conf.Get(apiconf, "internal-ipnet") if !ok { @@ -764,15 +763,6 @@ func RequireMiddleware(conf ini.File, apiconf string) func(http.Handler) http.Ha } } -func Middleware(conf ini.File, apiconf string) func(http.Handler) http.Handler { - return chimiddleware.Maybe(RequireMiddleware(conf, apiconf), func(r *http.Request) bool { - return strings.HasPrefix(r.URL.Path, "/query") && - r.URL.Path != "/query/metrics" && - r.URL.Path != "/query/api-meta.json" && - !strings.HasPrefix(r.URL.Path, "/query/external/") - }) -} - func ForContext(ctx context.Context) *AuthContext { raw, ok := ctx.Value(userCtxKey).(*AuthContext) if !ok { diff --git a/server/server.go b/server/server.go index 725b546aea08b00d7fea49c5f547420f3e7bda99..cba8994b1be52d1ab07296516a322c5d976b906c 100644 --- a/server/server.go +++ b/server/server.go @@ -53,6 +53,7 @@ type Server struct { conf ini.File db *sql.DB redis *goRedis.Client + root chi.Router router chi.Router service string queues []*work.Queue @@ -63,9 +64,11 @@ type Server struct { // Creates a new common server context for a SourceHut GraphQL daemon. func NewServer(service string, conf ini.File) *Server { + root := chi.NewRouter() server := &Server{ conf: conf, - router: chi.NewRouter(), + root: root, + router: root.Group(func(_ chi.Router) {}), service: service, } return server @@ -105,19 +108,25 @@ func (server *Server) WithSchema( playground.Handler("GraphQL playground", "/query")) } server.router.Handle("/query", srv) - server.router.Handle("/query/metrics", promhttp.Handler()) - server.router.Get("/query/api-meta.json", func(w http.ResponseWriter, r *http.Request) { - info := struct { - Scopes []string `json:"scopes"` - }{scopes} - j, err := json.Marshal(&info) - if err != nil { - panic(err) - } + // These don't need auth or any other middleware - just log and process + server.root.Group(func(r chi.Router) { + r.Use(middleware.RealIP) + r.Use(middleware.Logger) + r.Handle("/query/metrics", promhttp.Handler()) + r.Get("/query/api-meta.json", func(w http.ResponseWriter, r *http.Request) { + info := struct { + Scopes []string `json:"scopes"` + }{scopes} + + j, err := json.Marshal(&info) + if err != nil { + panic(err) + } - w.Header().Add("Content-Type", "application/json") - w.Write(j) + w.Header().Add("Content-Type", "application/json") + w.Write(j) + }) }) return server } @@ -263,7 +272,7 @@ func (server *Server) Run() { panic(err) } log.Printf("Running on %s", config.Addr) - qserver := &http.Server{Handler: server.router} + qserver := &http.Server{Handler: server.root} go qserver.Serve(qlisten) mux := &http.ServeMux{}