diff --git a/cmd/queryAPI/main.go b/cmd/queryAPI/main.go index 3a825688..4fc7a5c2 100644 --- a/cmd/queryAPI/main.go +++ b/cmd/queryAPI/main.go @@ -94,9 +94,9 @@ func main() { return swagger, nil } - // Both of these operations (InitializeConfig and InitializeAuthProvider) - // would be better off in the service.new but there are code dependencies - // that make this not possible right now without significant refactoring. + // Both of these operations (InitializeConfig and InitializeAuthConfig) + // would be better off in one function but since there are services + // that need the config but do not use auth we will keep them separate for now. // This must be done before the rbac.InitializeAuthProvider errInitializingConfig := serviceconfig.InitializeConfig(cfg) @@ -106,10 +106,9 @@ func main() { } // Authentication specific config. - // This may move to another function after refactoring is done. - // replace the path here with value from ENV - baseUrl := "http://localhost:8080" - errorInitializingAuthConfig := cfg.InitializeAuthConfig(baseUrl, cfg.GetLogger()) + cfg.BaseURL = fmt.Sprintf("%s:%d", cfg.BaseURL, cfg.Port) + errorInitializingAuthConfig := cfg.InitializeAuthConfig(cfg.BaseURL, cfg.GetLogger()) + fmt.Printf("base url after InitializeAuthConfig: %s\n", cfg.BaseURL) // join initErr with errorInitializingAuthConfig if errorInitializingAuthConfig != nil { slog.Error(errorInitializingAuthConfig.Error()) diff --git a/internal/serviceconfig/auth/config.go b/internal/serviceconfig/auth/config.go index 7d9206b9..c46e674a 100644 --- a/internal/serviceconfig/auth/config.go +++ b/internal/serviceconfig/auth/config.go @@ -2,11 +2,12 @@ package auth import ( "fmt" - "log" "log/slog" "os" "reflect" "strings" + + "github.com/caarlos0/env/v11" ) // CognitoConfig holds the configuration for AWS Cognito @@ -18,15 +19,16 @@ type CognitoConfig struct { AuthClientSecret string `env:"COGNITO_CLIENT_SECRET,required,notEmpty"` AuthDomain string `env:"COGNITO_DOMAIN,required,notEmpty"` AuthClientID string `env:"COGNITO_CLIENT_ID,required,notEmpty"` + DisableAuth string `env:"DISABLE_AUTH" envDefault:"false"` AuthRedirectURI string // URL where Cognito redirects after authentication AuthTokenURL string // Cognito endpoint for token operations AuthJwksURL string // URL for JSON Web Key Set (for token verification) AuthURL string // Cognito authorization endpoint for initiating login - AuthLoginPath string // Path for initiating login - AuthCallbackPath string // Path for OAuth callback - AuthHomePath string // Path for home page - AuthLogoutPath string // Path for logout + AuthLoginPath string `env:"COGNITO_LOGIN_PATH" envDefault:"/login"` + AuthCallbackPath string `env:"COGNITO_CALLBACK_PATH" envDefault:"/login-callback"` + AuthHomePath string `env:"COGNITO_HOME_PATH" envDefault:"/home"` + AuthLogoutPath string `env:"COGNITO_LOGOUT_PATH" envDefault:"/logout"` AuthLogger *slog.Logger // Logger instance ( normally just the same logger as main) AuthRoutePermissions map[string][]string // Map of routes to required permissions } @@ -76,6 +78,7 @@ type ConfigProvider interface { // Returns an error if initialization fails, nil otherwise. func (c *CognitoConfig) InitializeAuthConfig(baseURL string, logger *slog.Logger) error { tempConfig := InitializeConfig(baseURL, logger) + //fmt.Printf("base url after InitializeAuthConfig: %s\n", tempConfig.) if tempConfig == nil { return fmt.Errorf("could not initialize auth config") } @@ -92,7 +95,7 @@ func (c *CognitoConfig) InitializeAuthConfig(baseURL string, logger *slog.Logger dstField.Set(srcField) } } - + return nil } @@ -100,7 +103,8 @@ func (c *CognitoConfig) InitializeAuthConfig(baseURL string, logger *slog.Logger // and sets the values that are computed from other values and // sets all default values for fields that will infrequently change. func InitializeConfig(baseURL string, logger *slog.Logger) *CognitoConfig { - // Set default logger if not provided + + // Set default logger to text slog if not provided if logger == nil { var logLevel slog.Level if os.Getenv("DEBUG") == "true" { @@ -115,76 +119,28 @@ func InitializeConfig(baseURL string, logger *slog.Logger) *CognitoConfig { logger = slog.New(logHandler) } - // Set paths with defaults - loginPath := os.Getenv("COGNITO_LOGIN_PATH") - if loginPath == "" { - loginPath = "/login" - } - - callbackPath := os.Getenv("COGNITO_CALLBACK_PATH") - if callbackPath == "" { - callbackPath = "/login-callback" - } - - homePath := os.Getenv("COGNITO_HOME_PATH") - if homePath == "" { - homePath = "/home" - } - - logoutPath := os.Getenv("COGNITO_LOGOUT_PATH") - if logoutPath == "" { - logoutPath = "/logout" - } - - // Get AWS region with fallback - region := os.Getenv("AWS_REGION") - if region == "" { - region = "us-east-2" // Fallback to default value - } - - // Get User Pool ID with fallback - userPoolID := os.Getenv("COGNITO_USER_POOL_ID") - if userPoolID == "" { - userPoolID = "" // No default, will need to be provided - logger.Warn("COGNITO_USER_POOL_ID environment variable is not set") - } - - // Get Cognito domain - domain := os.Getenv("COGNITO_DOMAIN") - if domain == "" { - //logger.Warn("COGNITO_DOMAIN environment variable is not set, using default") - //// Use the user pool ID directly as part of the domain - //domain = fmt.Sprintf("%s.auth.%s.amazoncognito.com", userPoolID, region) - log.Fatalf("COGNITO_DOMAIN environment variable is not set") - } - - // Ensure domain format is correct (no protocol prefix) - domain = strings.TrimPrefix(domain, "https://") - domain = strings.TrimPrefix(domain, "http://") - // Sanitize base URL (remove trailing slash) baseURL = strings.TrimSuffix(baseURL, "/") - config := &CognitoConfig{ - AuthClientID: os.Getenv("COGNITO_CLIENT_ID"), - AuthClientSecret: os.Getenv("COGNITO_CLIENT_SECRET"), - AuthRedirectURI: baseURL + callbackPath, - AuthTokenURL: fmt.Sprintf("https://%s/oauth2/token", domain), - AuthURL: fmt.Sprintf("https://%s/oauth2/authorize", domain), - AuthJwksURL: fmt.Sprintf("https://cognito-idp.%s.amazonaws.com/%s/.well-known/jwks.json", region, userPoolID), - AuthUserPoolID: userPoolID, - AuthDomain: domain, - AuthRegion: region, - AuthLoginPath: loginPath, - AuthCallbackPath: callbackPath, - AuthHomePath: homePath, - AuthLogoutPath: logoutPath, - AuthLogger: logger, - AuthRoutePermissions: make(map[string][]string), + tempConfig := &CognitoConfig{} + errorParsingCognitoConfig := env.Parse(tempConfig) + if errorParsingCognitoConfig != nil { + logger.Error("Error parsing Cognito config", "error", errorParsingCognitoConfig) + return nil } - config.PrettyPrintDebugOnly() - return config + tempConfig.AuthRedirectURI = baseURL + tempConfig.AuthCallbackPath + tempConfig.AuthRedirectURI = baseURL + tempConfig.AuthCallbackPath + tempConfig.AuthTokenURL = fmt.Sprintf("https://%s/oauth2/token", tempConfig.AuthDomain) + tempConfig.AuthURL = fmt.Sprintf("https://%s/oauth2/authorize", tempConfig.AuthDomain) + tempConfig.AuthJwksURL = fmt.Sprintf("https://cognito-idp.%s.amazonaws.com/%s/.well-known/jwks.json", + tempConfig.AuthRegion, + tempConfig.AuthUserPoolID) + tempConfig.AuthLogger = logger + tempConfig.AuthRoutePermissions = make(map[string][]string) + + tempConfig.PrettyPrintDebugOnly() + return tempConfig } func (c *CognitoConfig) PrettyPrintDebugOnly() { @@ -202,6 +158,8 @@ func (c *CognitoConfig) PrettyPrintDebugOnly() { fmt.Printf(" AuthCallbackPath: %s\n", c.AuthCallbackPath) fmt.Printf(" AuthHomePath: %s\n", c.AuthHomePath) fmt.Printf(" AuthLogoutPath: %s\n", c.AuthLogoutPath) + fmt.Printf(" DisableAuth: %s\n", c.DisableAuth) + fmt.Printf(" AuthDomain: %s\n", c.AuthDomain) // pretty print the route permissions map for route, permissions := range c.AuthRoutePermissions { diff --git a/internal/serviceconfig/common.go b/internal/serviceconfig/common.go index 7ff7f457..fbe41149 100644 --- a/internal/serviceconfig/common.go +++ b/internal/serviceconfig/common.go @@ -32,9 +32,10 @@ type BaseConfig struct { // Always place non struct fields at the top of the struct // this is a requirement for the PrintAuthConfig function. - Pwd string `env:"PWD,required,notEmpty"` - - //rbac.AuthConfig + // These are the fields that are common to all services. + //Pwd string `env:"PWD,required,notEmpty"` + Port int `env:"PORT" envDefault:"8080"` + BaseURL string `env:"BASE_URL" envDefault:"http://localhost"` auth.CognitoConfig logger.LogConfig observability.ObsConfig