From bf98a0971ffb1b93efa6aa711c1d4ad19a64cc69 Mon Sep 17 00:00:00 2001 From: jay brown Date: Tue, 15 Apr 2025 12:04:54 -0700 Subject: [PATCH] auth fixes middleware handles logout --- api/queryAPI/authHandlers.go | 17 +++++++++++------ internal/cognitoauth/auth.go | 21 +++++++++++++-------- internal/cognitoauth/handler.go | 15 --------------- internal/cognitoauth/middleware.go | 12 ++++++++++++ internal/server/api/listener.go | 23 +++++++++++++++++++++++ 5 files changed, 59 insertions(+), 29 deletions(-) diff --git a/api/queryAPI/authHandlers.go b/api/queryAPI/authHandlers.go index af9e095f..99599ece 100644 --- a/api/queryAPI/authHandlers.go +++ b/api/queryAPI/authHandlers.go @@ -6,6 +6,9 @@ import ( "github.com/labstack/echo/v4" ) +// All of the auth related handlers that are called from the +// generated swagger code. + func (s *Controllers) Login(ctx echo.Context) error { // Redirect to Cognito login page // This is a placeholder implementation - you'll need to implement the actual Cognito redirect logic @@ -16,15 +19,17 @@ func (s *Controllers) Login(ctx echo.Context) error { func (s *Controllers) LoginCallback(ctx echo.Context, params LoginCallbackParams) error { // Handle OAuth2 callback // This is a placeholder implementation - you'll need to implement the actual token exchange logic - redirectURL := "https://doczy.com" // Replace with your actual redirect URL - return ctx.Redirect(http.StatusFound, redirectURL) + //redirectURL := "https://doczy.com" // Replace with your actual redirect URL + //return ctx.Redirect(http.StatusFound, redirectURL) + return ctx.JSON(http.StatusOK, map[string]string{"message": "Login callback is a no op since its handled by the middleware."}) } +// Logout is called by the swagger generated code for the logout endpoint. func (s *Controllers) Logout(ctx echo.Context) error { - // Handle logout - // This is a placeholder implementation - you'll need to implement the actual logout logic - logoutURL := "https://doczy.auth.us-east-1.amazoncognito.com/logout" - return ctx.Redirect(http.StatusFound, logoutURL) + // the middleware will have already removed the auth cookie + // so we can just redirect to the home page after logging out. + return ctx.Redirect(http.StatusFound, "/home") + } func (s *Controllers) GetHomePage(ctx echo.Context) error { diff --git a/internal/cognitoauth/auth.go b/internal/cognitoauth/auth.go index 96ae60ad..c675e868 100644 --- a/internal/cognitoauth/auth.go +++ b/internal/cognitoauth/auth.go @@ -17,8 +17,10 @@ import ( // RegisterRoutes registers all authentication-related routes to the Echo engine func RegisterRoutes(e *echo.Echo, config auth.ConfigProvider) { // check the auth feature flag + fmt.Println("Registering routes for Auth.") disableAuth := os.Getenv("DISABLE_AUTH") if strings.ToLower(disableAuth) == "true" { + fmt.Println("Auth is disabled. Skipping auth routes.") return // Do nothing if auth is not enabled } @@ -45,15 +47,16 @@ func RegisterRoutes(e *echo.Echo, config auth.ConfigProvider) { }) }) - // Register logout route - e.GET(config.GetAuthLogoutPath(), func(c echo.Context) error { - return LogoutHandler(c, config) - }) + //fmt.Printf("registering logoutpath: %s \v", config.GetAuthLogoutPath()) + //// Register logout route + //e.GET(config.GetAuthLogoutPath(), func(c echo.Context) error { + // return LogoutHandler(c) + //}) - // Default home page handler if requested - e.GET(config.GetAuthHomePath(), func(c echo.Context) error { - return HomeHandler(c, config) - }) + //// Default home page handler if requested + //e.GET(config.GetAuthHomePath(), func(c echo.Context) error { + // return HomeHandler(c, config) + //}) // Apply the JWT Auth middleware first e.Use(JWTAuthMiddleware(config)) @@ -65,6 +68,8 @@ func RegisterRoutes(e *echo.Echo, config auth.ConfigProvider) { // HomeHandler implements a simple home page that shows auth status and available endpoints func HomeHandler(c echo.Context, config auth.ConfigProvider) error { // Create a list of all registered routes + println("HomeHandler called.") + var endpoints []string // Add the auth routes diff --git a/internal/cognitoauth/handler.go b/internal/cognitoauth/handler.go index a37b7cb1..0d7d1c3c 100644 --- a/internal/cognitoauth/handler.go +++ b/internal/cognitoauth/handler.go @@ -229,18 +229,3 @@ func handleOAuthCallback(c echo.Context, config auth.ConfigProvider) error { // Redirect to home page return c.Redirect(http.StatusFound, config.GetAuthHomePath()) } - -// LogoutHandler handles the logout process by clearing the auth cookie -func LogoutHandler(c echo.Context, config auth.ConfigProvider) error { - // Clear the token cookie - cookie := new(http.Cookie) - cookie.Name = "auth_token" - cookie.Value = "" - cookie.Path = "/" - cookie.Expires = time.Now().Add(-1 * time.Hour) // Set expiry in the past - cookie.HttpOnly = true - c.SetCookie(cookie) - - // Redirect to home page - return c.Redirect(http.StatusFound, config.GetAuthHomePath()) -} diff --git a/internal/cognitoauth/middleware.go b/internal/cognitoauth/middleware.go index 3c4dc277..f9bf3675 100644 --- a/internal/cognitoauth/middleware.go +++ b/internal/cognitoauth/middleware.go @@ -2,6 +2,7 @@ package cognitoauth import ( "net/http" + "time" "queryorchestration/internal/serviceconfig/auth" @@ -117,6 +118,17 @@ func JWTAuthMiddleware(config auth.ConfigProvider) echo.MiddlewareFunc { return next(c) } + // if logout then remove the auth cookie + if c.Path() == config.GetAuthLogoutPath() { + cookie := new(http.Cookie) + cookie.Name = "auth_token" + cookie.Value = "" + cookie.Path = "/" + cookie.Expires = time.Now().Add(-1 * time.Hour) // Set expiry in the past + cookie.HttpOnly = true + c.SetCookie(cookie) + } + // Skip for home and logout as they should be accessible without auth if c.Path() == config.GetAuthHomePath() || c.Path() == config.GetAuthLogoutPath() { return next(c) diff --git a/internal/server/api/listener.go b/internal/server/api/listener.go index 6045d7ae..a1b713b4 100644 --- a/internal/server/api/listener.go +++ b/internal/server/api/listener.go @@ -23,6 +23,8 @@ import ( echoSwagger "github.com/swaggo/echo-swagger" ) +const configContextKey = "config" + type Config interface { server.Config SetRouter(*echo.Echo) @@ -37,6 +39,18 @@ type BaseConfig struct { Router *echo.Echo } +// GetConfigFromContext returns the config from the context. +// experimental since it is not used yet and may pose cylical dependency issues +// in handlers that are called by the generated +// swagger code. This needs to be verified. +func GetConfigFromContext(ctx echo.Context) (Config, error) { + cfg, ok := ctx.Get(configContextKey).(Config) + if !ok { + return nil, errors.New("config not found in context") + } + return cfg, nil +} + func (c *BaseConfig) SetRouter(e *echo.Echo) { c.Router = e } @@ -188,6 +202,15 @@ func New(ctx context.Context, cfg Config) (*Server, error) { cognitoauth.RegisterRoutes(cfg.GetRouter(), cfg) // auth end + // Add config middleware before other middleware + // so that the config is available to all middleware and handlers. + e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + c.Set(string(configContextKey), cfg) + return next(c) + } + }) + e.Use(echoprometheus.NewMiddleware("echo")) e.GET("/metrics", echoprometheus.NewHandler())