From 19c91aff194accad9d45ea12be58209b674a0363 Mon Sep 17 00:00:00 2001 From: Julien Neuhart Date: Fri, 17 Jan 2025 14:08:01 +0100 Subject: [PATCH] feat(api): add root, favicon and version routes to basic auth middleware if enabled --- Makefile | 2 +- pkg/modules/api/api.go | 21 ++++++++++++++++----- pkg/modules/api/api_test.go | 3 +++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index ed69207c..de2e0dbd 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ API_BIND_IP= API_START_TIMEOUT=30s API_TIMEOUT=30s API_BODY_LIMIT= -API_ROOT_PATH=/ +API_ROOT_PATH="/" API_TRACE_HEADER=Gotenberg-Trace API_ENABLE_BASIC_AUTH=false GOTENBERG_API_BASIC_AUTH_USERNAME= diff --git a/pkg/modules/api/api.go b/pkg/modules/api/api.go index 4ec91d9f..e7aaf492 100644 --- a/pkg/modules/api/api.go +++ b/pkg/modules/api/api.go @@ -456,14 +456,22 @@ func (a *Api) Start() error { hardTimeout := a.timeout + (time.Duration(5) * time.Second) + // Basic auth? + var securityMiddleware echo.MiddlewareFunc + if a.basicAuthUsername != "" { + securityMiddleware = basicAuthMiddleware(a.basicAuthUsername, a.basicAuthPassword) + } else { + securityMiddleware = func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + return next(c) + } + } + } + // Add the modules' routes and their specific middlewares. for _, route := range a.routes { var middlewares []echo.MiddlewareFunc - - // Basic auth? - if a.basicAuthUsername != "" { - middlewares = append(middlewares, basicAuthMiddleware(a.basicAuthUsername, a.basicAuthPassword)) - } + middlewares = append(middlewares, securityMiddleware) if route.IsMultipart { middlewares = append(middlewares, contextMiddleware(a.fs, a.timeout, a.bodyLimit, a.downloadFromCfg)) @@ -489,6 +497,7 @@ func (a *Api) Start() error { func(c echo.Context) error { return c.HTML(http.StatusOK, `Hey, Gotenberg has no UI, it's an API. Head to the documentation to learn how to interact with it 🚀`) }, + securityMiddleware, ) // Favicon route. @@ -497,6 +506,7 @@ func (a *Api) Start() error { func(c echo.Context) error { return c.NoContent(http.StatusNoContent) }, + securityMiddleware, ) // Let's not forget the health check routes... @@ -525,6 +535,7 @@ func (a *Api) Start() error { func(c echo.Context) error { return c.String(http.StatusOK, gotenberg.Version) }, + securityMiddleware, ) // Wait for all modules to be ready. diff --git a/pkg/modules/api/api_test.go b/pkg/modules/api/api_test.go index 9a123176..cd5c3e3a 100644 --- a/pkg/modules/api/api_test.go +++ b/pkg/modules/api/api_test.go @@ -869,6 +869,7 @@ func TestApi_Start(t *testing.T) { // root request. recorder := httptest.NewRecorder() rootRequest := httptest.NewRequest(http.MethodGet, "/", nil) + rootRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) mod.srv.ServeHTTP(recorder, rootRequest) if recorder.Code != http.StatusOK { t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code) @@ -877,6 +878,7 @@ func TestApi_Start(t *testing.T) { // favicon request. recorder = httptest.NewRecorder() faviconRequest := httptest.NewRequest(http.MethodGet, "/favicon.ico", nil) + faviconRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) mod.srv.ServeHTTP(recorder, faviconRequest) if recorder.Code != http.StatusNoContent { t.Errorf("expected %d status code but got %d", http.StatusNoContent, recorder.Code) @@ -900,6 +902,7 @@ func TestApi_Start(t *testing.T) { // version request. recorder = httptest.NewRecorder() versionRequest := httptest.NewRequest(http.MethodGet, "/version", nil) + versionRequest.SetBasicAuth(mod.basicAuthUsername, mod.basicAuthPassword) mod.srv.ServeHTTP(recorder, versionRequest) if recorder.Code != http.StatusOK { t.Errorf("expected %d status code but got %d", http.StatusOK, recorder.Code)