From 99b4f1f94077e1c0e43b4e7739bf8c10035c6ee2 Mon Sep 17 00:00:00 2001 From: Adam Eijdenberg Date: Tue, 3 Oct 2017 16:23:56 +1100 Subject: [PATCH 1/3] Part 1: Allow all environment variables to be set in either CF user-provided-service, then fallback to environment Update tests to reflect. --- controllers/root_test.go | 7 +- controllers/routes.go | 2 +- controllers/routes_test.go | 6 +- controllers/secure_test.go | 2 +- helpers/env_vars.go | 120 +++++++++++--- helpers/settings.go | 102 +++++------- helpers/settings_test.go | 244 ++++++++++++++--------------- helpers/testhelpers/testhelpers.go | 46 +++--- server.go | 128 ++------------- 9 files changed, 304 insertions(+), 353 deletions(-) diff --git a/controllers/root_test.go b/controllers/root_test.go index 8a67a75e..61329aa9 100644 --- a/controllers/root_test.go +++ b/controllers/root_test.go @@ -8,6 +8,7 @@ import ( "github.com/cloudfoundry-community/go-cfenv" "github.com/18F/cg-dashboard/controllers" + "github.com/18F/cg-dashboard/helpers" . "github.com/18F/cg-dashboard/helpers/testhelpers" . "github.com/18F/cg-dashboard/helpers/testhelpers/docker" ) @@ -15,7 +16,7 @@ import ( func TestPing(t *testing.T) { response, request := NewTestRequest("GET", "/ping", nil) env, _ := cfenv.Current() - router, _, err := controllers.InitApp(GetMockCompleteEnvVars(), env) + router, _, err := controllers.InitApp(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(GetMockCompleteEnvVars())), env) if err != nil { t.Fatal(err) } @@ -39,11 +40,11 @@ func TestPingWithRedis(t *testing.T) { defer cleanUpRedis() // Override the mock env vars to use redis for session backend. envVars := GetMockCompleteEnvVars() - envVars.SessionBackend = "redis" + envVars[helpers.SessionBackendEnvVar] = "redis" env, _ := cfenv.Current() // Setup router. - router, _, err := controllers.InitApp(envVars, env) + router, _, err := controllers.InitApp(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(envVars)), env) if err != nil { t.Fatal(err) } diff --git a/controllers/routes.go b/controllers/routes.go index 384751a1..286d3f84 100644 --- a/controllers/routes.go +++ b/controllers/routes.go @@ -70,7 +70,7 @@ func InitRouter(settings *helpers.Settings, templates *helpers.Templates, mailer } // InitApp takes in envars and sets up the router and settings that will be used for the unstarted server. -func InitApp(envVars helpers.EnvVars, env *cfenv.App) (*web.Router, *helpers.Settings, error) { +func InitApp(envVars *helpers.EnvVars, env *cfenv.App) (*web.Router, *helpers.Settings, error) { // Initialize the settings. settings := helpers.Settings{} if err := settings.InitSettings(envVars, env); err != nil { diff --git a/controllers/routes_test.go b/controllers/routes_test.go index 4e2cf073..5d8352b8 100644 --- a/controllers/routes_test.go +++ b/controllers/routes_test.go @@ -13,7 +13,7 @@ import ( type initAppTest struct { testName string - envVars helpers.EnvVars + envVars map[string]string returnRouterNil bool returnSettingsNil bool returnErrorNil bool @@ -29,7 +29,7 @@ var initAppTests = []initAppTest{ }, { testName: "Blank EnvVars", - envVars: helpers.EnvVars{}, + envVars: map[string]string{}, returnRouterNil: true, returnSettingsNil: true, returnErrorNil: false, @@ -39,7 +39,7 @@ var initAppTests = []initAppTest{ func TestInitApp(t *testing.T) { for _, test := range initAppTests { env, _ := cfenv.Current() - router, settings, err := controllers.InitApp(test.envVars, env) + router, settings, err := controllers.InitApp(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(test.envVars)), env) if (router == nil) != test.returnRouterNil { t.Errorf("Test %s did not return correct router value. Expected %t, Actual %t", test.testName, test.returnRouterNil, (router == nil)) } else if (settings == nil) != test.returnSettingsNil { diff --git a/controllers/secure_test.go b/controllers/secure_test.go index 313f9896..bbf3db74 100644 --- a/controllers/secure_test.go +++ b/controllers/secure_test.go @@ -81,7 +81,7 @@ func TestPrivilegedProxy(t *testing.T) { for _, test := range proxyTests { // We can only get this after the server has started. testServer := CreateExternalServerForPrivileged(t, test) - test.EnvVars.UAAURL = testServer.URL + test.EnvVars[helpers.UAAURLEnvVar] = testServer.URL // Construct full url for the proxy. fullURL := fmt.Sprintf("%s%s", testServer.URL, test.RequestPath) c := &controllers.SecureContext{Context: &controllers.Context{}} diff --git a/helpers/env_vars.go b/helpers/env_vars.go index 4058d58a..ed5c9414 100644 --- a/helpers/env_vars.go +++ b/helpers/env_vars.go @@ -1,5 +1,12 @@ package helpers +import ( + "fmt" + "log" + + cfenv "github.com/cloudfoundry-community/go-cfenv" +) + var ( // ClientIDEnvVar is the environment variable key that represents the registered // Client ID for this web app. @@ -53,27 +60,96 @@ var ( TICSecretEnvVar = "TIC_SECRET" ) -// EnvVars holds all the environment variable values that a non-test server should have. +// EnvVars provides a convenient method to access environment variables type EnvVars struct { - ClientID string - ClientSecret string - Hostname string - LoginURL string - UAAURL string - APIURL string - LogURL string - PProfEnabled string - BuildInfo string - NewRelicLicense string - SecureCookies string - LocalCF string - SessionBackend string - SessionKey string - BasePath string - SMTPHost string - SMTPPort string - SMTPUser string - SMTPPass string - SMTPFrom string - TICSecret string + path []EnvLookup +} + +// Get returns value for key if present, else returns defaultVal if not found +func (el *EnvVars) Get(key, defaultVal string) string { + rv, found := el.load(key) + if !found { + return defaultVal + } + return rv +} + +// MustGet will panic if value is not set, otherwise it returns the value. +func (el *EnvVars) MustGet(key string) string { + rv, found := el.load(key) + if !found { + panic(&ErrMissingEnvVar{EnvVar: key}) + } + return rv +} + +// BoolGet returns true if and only the value "true" or "1" is set for the key, else defaults to false +func (el *EnvVars) BoolGet(key string) bool { + val, _ := el.load(key) + return val == "true" || val == "1" +} + +// load is an internal method that looks for a given key within +// all elements in the path, and if none found, returns "", false. +func (el *EnvVars) load(key string) (string, bool) { + for _, env := range el.path { + rv, found := env(key) + if found { + return rv, true + } + } + return "", false +} + +// NewEnvVarsFromPath create an EnvVars object, where the elements in the path +// are searched in order to load a given variable. +func NewEnvVarsFromPath(path ...EnvLookup) *EnvVars { + return &EnvVars{path: path} +} + +// EnvLookup must return the value for the given key and whether it was found or not +type EnvLookup func(key string) (string, bool) + +// ErrMissingEnvVar is panicked if a MustGet fails. +type ErrMissingEnvVar struct { + // EnvVar is the key that was not found + EnvVar string +} + +// Error returns an error string +func (err *ErrMissingEnvVar) Error() string { + return fmt.Sprintf("missing env variable: %s", err.EnvVar) +} + +// NewEnvLookupFromMap creates a lookup based on a map +func NewEnvLookupFromMap(m map[string]string) EnvLookup { + return func(name string) (string, bool) { + rv, found := m[name] + return rv, found + } +} + +// NewEnvLookupFromCFAppNamedService looks for a CloudFoundry bound service +// with the given name, and will allow sourcing of environment variables +// from there. If no service is found, a warning is printed, but no error thrown. +func NewEnvLookupFromCFAppNamedService(cfApp *cfenv.App, namedService string) EnvLookup { + service, err := cfApp.Services.WithName(namedService) + if err != nil { + log.Printf("Warning: No bound service found with name: %s, will not be used for sourcing env variables.\n", namedService) + } + return func(name string) (string, bool) { + if service == nil { // no service + return "", false + } + serviceVar, found := service.Credentials[name] + if !found { + return "", false + } + serviceVarAsString, ok := serviceVar.(string) + if !ok { + log.Printf("Warning: variable found in service for %s, but unable to cast as string, so ignoring.\n", name) + return "", false + } + return serviceVarAsString, true + } } diff --git a/helpers/settings.go b/helpers/settings.go index 13544a47..31342b2d 100644 --- a/helpers/settings.go +++ b/helpers/settings.go @@ -90,50 +90,32 @@ func (s *Settings) CreateContext() context.Context { // InitSettings attempts to populate all the fields of the Settings struct. It will return an error if it fails, // otherwise it returns nil for success. -func (s *Settings) InitSettings(envVars EnvVars, env *cfenv.App) error { - if len(envVars.ClientID) == 0 { - return errors.New("Unable to find '" + ClientIDEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.ClientSecret) == 0 { - return errors.New("Unable to find '" + ClientSecretEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.Hostname) == 0 { - return errors.New("Unable to find '" + HostnameEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.LoginURL) == 0 { - return errors.New("Unable to find '" + LoginURLEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.UAAURL) == 0 { - return errors.New("Unable to find '" + UAAURLEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.APIURL) == 0 { - return errors.New("Unable to find '" + APIURLEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.LogURL) == 0 { - return errors.New("Unable to find '" + LogURLEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.SessionKey) == 0 { - return errors.New("Unable to find '" + SessionKeyEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.SMTPFrom) == 0 { - return errors.New("Unable to find '" + SMTPFromEnvVar + "' in environment. Exiting.\n") - } - if len(envVars.SMTPHost) == 0 { - return errors.New("Unable to find '" + SMTPHostEnvVar + "' in environment. Exiting.\n") - } +func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) { + defer func() { + // While .MustGet() is convenient in readability below, we'd prefer to convert this + // to an error for upstream callers. + if r := recover(); r != nil { + missingErr, ok := r.(*ErrMissingEnvVar) + if !ok { + // We don't know what this is, re-panic + panic(r) + } - s.BasePath = envVars.BasePath - s.AppURL = envVars.Hostname - s.ConsoleAPI = envVars.APIURL - s.LoginURL = envVars.LoginURL - s.UaaURL = envVars.UAAURL - s.LogURL = envVars.LogURL - s.PProfEnabled = ((envVars.PProfEnabled == "true") || (envVars.PProfEnabled == "1")) - if s.BuildInfo = envVars.BuildInfo; len(s.BuildInfo) == 0 { - s.BuildInfo = "developer-build" - } - s.LocalCF = ((envVars.LocalCF == "true") || (envVars.LocalCF == "1")) - s.SecureCookies = ((envVars.SecureCookies == "true") || (envVars.SecureCookies == "1")) + // Set return code to the actual error + retErr = missingErr + } + }() + + s.BasePath = envVars.Get(BasePathEnvVar, "") + s.AppURL = envVars.MustGet(HostnameEnvVar) + s.ConsoleAPI = envVars.MustGet(APIURLEnvVar) + s.LoginURL = envVars.MustGet(LoginURLEnvVar) + s.UaaURL = envVars.MustGet(UAAURLEnvVar) + s.LogURL = envVars.MustGet(LogURLEnvVar) + s.PProfEnabled = envVars.BoolGet(PProfEnabledEnvVar) + s.BuildInfo = envVars.Get(BuildInfoEnvVar, "developer-build") + s.LocalCF = envVars.BoolGet(LocalCFEnvVar) + s.SecureCookies = envVars.BoolGet(SecureCookiesEnvVar) // Safe guard: shouldn't run with insecure cookies if we are // in a non-development environment (i.e. production) if s.LocalCF == false && s.SecureCookies == false { @@ -142,13 +124,13 @@ func (s *Settings) InitSettings(envVars EnvVars, env *cfenv.App) error { // Setup OAuth2 Client Service. s.OAuthConfig = &oauth2.Config{ - ClientID: envVars.ClientID, - ClientSecret: envVars.ClientSecret, + ClientID: envVars.MustGet(ClientIDEnvVar), + ClientSecret: envVars.MustGet(ClientSecretEnvVar), RedirectURL: s.AppURL + "/oauth2callback", Scopes: []string{"cloud_controller.read", "cloud_controller.write", "cloud_controller.admin", "scim.read", "openid"}, Endpoint: oauth2.Endpoint{ - AuthURL: envVars.LoginURL + "/oauth/authorize", - TokenURL: envVars.UAAURL + "/oauth/token", + AuthURL: envVars.MustGet(LoginURLEnvVar) + "/oauth/authorize", + TokenURL: envVars.MustGet(UAAURLEnvVar) + "/oauth/token", }, } @@ -157,7 +139,7 @@ func (s *Settings) InitSettings(envVars EnvVars, env *cfenv.App) error { } // Initialize Sessions. - switch envVars.SessionBackend { + switch envVars.Get(SessionBackendEnvVar, "") { case "redis": address, password, err := getRedisSettings(env) if err != nil { @@ -193,7 +175,7 @@ func (s *Settings) InitSettings(envVars EnvVars, env *cfenv.App) error { }, } // create our redis pool. - store, err := redistore.NewRediStoreWithPool(redisPool, []byte(envVars.SessionKey)) + store, err := redistore.NewRediStoreWithPool(redisPool, []byte(envVars.MustGet(SessionKeyEnvVar))) if err != nil { return err } @@ -205,7 +187,7 @@ func (s *Settings) InitSettings(envVars EnvVars, env *cfenv.App) error { Secure: s.SecureCookies, } s.Sessions = store - s.SessionBackend = envVars.SessionBackend + s.SessionBackend = "redis" // Use health check function where we do a PING. s.SessionBackendHealthCheck = func() bool { @@ -219,7 +201,7 @@ func (s *Settings) InitSettings(envVars EnvVars, env *cfenv.App) error { return true } default: - store := sessions.NewFilesystemStore("", []byte(envVars.SessionKey)) + store := sessions.NewFilesystemStore("", []byte(envVars.MustGet(SessionKeyEnvVar))) store.MaxLength(4096 * 4) store.Options = &sessions.Options{ HttpOnly: true, @@ -238,18 +220,18 @@ func (s *Settings) InitSettings(envVars EnvVars, env *cfenv.App) error { gob.Register(oauth2.Token{}) s.HighPrivilegedOauthConfig = &clientcredentials.Config{ - ClientID: envVars.ClientID, - ClientSecret: envVars.ClientSecret, + ClientID: envVars.MustGet(ClientIDEnvVar), + ClientSecret: envVars.MustGet(ClientSecretEnvVar), Scopes: []string{"scim.invite", "cloud_controller.admin", "scim.read"}, - TokenURL: envVars.UAAURL + "/oauth/token", + TokenURL: envVars.MustGet(UAAURLEnvVar) + "/oauth/token", } - s.SMTPFrom = envVars.SMTPFrom - s.SMTPHost = envVars.SMTPHost - s.SMTPPass = envVars.SMTPPass - s.SMTPPort = envVars.SMTPPort - s.SMTPUser = envVars.SMTPUser - s.TICSecret = envVars.TICSecret + s.SMTPFrom = envVars.MustGet(SMTPFromEnvVar) + s.SMTPHost = envVars.MustGet(SMTPHostEnvVar) + s.SMTPPass = envVars.Get(SMTPPassEnvVar, "") + s.SMTPPort = envVars.Get(SMTPPortEnvVar, "") + s.SMTPUser = envVars.Get(SMTPUserEnvVar, "") + s.TICSecret = envVars.Get(TICSecretEnvVar, "") return nil } diff --git a/helpers/settings_test.go b/helpers/settings_test.go index 5b0bbabf..65d99838 100644 --- a/helpers/settings_test.go +++ b/helpers/settings_test.go @@ -10,194 +10,194 @@ import ( type initSettingsTest struct { testName string - envVars helpers.EnvVars + envVars map[string]string returnValueNull bool } var initSettingsTests = []initSettingsTest{ { testName: "Basic Valid Production CF Settings", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", - SMTPFrom: "blah@blah.com", - SMTPHost: "localhost", - SecureCookies: "1", - TICSecret: "tic", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", + helpers.SMTPFromEnvVar: "blah@blah.com", + helpers.SMTPHostEnvVar: "localhost", + helpers.SecureCookiesEnvVar: "1", + helpers.TICSecretEnvVar: "tic", }, returnValueNull: true, }, { testName: "Basic Valid Local CF Settings", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", - SMTPFrom: "blah@blah.com", - SMTPHost: "localhost", - SecureCookies: "0", - LocalCF: "1", - TICSecret: "tic", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", + helpers.SMTPFromEnvVar: "blah@blah.com", + helpers.SMTPHostEnvVar: "localhost", + helpers.SecureCookiesEnvVar: "0", + helpers.LocalCFEnvVar: "1", + helpers.TICSecretEnvVar: "tic", }, returnValueNull: true, }, { testName: "Basic Invalid Prod CF Settings", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", - SMTPFrom: "blah@blah.com", - SMTPHost: "localhost", - LocalCF: "0", - TICSecret: "tic", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", + helpers.SMTPFromEnvVar: "blah@blah.com", + helpers.SMTPHostEnvVar: "localhost", + helpers.LocalCFEnvVar: "0", + helpers.TICSecretEnvVar: "tic", // Let SecureCookies Default to false (similar to what would happen in real life). }, returnValueNull: false, }, { testName: "Missing Client ID check", - envVars: helpers.EnvVars{ - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", + envVars: map[string]string{ + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", }, returnValueNull: false, }, { testName: "Missing Client Secret check", - envVars: helpers.EnvVars{ - ClientID: "ID", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", }, returnValueNull: false, }, { testName: "Missing Hostname check", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", }, returnValueNull: false, }, { testName: "Missing Auth URL check", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - UAAURL: "uaaurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", }, returnValueNull: false, }, { testName: "Missing Token URL check", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - APIURL: "apiurl", - LogURL: "logurl", - SessionKey: "lalala", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.APIURLEnvVar: "apiurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", }, returnValueNull: false, }, { testName: "Missing API URL check", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - LogURL: "logurl", - SessionKey: "lalala", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.LogURLEnvVar: "logurl", + helpers.SessionKeyEnvVar: "lalala", }, returnValueNull: false, }, { testName: "Missing Log URL check", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - SessionKey: "lalala", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.SessionKeyEnvVar: "lalala", }, returnValueNull: false, }, { testName: "Missing Session Key check", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", }, returnValueNull: false, }, { testName: "Missing SMTP From", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - SessionKey: "blah", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.SessionKeyEnvVar: "blah", }, returnValueNull: false, }, { testName: "Missing SMTP Host", - envVars: helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "hostname", - LoginURL: "loginurl", - UAAURL: "uaaurl", - APIURL: "apiurl", - SessionKey: "blah", - SMTPFrom: "blah@blah.com", + envVars: map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "hostname", + helpers.LoginURLEnvVar: "loginurl", + helpers.UAAURLEnvVar: "uaaurl", + helpers.APIURLEnvVar: "apiurl", + helpers.SessionKeyEnvVar: "blah", + helpers.SMTPFromEnvVar: "blah@blah.com", }, returnValueNull: false, }, @@ -207,7 +207,7 @@ func TestInitSettings(t *testing.T) { s := helpers.Settings{} env, _ := cfenv.Current() for _, test := range initSettingsTests { - ret := s.InitSettings(test.envVars, env) + ret := s.InitSettings(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(test.envVars)), env) if (ret == nil) != test.returnValueNull { t.Errorf("Test %s did not return correct value. Expected %t, Actual %t", test.testName, test.returnValueNull, (ret == nil)) } diff --git a/helpers/testhelpers/testhelpers.go b/helpers/testhelpers/testhelpers.go index e18faaaf..3dd76f3b 100644 --- a/helpers/testhelpers/testhelpers.go +++ b/helpers/testhelpers/testhelpers.go @@ -109,11 +109,11 @@ func EchoResponseHandler(rw http.ResponseWriter, response *http.Response) { } // CreateRouterWithMockSession will create a settings with the appropriate envVars and load the mock session with the session data. -func CreateRouterWithMockSession(sessionData map[string]interface{}, envVars helpers.EnvVars) (*web.Router, *MockSessionStore) { +func CreateRouterWithMockSession(sessionData map[string]interface{}, envVars map[string]string) (*web.Router, *MockSessionStore) { // Initialize settings. settings := helpers.Settings{} env, _ := cfenv.Current() - settings.InitSettings(envVars, env) + settings.InitSettings(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(envVars)), env) // Initialize a new session store. store := MockSessionStore{} @@ -140,7 +140,7 @@ type BasicConsoleUnitTest struct { // Name of the tests TestName string // Set of env vars to set up the settings. - EnvVars helpers.EnvVars + EnvVars map[string]string // Ending location of request. Location string Code int @@ -236,22 +236,22 @@ type BasicProxyTest struct { } // GetMockCompleteEnvVars is just a commonly used env vars object that contains non-empty values for all the fields of the EnvVars struct. -func GetMockCompleteEnvVars() helpers.EnvVars { - return helpers.EnvVars{ - ClientID: "ID", - ClientSecret: "Secret", - Hostname: "https://hostname", - LoginURL: "https://loginurl", - UAAURL: "https://uaaurl", - APIURL: "https://apiurl", - LogURL: "https://logurl", - PProfEnabled: "true", - SessionKey: "lalala", - BasePath: os.Getenv(helpers.BasePathEnvVar), - SMTPFrom: "cloud@cloud.gov", - SMTPHost: "localhost", - SecureCookies: "1", - TICSecret: "tic", +func GetMockCompleteEnvVars() map[string]string { + return map[string]string{ + helpers.ClientIDEnvVar: "ID", + helpers.ClientSecretEnvVar: "Secret", + helpers.HostnameEnvVar: "https://hostname", + helpers.LoginURLEnvVar: "https://loginurl", + helpers.UAAURLEnvVar: "https://uaaurl", + helpers.APIURLEnvVar: "https://apiurl", + helpers.LogURLEnvVar: "https://logurl", + helpers.PProfEnabledEnvVar: "true", + helpers.SessionKeyEnvVar: "lalala", + helpers.BasePathEnvVar: os.Getenv(helpers.BasePathEnvVar), + helpers.SMTPFromEnvVar: "cloud@cloud.gov", + helpers.SMTPHostEnvVar: "localhost", + helpers.SecureCookiesEnvVar: "1", + helpers.TICSecretEnvVar: "tic", } } @@ -273,7 +273,7 @@ func CreateExternalServerForPrivileged(t *testing.T, test BasicProxyTest) *httpt if err != nil { t.Errorf("failed reading request body: %s.", err) } - expectedRequestBody := "client_id=" + GetMockCompleteEnvVars().ClientID + "&grant_type=client_credentials&scope=scim.invite+cloud_controller.admin+scim.read" + expectedRequestBody := "client_id=" + GetMockCompleteEnvVars()[helpers.ClientIDEnvVar] + "&grant_type=client_credentials&scope=scim.invite+cloud_controller.admin+scim.read" if string(body) != expectedRequestBody { t.Errorf("payload = %q; want %q", string(body), expectedRequestBody) } @@ -356,7 +356,7 @@ func PrepareExternalServerCall(t *testing.T, c *controllers.SecureContext, testS // Assign settings to context mockSettings := &helpers.Settings{} env, _ := cfenv.Current() - mockSettings.InitSettings(test.EnvVars, env) + mockSettings.InitSettings(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(test.EnvVars)), env) c.Settings = mockSettings response, request := NewTestRequest(test.RequestMethod, fullURL, test.RequestBody) @@ -366,8 +366,8 @@ func PrepareExternalServerCall(t *testing.T, c *controllers.SecureContext, testS for header, value := range test.RequestHeaders { request.Header.Set(header, value) } - test.EnvVars.APIURL = testServer.URL - test.EnvVars.UAAURL = testServer.URL + test.EnvVars[helpers.APIURLEnvVar] = testServer.URL + test.EnvVars[helpers.UAAURLEnvVar] = testServer.URL router, _ := CreateRouterWithMockSession(test.SessionData, test.EnvVars) return response, request, router } diff --git a/server.go b/server.go index 4623daf7..71b3c338 100644 --- a/server.go +++ b/server.go @@ -20,117 +20,6 @@ const ( cfUserProvidedService = "dashboard-ups" ) -func loadEnvVars() helpers.EnvVars { - envVars := helpers.EnvVars{} - - envVars.ClientID = os.Getenv(helpers.ClientIDEnvVar) - envVars.ClientSecret = os.Getenv(helpers.ClientSecretEnvVar) - envVars.Hostname = os.Getenv(helpers.HostnameEnvVar) - envVars.LoginURL = os.Getenv(helpers.LoginURLEnvVar) - envVars.UAAURL = os.Getenv(helpers.UAAURLEnvVar) - envVars.APIURL = os.Getenv(helpers.APIURLEnvVar) - envVars.LogURL = os.Getenv(helpers.LogURLEnvVar) - envVars.PProfEnabled = os.Getenv(helpers.PProfEnabledEnvVar) - envVars.BuildInfo = os.Getenv(helpers.BuildInfoEnvVar) - envVars.NewRelicLicense = os.Getenv(helpers.NewRelicLicenseEnvVar) - envVars.SecureCookies = os.Getenv(helpers.SecureCookiesEnvVar) - envVars.LocalCF = os.Getenv(helpers.LocalCFEnvVar) - envVars.SessionBackend = os.Getenv(helpers.SessionBackendEnvVar) - envVars.SessionKey = os.Getenv(helpers.SessionKeyEnvVar) - envVars.BasePath = os.Getenv(helpers.BasePathEnvVar) - envVars.SMTPHost = os.Getenv(helpers.SMTPHostEnvVar) - envVars.SMTPPort = os.Getenv(helpers.SMTPPortEnvVar) - envVars.SMTPUser = os.Getenv(helpers.SMTPUserEnvVar) - envVars.SMTPPass = os.Getenv(helpers.SMTPPassEnvVar) - envVars.SMTPFrom = os.Getenv(helpers.SMTPFromEnvVar) - envVars.TICSecret = os.Getenv(helpers.TICSecretEnvVar) - return envVars -} - -func replaceEnvVar(envVars *helpers.EnvVars, envVar string, value interface{}) { - if stringValue, ok := value.(string); ok { - // only replace if non empty. - if len(stringValue) < 1 { - return - } - switch envVar { - case helpers.ClientIDEnvVar: - envVars.ClientID = stringValue - case helpers.ClientSecretEnvVar: - envVars.ClientSecret = stringValue - case helpers.NewRelicLicenseEnvVar: - envVars.NewRelicLicense = stringValue - case helpers.SessionKeyEnvVar: - envVars.SessionKey = stringValue - case helpers.SMTPHostEnvVar: - envVars.SMTPHost = stringValue - case helpers.SMTPPortEnvVar: - envVars.SMTPPort = stringValue - case helpers.SMTPUserEnvVar: - envVars.SMTPUser = stringValue - case helpers.SMTPPassEnvVar: - envVars.SMTPPass = stringValue - case helpers.SMTPFromEnvVar: - envVars.SMTPFrom = stringValue - case helpers.TICSecretEnvVar: - envVars.TICSecret = stringValue - } - } -} - -func loadUPSVars(envVars *helpers.EnvVars, cfEnv *cfenv.App) { - if cfEnv == nil { - return - } - - if cfUPS, err := cfEnv.Services.WithName(cfUserProvidedService); err == nil { - fmt.Println("User Provided Service found") - if clientID, found := cfUPS.Credentials[helpers.ClientIDEnvVar]; found { - fmt.Println("Replacing " + helpers.ClientIDEnvVar) - replaceEnvVar(envVars, helpers.ClientIDEnvVar, clientID) - } - if clientSecret, found := cfUPS.Credentials[helpers.ClientSecretEnvVar]; found { - fmt.Println("Replacing " + helpers.ClientSecretEnvVar) - replaceEnvVar(envVars, helpers.ClientSecretEnvVar, clientSecret) - } - if newRelic, found := cfUPS.Credentials[helpers.NewRelicLicenseEnvVar]; found { - fmt.Println("Replacing " + helpers.NewRelicLicenseEnvVar) - replaceEnvVar(envVars, helpers.NewRelicLicenseEnvVar, newRelic) - } - if sessionKey, found := cfUPS.Credentials[helpers.SessionKeyEnvVar]; found { - fmt.Println("Replacing " + helpers.SessionKeyEnvVar) - replaceEnvVar(envVars, helpers.SessionKeyEnvVar, sessionKey) - } - if smtpFrom, found := cfUPS.Credentials[helpers.SMTPFromEnvVar]; found { - fmt.Println("Replacing " + helpers.SMTPFromEnvVar) - replaceEnvVar(envVars, helpers.SMTPFromEnvVar, smtpFrom) - } - if smtpHost, found := cfUPS.Credentials[helpers.SMTPHostEnvVar]; found { - fmt.Println("Replacing " + helpers.SMTPHostEnvVar) - replaceEnvVar(envVars, helpers.SMTPHostEnvVar, smtpHost) - } - if smtpPass, found := cfUPS.Credentials[helpers.SMTPPassEnvVar]; found { - fmt.Println("Replacing " + helpers.SMTPPassEnvVar) - replaceEnvVar(envVars, helpers.SMTPPassEnvVar, smtpPass) - } - if smtpPort, found := cfUPS.Credentials[helpers.SMTPPortEnvVar]; found { - fmt.Println("Replacing " + helpers.SMTPPortEnvVar) - replaceEnvVar(envVars, helpers.SMTPPortEnvVar, smtpPort) - } - if smtpUser, found := cfUPS.Credentials[helpers.SMTPUserEnvVar]; found { - fmt.Println("Replacing " + helpers.SMTPUserEnvVar) - replaceEnvVar(envVars, helpers.SMTPUserEnvVar, smtpUser) - } - if ticSecret, found := cfUPS.Credentials[helpers.TICSecretEnvVar]; found { - fmt.Println("Replacing " + helpers.TICSecretEnvVar) - replaceEnvVar(envVars, helpers.TICSecretEnvVar, ticSecret) - } - - } else { - fmt.Println("CF Env error: " + err.Error()) - } -} - func main() { // Start the server up. var port string @@ -161,10 +50,12 @@ func startMonitoring(license string) { } func startApp(port string, env *cfenv.App) { - // Load environment variables - envVars := loadEnvVars() - // Override with Cloud Foundry user-provided service credentials if specified. - loadUPSVars(&envVars, env) + // Look for env vars first in a user provided service (if available), and if not found, + // fallback to the environment. + envVars := helpers.NewEnvVarsFromPath( + helpers.NewEnvLookupFromCFAppNamedService(env, cfUserProvidedService), + os.LookupEnv, + ) app, settings, err := controllers.InitApp(envVars, env) if err != nil { @@ -178,15 +69,16 @@ func startApp(port string, env *cfenv.App) { pprof.InitPProfRouter(app) } - if envVars.NewRelicLicense != "" { + nrLicense := envVars.Get(helpers.NewRelicLicenseEnvVar, "") + if nrLicense != "" { fmt.Println("starting monitoring...") - startMonitoring(envVars.NewRelicLicense) + startMonitoring(nrLicense) } fmt.Println("starting app now...") // TODO add better timeout message. By default it will just say "Timeout" - protect := csrf.Protect([]byte(envVars.SessionKey), csrf.Secure(settings.SecureCookies)) + protect := csrf.Protect([]byte(envVars.MustGet(helpers.SessionKeyEnvVar)), csrf.Secure(settings.SecureCookies)) http.ListenAndServe(":"+port, protect( http.TimeoutHandler(context.ClearHandler(app), helpers.TimeoutConstant, ""), )) From 09a8c3f61ebab462e79498c8cd66803c249c22b5 Mon Sep 17 00:00:00 2001 From: Adam Eijdenberg Date: Wed, 4 Oct 2017 08:10:56 +1100 Subject: [PATCH 2/3] Move NewEnvLookupFromMap to testhelpers --- controllers/root_test.go | 4 ++-- controllers/routes_test.go | 2 +- helpers/env_vars.go | 8 -------- helpers/settings_test.go | 3 ++- helpers/testhelpers/testhelpers.go | 12 ++++++++++-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/controllers/root_test.go b/controllers/root_test.go index 61329aa9..7f16b3d8 100644 --- a/controllers/root_test.go +++ b/controllers/root_test.go @@ -16,7 +16,7 @@ import ( func TestPing(t *testing.T) { response, request := NewTestRequest("GET", "/ping", nil) env, _ := cfenv.Current() - router, _, err := controllers.InitApp(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(GetMockCompleteEnvVars())), env) + router, _, err := controllers.InitApp(helpers.NewEnvVarsFromPath(NewEnvLookupFromMap(GetMockCompleteEnvVars())), env) if err != nil { t.Fatal(err) } @@ -44,7 +44,7 @@ func TestPingWithRedis(t *testing.T) { env, _ := cfenv.Current() // Setup router. - router, _, err := controllers.InitApp(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(envVars)), env) + router, _, err := controllers.InitApp(helpers.NewEnvVarsFromPath(NewEnvLookupFromMap(envVars)), env) if err != nil { t.Fatal(err) } diff --git a/controllers/routes_test.go b/controllers/routes_test.go index 5d8352b8..e457bcec 100644 --- a/controllers/routes_test.go +++ b/controllers/routes_test.go @@ -39,7 +39,7 @@ var initAppTests = []initAppTest{ func TestInitApp(t *testing.T) { for _, test := range initAppTests { env, _ := cfenv.Current() - router, settings, err := controllers.InitApp(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(test.envVars)), env) + router, settings, err := controllers.InitApp(helpers.NewEnvVarsFromPath(NewEnvLookupFromMap(test.envVars)), env) if (router == nil) != test.returnRouterNil { t.Errorf("Test %s did not return correct router value. Expected %t, Actual %t", test.testName, test.returnRouterNil, (router == nil)) } else if (settings == nil) != test.returnSettingsNil { diff --git a/helpers/env_vars.go b/helpers/env_vars.go index ed5c9414..896bce0d 100644 --- a/helpers/env_vars.go +++ b/helpers/env_vars.go @@ -121,14 +121,6 @@ func (err *ErrMissingEnvVar) Error() string { return fmt.Sprintf("missing env variable: %s", err.EnvVar) } -// NewEnvLookupFromMap creates a lookup based on a map -func NewEnvLookupFromMap(m map[string]string) EnvLookup { - return func(name string) (string, bool) { - rv, found := m[name] - return rv, found - } -} - // NewEnvLookupFromCFAppNamedService looks for a CloudFoundry bound service // with the given name, and will allow sourcing of environment variables // from there. If no service is found, a warning is printed, but no error thrown. diff --git a/helpers/settings_test.go b/helpers/settings_test.go index 65d99838..d8b95635 100644 --- a/helpers/settings_test.go +++ b/helpers/settings_test.go @@ -6,6 +6,7 @@ import ( "github.com/cloudfoundry-community/go-cfenv" "github.com/18F/cg-dashboard/helpers" + "github.com/18F/cg-dashboard/helpers/testhelpers" ) type initSettingsTest struct { @@ -207,7 +208,7 @@ func TestInitSettings(t *testing.T) { s := helpers.Settings{} env, _ := cfenv.Current() for _, test := range initSettingsTests { - ret := s.InitSettings(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(test.envVars)), env) + ret := s.InitSettings(helpers.NewEnvVarsFromPath(testhelpers.NewEnvLookupFromMap(test.envVars)), env) if (ret == nil) != test.returnValueNull { t.Errorf("Test %s did not return correct value. Expected %t, Actual %t", test.testName, test.returnValueNull, (ret == nil)) } diff --git a/helpers/testhelpers/testhelpers.go b/helpers/testhelpers/testhelpers.go index 3dd76f3b..478915db 100644 --- a/helpers/testhelpers/testhelpers.go +++ b/helpers/testhelpers/testhelpers.go @@ -113,7 +113,7 @@ func CreateRouterWithMockSession(sessionData map[string]interface{}, envVars map // Initialize settings. settings := helpers.Settings{} env, _ := cfenv.Current() - settings.InitSettings(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(envVars)), env) + settings.InitSettings(helpers.NewEnvVarsFromPath(NewEnvLookupFromMap(envVars)), env) // Initialize a new session store. store := MockSessionStore{} @@ -356,7 +356,7 @@ func PrepareExternalServerCall(t *testing.T, c *controllers.SecureContext, testS // Assign settings to context mockSettings := &helpers.Settings{} env, _ := cfenv.Current() - mockSettings.InitSettings(helpers.NewEnvVarsFromPath(helpers.NewEnvLookupFromMap(test.EnvVars)), env) + mockSettings.InitSettings(helpers.NewEnvVarsFromPath(NewEnvLookupFromMap(test.EnvVars)), env) c.Settings = mockSettings response, request := NewTestRequest(test.RequestMethod, fullURL, test.RequestBody) @@ -391,3 +391,11 @@ func VerifyExternalCallResponse(t *testing.T, response *httptest.ResponseRecorde } } } + +// NewEnvLookupFromMap creates a lookup based on a map +func NewEnvLookupFromMap(m map[string]string) helpers.EnvLookup { + return func(name string) (string, bool) { + rv, found := m[name] + return rv, found + } +} From 3da2bb89d5a017cb6f58583144bd2d32f40c4391 Mon Sep 17 00:00:00 2001 From: Adam Eijdenberg Date: Wed, 4 Oct 2017 11:44:34 +1100 Subject: [PATCH 3/3] Rename per comments from @jonathaningram --- helpers/env_vars.go | 37 +++++++++++++++++++++---------- helpers/settings.go | 54 ++++++++++++++++++++++----------------------- server.go | 4 ++-- 3 files changed, 54 insertions(+), 41 deletions(-) diff --git a/helpers/env_vars.go b/helpers/env_vars.go index 896bce0d..e078c7f2 100644 --- a/helpers/env_vars.go +++ b/helpers/env_vars.go @@ -3,6 +3,7 @@ package helpers import ( "fmt" "log" + "strconv" cfenv "github.com/cloudfoundry-community/go-cfenv" ) @@ -65,8 +66,8 @@ type EnvVars struct { path []EnvLookup } -// Get returns value for key if present, else returns defaultVal if not found -func (el *EnvVars) Get(key, defaultVal string) string { +// String returns value for key if present, else returns defaultVal if not found +func (el *EnvVars) String(key, defaultVal string) string { rv, found := el.load(key) if !found { return defaultVal @@ -74,19 +75,31 @@ func (el *EnvVars) Get(key, defaultVal string) string { return rv } -// MustGet will panic if value is not set, otherwise it returns the value. -func (el *EnvVars) MustGet(key string) string { +// MustString will panic if value is not set, otherwise it returns the value. +func (el *EnvVars) MustString(key string) string { rv, found := el.load(key) if !found { - panic(&ErrMissingEnvVar{EnvVar: key}) + panic(&ErrMissingEnvVar{Name: key}) } return rv } -// BoolGet returns true if and only the value "true" or "1" is set for the key, else defaults to false -func (el *EnvVars) BoolGet(key string) bool { - val, _ := el.load(key) - return val == "true" || val == "1" +// Bool looks for the key, and if found, parses it using strconv.ParseBool and returns +// the result. If not found, returns false. If found and won't parse, panics. +func (el *EnvVars) Bool(key string) bool { + val, found := el.load(key) + if !found { + return false + } + + rv, err := strconv.ParseBool(val) + if err != nil { + // invalid values will now return an error + // previous behavior defaulted to false + panic(err) + } + + return rv } // load is an internal method that looks for a given key within @@ -112,13 +125,13 @@ type EnvLookup func(key string) (string, bool) // ErrMissingEnvVar is panicked if a MustGet fails. type ErrMissingEnvVar struct { - // EnvVar is the key that was not found - EnvVar string + // Name of the key that was not found + Name string } // Error returns an error string func (err *ErrMissingEnvVar) Error() string { - return fmt.Sprintf("missing env variable: %s", err.EnvVar) + return fmt.Sprintf("missing env variable: %s", err.Name) } // NewEnvLookupFromCFAppNamedService looks for a CloudFoundry bound service diff --git a/helpers/settings.go b/helpers/settings.go index 31342b2d..f6d1e50c 100644 --- a/helpers/settings.go +++ b/helpers/settings.go @@ -92,7 +92,7 @@ func (s *Settings) CreateContext() context.Context { // otherwise it returns nil for success. func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) { defer func() { - // While .MustGet() is convenient in readability below, we'd prefer to convert this + // While .MustString() is convenient in readability below, we'd prefer to convert this // to an error for upstream callers. if r := recover(); r != nil { missingErr, ok := r.(*ErrMissingEnvVar) @@ -106,16 +106,16 @@ func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) } }() - s.BasePath = envVars.Get(BasePathEnvVar, "") - s.AppURL = envVars.MustGet(HostnameEnvVar) - s.ConsoleAPI = envVars.MustGet(APIURLEnvVar) - s.LoginURL = envVars.MustGet(LoginURLEnvVar) - s.UaaURL = envVars.MustGet(UAAURLEnvVar) - s.LogURL = envVars.MustGet(LogURLEnvVar) - s.PProfEnabled = envVars.BoolGet(PProfEnabledEnvVar) - s.BuildInfo = envVars.Get(BuildInfoEnvVar, "developer-build") - s.LocalCF = envVars.BoolGet(LocalCFEnvVar) - s.SecureCookies = envVars.BoolGet(SecureCookiesEnvVar) + s.BasePath = envVars.String(BasePathEnvVar, "") + s.AppURL = envVars.MustString(HostnameEnvVar) + s.ConsoleAPI = envVars.MustString(APIURLEnvVar) + s.LoginURL = envVars.MustString(LoginURLEnvVar) + s.UaaURL = envVars.MustString(UAAURLEnvVar) + s.LogURL = envVars.MustString(LogURLEnvVar) + s.PProfEnabled = envVars.Bool(PProfEnabledEnvVar) + s.BuildInfo = envVars.String(BuildInfoEnvVar, "developer-build") + s.LocalCF = envVars.Bool(LocalCFEnvVar) + s.SecureCookies = envVars.Bool(SecureCookiesEnvVar) // Safe guard: shouldn't run with insecure cookies if we are // in a non-development environment (i.e. production) if s.LocalCF == false && s.SecureCookies == false { @@ -124,13 +124,13 @@ func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) // Setup OAuth2 Client Service. s.OAuthConfig = &oauth2.Config{ - ClientID: envVars.MustGet(ClientIDEnvVar), - ClientSecret: envVars.MustGet(ClientSecretEnvVar), + ClientID: envVars.MustString(ClientIDEnvVar), + ClientSecret: envVars.MustString(ClientSecretEnvVar), RedirectURL: s.AppURL + "/oauth2callback", Scopes: []string{"cloud_controller.read", "cloud_controller.write", "cloud_controller.admin", "scim.read", "openid"}, Endpoint: oauth2.Endpoint{ - AuthURL: envVars.MustGet(LoginURLEnvVar) + "/oauth/authorize", - TokenURL: envVars.MustGet(UAAURLEnvVar) + "/oauth/token", + AuthURL: envVars.MustString(LoginURLEnvVar) + "/oauth/authorize", + TokenURL: envVars.MustString(UAAURLEnvVar) + "/oauth/token", }, } @@ -139,7 +139,7 @@ func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) } // Initialize Sessions. - switch envVars.Get(SessionBackendEnvVar, "") { + switch envVars.String(SessionBackendEnvVar, "") { case "redis": address, password, err := getRedisSettings(env) if err != nil { @@ -175,7 +175,7 @@ func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) }, } // create our redis pool. - store, err := redistore.NewRediStoreWithPool(redisPool, []byte(envVars.MustGet(SessionKeyEnvVar))) + store, err := redistore.NewRediStoreWithPool(redisPool, []byte(envVars.MustString(SessionKeyEnvVar))) if err != nil { return err } @@ -201,7 +201,7 @@ func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) return true } default: - store := sessions.NewFilesystemStore("", []byte(envVars.MustGet(SessionKeyEnvVar))) + store := sessions.NewFilesystemStore("", []byte(envVars.MustString(SessionKeyEnvVar))) store.MaxLength(4096 * 4) store.Options = &sessions.Options{ HttpOnly: true, @@ -220,18 +220,18 @@ func (s *Settings) InitSettings(envVars *EnvVars, env *cfenv.App) (retErr error) gob.Register(oauth2.Token{}) s.HighPrivilegedOauthConfig = &clientcredentials.Config{ - ClientID: envVars.MustGet(ClientIDEnvVar), - ClientSecret: envVars.MustGet(ClientSecretEnvVar), + ClientID: envVars.MustString(ClientIDEnvVar), + ClientSecret: envVars.MustString(ClientSecretEnvVar), Scopes: []string{"scim.invite", "cloud_controller.admin", "scim.read"}, - TokenURL: envVars.MustGet(UAAURLEnvVar) + "/oauth/token", + TokenURL: envVars.MustString(UAAURLEnvVar) + "/oauth/token", } - s.SMTPFrom = envVars.MustGet(SMTPFromEnvVar) - s.SMTPHost = envVars.MustGet(SMTPHostEnvVar) - s.SMTPPass = envVars.Get(SMTPPassEnvVar, "") - s.SMTPPort = envVars.Get(SMTPPortEnvVar, "") - s.SMTPUser = envVars.Get(SMTPUserEnvVar, "") - s.TICSecret = envVars.Get(TICSecretEnvVar, "") + s.SMTPFrom = envVars.MustString(SMTPFromEnvVar) + s.SMTPHost = envVars.MustString(SMTPHostEnvVar) + s.SMTPPass = envVars.String(SMTPPassEnvVar, "") + s.SMTPPort = envVars.String(SMTPPortEnvVar, "") + s.SMTPUser = envVars.String(SMTPUserEnvVar, "") + s.TICSecret = envVars.String(TICSecretEnvVar, "") return nil } diff --git a/server.go b/server.go index 71b3c338..3dfcb892 100644 --- a/server.go +++ b/server.go @@ -69,7 +69,7 @@ func startApp(port string, env *cfenv.App) { pprof.InitPProfRouter(app) } - nrLicense := envVars.Get(helpers.NewRelicLicenseEnvVar, "") + nrLicense := envVars.String(helpers.NewRelicLicenseEnvVar, "") if nrLicense != "" { fmt.Println("starting monitoring...") startMonitoring(nrLicense) @@ -78,7 +78,7 @@ func startApp(port string, env *cfenv.App) { fmt.Println("starting app now...") // TODO add better timeout message. By default it will just say "Timeout" - protect := csrf.Protect([]byte(envVars.MustGet(helpers.SessionKeyEnvVar)), csrf.Secure(settings.SecureCookies)) + protect := csrf.Protect([]byte(envVars.MustString(helpers.SessionKeyEnvVar)), csrf.Secure(settings.SecureCookies)) http.ListenAndServe(":"+port, protect( http.TimeoutHandler(context.ClearHandler(app), helpers.TimeoutConstant, ""), ))