// Auth handles token authentication. func Auth(h app.Handler) app.Handler { // Check if authentication is turned off. on, err := cfg.Bool(cfgAuth) if err == nil && !on { return func(c *app.Context) error { log.Dev(c.SessionID, "Auth", "******> Authentication Off") return h(c) } } // Turn authentication on. return func(c *app.Context) error { token := c.Request.Header.Get("Authorization") log.Dev(c.SessionID, "Auth", "Started : Token[%s]", token) if len(token) < 5 || token[0:5] != "Basic" { log.Error(c.SessionID, "Auth", app.ErrNotAuthorized, "Validating token") return app.ErrNotAuthorized } var err error if c.User, err = auth.ValidateWebToken(c.SessionID, c.DB, token[6:]); err != nil { log.Error(c.SessionID, "Auth", err, "Validating token") return app.ErrNotAuthorized } log.Dev(c.SessionID, "Auth", "Completed") return h(c) } }
// API returns a handler for a set of routes. func API() http.Handler { mongoURI := cfg.MustURL(cfgMongoURI) // The web framework middleware for Mongo is using the name of the // database as the name of the master session by convention. So use // cfg.DB as the second argument when creating the master session. if err := db.RegMasterSession("startup", mongoURI.Path, mongoURI.String(), 25*time.Second); err != nil { log.Error("startup", "Init", err, "Initializing MongoDB") os.Exit(1) } w := web.New(logm.Midware, errorm.Midware) publicKey, err := cfg.String(cfgAuthPublicKey) if err != nil || publicKey == "" { log.User("startup", "Init", "%s is missing, internal authentication is disabled", cfgAuthPublicKey) } // If the public key is provided then add the auth middleware or fail using // the provided public key. if publicKey != "" { log.Dev("startup", "Init", "Initializing Auth") authm, err := authm.Midware(publicKey, authm.MidwareOpts{}) if err != nil { log.Error("startup", "Init", err, "Initializing Auth") os.Exit(1) } // Apply the authentication middleware on top of the application as the // first middleware. w.Use(authm) } // Add the Mongo and Cayley middlewares possibly after the auth middleware. w.Use(mongo.Midware(mongoURI), cayley.Midware(mongoURI)) if cors, err := cfg.Bool(cfgEnableCORS); err == nil && cors { log.Dev("startup", "Init", "Initializing CORS : CORS Enabled") w.Use(w.CORS()) } else { log.Dev("startup", "Init", "CORS Disabled") } log.Dev("startup", "Init", "Initalizing routes") routes(w) return w }
// API returns a handler for a set of routes. func API() http.Handler { mongoURI := cfg.MustURL(cfgMongoURI) // The web framework middleware for Mongo is using the name of the // database as the name of the master session by convention. So use // cfg.DB as the second argument when creating the master session. if err := db.RegMasterSession("startup", mongoURI.Path, mongoURI.String(), 25*time.Second); err != nil { log.Error("startup", "Init", err, "Initializing MongoDB") os.Exit(1) } // Ensure that the database indexes are setup on the underlying MongoDB // database. if err := ensureDBIndexes(mongoURI); err != nil { log.Error("startup", "Init", err, "Initializing DB Indexes") os.Exit(1) } w := web.New(logm.Midware, errorm.Midware, mongo.Midware(mongoURI)) // Load in the recaptcha secret from the config. if recaptcha, err := cfg.String(cfgRecaptchaSecret); err == nil && recaptcha != "" { w.Ctx["recaptcha"] = recaptcha log.Dev("startup", "Init", "Recaptcha Enabled") } else { log.Dev("startup", "Init", "%s is missing, recaptcha is disabled", cfgRecaptchaSecret) } if cors, err := cfg.Bool(cfgEnableCORS); err == nil && cors { log.Dev("startup", "Init", "Initializing CORS : CORS Enabled") w.Use(w.CORS()) } else { log.Dev("startup", "Init", "CORS Disabled") } log.Dev("startup", "Init", "Initalizing routes") routes(w) return w }
// TestExists validates the ability to load configuration values // using the OS-level environment variables and read them back. func TestExists(t *testing.T) { t.Log("Given the need to read environment variables.") { uStr := "postgres://*****:*****@127.0.0.1:8080/postgres?sslmode=disable" os.Setenv("MYAPP_PROC_ID", "322") os.Setenv("MYAPP_SOCKET", "./tmp/sockets.po") os.Setenv("MYAPP_PORT", "4034") os.Setenv("MYAPP_FLAG", "true") os.Setenv("MYAPP_DSN", uStr) cfg.Init("MYAPP") t.Log("\tWhen given a namspace key to search for that exists.") { proc, err := cfg.Int("PROC_ID") if err != nil { t.Errorf("\t\t%s Should not return error when valid key %q", failed, "PROC_ID") } else { t.Logf("\t\t%s Should not return error when valid key %q", succeed, "PROC_ID") if proc != 322 { t.Errorf("\t\t%s Should have key %q with value %d", failed, "PROC_ID", 322) } else { t.Logf("\t\t%s Should have key %q with value %d", succeed, "PROC_ID", 322) } } socket, err := cfg.String("SOCKET") if err != nil { t.Errorf("\t\t%s Should not return error when valid key %q", failed, "SOCKET") } else { t.Logf("\t\t%s Should not return error when valid key %q", succeed, "SOCKET") if socket != "./tmp/sockets.po" { t.Errorf("\t\t%s Should have key %q with value %q", failed, "SOCKET", "./tmp/sockets.po") } else { t.Logf("\t\t%s Should have key %q with value %q", succeed, "SOCKET", "./tmp/sockets.po") } } port, err := cfg.Int("PORT") if err != nil { t.Errorf("\t\t%s Should not return error when valid key %q", failed, "PORT") } else { t.Logf("\t\t%s Should not return error when valid key %q", succeed, "PORT") if port != 4034 { t.Errorf("\t\t%s Should have key %q with value %d", failed, "PORT", 4034) } else { t.Logf("\t\t%s Should have key %q with value %d", succeed, "PORT", 4034) } } flag, err := cfg.Bool("FLAG") if err != nil { t.Errorf("\t\t%s Should not return error when valid key %q", failed, "FLAG") } else { t.Logf("\t\t%s Should not return error when valid key %q", succeed, "FLAG") if flag == false { t.Errorf("\t\t%s Should have key %q with value %v", failed, "FLAG", true) } else { t.Logf("\t\t%s Should have key %q with value %v", succeed, "FLAG", true) } } u, err := cfg.URL("DSN") if err != nil { t.Errorf("\t\t%s Should not return error when valid key %q", failed, "DSN") } else { t.Logf("\t\t%s Should not return error when valid key %q", succeed, "DSN") if u.String() != uStr { t.Errorf("\t\t%s Should have key %q with value %v", failed, "DSN", true) } else { t.Logf("\t\t%s Should have key %q with value %v", succeed, "DSN", true) } } } } }
// API returns a handler for a set of routes. func API() http.Handler { w := web.New(logm.Midware, errorm.Midware) publicKey, err := cfg.String(cfgAuthPublicKey) if err != nil || publicKey == "" { log.User("startup", "Init", "%s is missing, internal authentication is disabled", cfgAuthPublicKey) } // If the public key is provided then add the auth middleware or fail using // the provided public key. if publicKey != "" { log.Dev("startup", "Init", "Initializing Auth") authm, err := authm.Midware(publicKey, authm.MidwareOpts{}) if err != nil { log.Error("startup", "Init", err, "Initializing Auth") os.Exit(1) } // Apply the authentication middleware on top of the application as the // first middleware. w.Use(authm) } platformPrivateKey, err := cfg.String(cfgPlatformPrivateKey) if err != nil || platformPrivateKey == "" { log.User("startup", "Init", "%s is missing, downstream platform authentication is disabled", cfgPlatformPrivateKey) } // If the platformPrivateKey is provided, then we should generate the token // signing function to be used when composing requests down to the platform. if platformPrivateKey != "" { log.Dev("startup", "Init", "Initializing Downstream Platform Auth") signer, err := auth.NewSigner(platformPrivateKey) if err != nil { log.Error("startup", "Init", err, "Initializing Downstream Platform Auth") os.Exit(1) } // Requests can now be signed with the given signer function which we will // save on the application wide context. In the event that a function // requires a call down to a downstream platform, we will include a signed // header using the signer function here. w.Ctx["signer"] = signer } if cors, err := cfg.Bool(cfgEnableCORS); err == nil && cors { log.Dev("startup", "Init", "Initializing CORS : CORS Enabled") w.Use(w.CORS()) } else { log.Dev("startup", "Init", "CORS Disabled") } // We need the URL for the services Sponged and Xeniad that needs to be running. spongedURL, err = cfg.String(cfgSpongedURL) if err != nil || spongedURL == "" { log.Error("startup", "Init", err, "Service Sponged needs to be setup.") os.Exit(1) } w.Ctx["spongedURL"] = cfg.MustURL(cfgSpongedURL).String() xeniadURL, err = cfg.String(cfgXeniadURL) if err != nil || xeniadURL == "" { log.Error("startup", "Init", err, "Service Xeniad needs to be setup.") os.Exit(1) } w.Ctx["xeniadURL "] = cfg.MustURL(cfgXeniadURL).String() log.Dev("startup", "Init", "Initalizing routes") routes(w) return w }
// TestSets validates the ability to manually set configuration values. func TestSets(t *testing.T) { t.Log("Given the need to manually set configuration values.") { /* uStr := "postgres://*****:*****@127.0.0.1:8080/postgres?sslmode=disable" Map: map[string]string{ "PROC_ID": "322", "SOCKET": "./tmp/sockets.po", "PORT": "4034", "FLAG": "on", "DSN": uStr, }, */ cfg.Init(cfg.MapProvider{ Map: map[string]string{}, }) t.Log("\tWhen setting values.") { key := "key1" strVal := "bill" cfg.SetString(key, strVal) retStrVal, err := cfg.String(key) if err != nil { t.Errorf("\t\t%s Should find a value for the specified key %q.", failed, key) } else { t.Logf("\t\t%s Should find a value for the specified key %q.", success, key) } if strVal != retStrVal { t.Log(strVal) t.Log(retStrVal) t.Errorf("\t\t%s Should return the string value %q that was set.", failed, strVal) } else { t.Logf("\t\t%s Should return the string value %q that was set.", success, strVal) } key = "key2" intVal := 223 cfg.SetInt(key, intVal) retIntVal, err := cfg.Int(key) if err != nil { t.Errorf("\t\t%s Should find a value for the specified key %q.", failed, key) } else { t.Logf("\t\t%s Should find a value for the specified key %q.", success, key) } if intVal != retIntVal { t.Log(intVal) t.Log(retIntVal) t.Errorf("\t\t%s Should return the int value %d that was set.", failed, intVal) } else { t.Logf("\t\t%s Should return the int value %d that was set.", success, intVal) } key = "key3" timeVal, _ := time.Parse(time.UnixDate, "Mon Oct 27 20:18:15 EST 2016") cfg.SetTime(key, timeVal) retTimeVal, err := cfg.Time(key) if err != nil { t.Errorf("\t\t%s Should find a value for the specified key %q.", failed, key) } else { t.Logf("\t\t%s Should find a value for the specified key %q.", success, key) } if timeVal != retTimeVal { t.Log(timeVal) t.Log(retTimeVal) t.Errorf("\t\t%s Should return the time value %q that was set.", failed, timeVal) } else { t.Logf("\t\t%s Should return the time value %q that was set.", success, timeVal) } key = "key4" boolVal := true cfg.SetBool(key, boolVal) retBoolVal, err := cfg.Bool(key) if err != nil { t.Errorf("\t\t%s Should find a value for the specified key %q.", failed, key) } else { t.Logf("\t\t%s Should find a value for the specified key %q.", success, key) } if boolVal != retBoolVal { t.Log(boolVal) t.Log(retBoolVal) t.Errorf("\t\t%s Should return the bool value \"%v\" that was set.", failed, boolVal) } else { t.Logf("\t\t%s Should return the bool value \"%v\" that was set.", success, boolVal) } key = "key5" urlVal, _ := url.Parse("postgres://*****:*****@127.0.0.1:8080/postgres?sslmode=disable") cfg.SetURL(key, urlVal) retURLVal, err := cfg.URL(key) if err != nil { t.Errorf("\t\t%s Should find a value for the specified key %q.", failed, key) } else { t.Logf("\t\t%s Should find a value for the specified key %q.", success, key) } if urlVal.String() != retURLVal.String() { t.Log(urlVal) t.Log(retURLVal) t.Errorf("\t\t%s Should return the bool value \"%v\" that was set.", failed, urlVal) } else { t.Logf("\t\t%s Should return the bool value \"%v\" that was set.", success, urlVal) } } } }