//GetRouter contructs the router hierarchy and registers all handlers and middleware func GetRouter() http.Handler { r := mux.NewRouter().StrictSlash(true) siteservice := siteservice.NewService() siteservice.AddRoutes(r) apiRouter := r.PathPrefix("/api").Subrouter() identityservice.NewService().AddRoutes(apiRouter) oauthservice.NewService(siteservice).AddRoutes(r) // Add middlewares router := NewRouter(r) dbmw := db.DBMiddleware() recovery := handlers.RecoveryHandler() router.Use(recovery, LoggingMiddleware, dbmw) return router.Handler() }
func main() { app := cli.NewApp() app.Name = "Identity server" app.Version = "0.1-Dev" log.SetFormatter(&log.TextFormatter{FullTimestamp: true}) var debugLogging, ignoreDevcert bool var bindAddress, dbConnectionString string var tlsCert, tlsKey string var twilioAccountSID, twilioAuthToken, twilioMessagingServiceSID string var smtpserver, smtpuser, smtppassword string var smtpport int app.Flags = []cli.Flag{ cli.BoolFlag{ Name: "debug, d", Usage: "Enable debug logging", Destination: &debugLogging, }, cli.StringFlag{ Name: "bind, b", Usage: "Bind address", Value: ":8443", Destination: &bindAddress, }, cli.StringFlag{ Name: "connectionstring, c", Usage: "Mongodb connection string", Value: "127.0.0.1:27017", Destination: &dbConnectionString, }, cli.StringFlag{ Name: "cert, s", Usage: "TLS certificate path", Value: "", Destination: &tlsCert, }, cli.StringFlag{ Name: "key, k", Usage: "TLS private key path", Value: "", Destination: &tlsKey, }, cli.BoolFlag{ Name: "ignore-devcert, i", Usage: "Ignore default devcert even if exists", Destination: &ignoreDevcert, }, cli.StringFlag{ Name: "twilio-AccountSID", Usage: "Twilio AccountSID", Destination: &twilioAccountSID, }, cli.StringFlag{ Name: "twilio-AuthToken", Usage: "Twilio AuthToken", Destination: &twilioAuthToken, }, cli.StringFlag{ Name: "twilio-MsgSvcSID", Usage: "Twilio MessagingServiceSID", Destination: &twilioMessagingServiceSID, }, cli.StringFlag{ Name: "smtp-server", Usage: "Host of smtp server", Destination: &smtpserver, }, cli.StringFlag{ Name: "smtp-user", Usage: "User to login smtp server", Destination: &smtpuser, }, cli.StringFlag{ Name: "smtp-password", Usage: "Password of smtp server", Destination: &smtppassword, }, cli.IntFlag{ Name: "smtp-port", Usage: "Port of smtp server", Destination: &smtpport, Value: 587, }, } app.Before = func(c *cli.Context) error { if debugLogging { log.SetLevel(log.DebugLevel) log.Debug("Debug logging enabled") log.Debug(app.Name, "-", app.Version) } return nil } app.Action = func(c *cli.Context) { // Connect to DB! go db.Connect(dbConnectionString) defer db.Close() cookieSecret := identityservice.GetCookieSecret() var smsService communication.SMSService var emailService communication.EmailService if twilioAccountSID != "" { smsService = &communication.TwilioSMSService{ AccountSID: twilioAccountSID, AuthToken: twilioAuthToken, MessagingServiceSID: twilioMessagingServiceSID, } } else { log.Warn("============================================================================") log.Warn("No valid Twilio Account provided, falling back to development implementation") log.Warn("============================================================================") smsService = &communication.DevSMSService{} } if smtpserver == "" { log.Warn("============================================================================") log.Warn("No valid SMTP server provided, falling back to development implementation") log.Warn("============================================================================") emailService = &communication.DevEmailService{} } else { emailService = communication.NewSMTPEmailService(smtpserver, smtpport, smtpuser, smtppassword) } sc := siteservice.NewService(cookieSecret, smsService, emailService) is := identityservice.NewService(smsService, emailService) config := globalconfig.NewManager() var jwtKey []byte var err error exists, err := config.Exists("jwtkey") if err == nil && exists { var jwtKeyConfig *globalconfig.GlobalConfig jwtKeyConfig, err = config.GetByKey("jwtkey") jwtKey = []byte(jwtKeyConfig.Value) } else { if err == nil { if _, e := os.Stat("devcert/jwt_key.pem"); e == nil { log.Warning("===============================================================================") log.Warning("This instance uses a development JWT signing key, don't do this in production !") log.Warning("===============================================================================") jwtKey, err = ioutil.ReadFile("devcert/jwt_key.pem") } } } if err != nil { log.Fatal("Unable to load a valid key for signing JWT's: ", err) } ecdsaKey, err := jwt.ParseECPrivateKeyFromPEM(jwtKey) if err != nil { log.Fatal("Unable to load a valid key for signing JWT's: ", err) } security.JWTPublicKey = ecdsaKey.PublicKey oauthsc, err := oauthservice.NewService(sc, is, ecdsaKey) if err != nil { log.Fatal("Unable to create the oauthservice: ", err) } r := routes.GetRouter(sc, is, oauthsc) server := https.PrepareHTTP(bindAddress, r) https.PrepareHTTPS(server, tlsCert, tlsKey, ignoreDevcert) // Go make magic over HTTPS log.Info("Listening (https) on ", bindAddress) log.Fatal(server.ListenAndServeTLS("", "")) } app.Run(os.Args) }