From 5e6100d83a5c17ace32f8548460f9e11dab6be04 Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Wed, 16 Jan 2019 12:54:50 +0100 Subject: [PATCH] upd(crm): update routes for consistency, middleware --- crm/rest/router.go | 2 +- crm/routes.go | 33 +++++++++++++++++++++++ crm/start.go | 66 ++++++++++++++++------------------------------ sam/start.go | 2 +- system/start.go | 2 +- 5 files changed, 59 insertions(+), 46 deletions(-) diff --git a/crm/rest/router.go b/crm/rest/router.go index caeebce47..e9f818d9e 100644 --- a/crm/rest/router.go +++ b/crm/rest/router.go @@ -7,7 +7,7 @@ import ( "github.com/crusttech/crust/internal/auth" ) -func MountRoutes(jwtAuth auth.TokenEncoder) func(chi.Router) { +func MountRoutes() func(chi.Router) { var ( module = Module{}.New() page = Page{}.New() diff --git a/crm/routes.go b/crm/routes.go index 4a8305f78..baae32779 100644 --- a/crm/routes.go +++ b/crm/routes.go @@ -1,19 +1,41 @@ package service import ( + "context" "fmt" "reflect" "runtime" + "net/http" + "github.com/99designs/basicauth-go" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" + "github.com/go-chi/cors" "github.com/crusttech/crust/internal/config" "github.com/crusttech/crust/internal/metrics" "github.com/crusttech/crust/internal/version" + "github.com/crusttech/crust/sam/rest" ) +func Routes(ctx context.Context) *chi.Mux { + r := chi.NewRouter() + r.Use(handleCORS) + r.Use(middleware.RealIP) + r.Use(middleware.RequestID) + + // Only protect application routes with JWT + r.Group(func(r chi.Router) { + r.Use(jwtVerifier, jwtAuthenticator) + mountRoutes(r, flags.http, rest.MountRoutes()) + }) + + printRoutes(r, flags.http) + mountSystemRoutes(r, flags.http) + return r +} + func mountRoutes(r chi.Router, opts *config.HTTP, mounts ...func(r chi.Router)) { if opts.Logging { r.Use(middleware.Logger) @@ -57,3 +79,14 @@ func printRoutes(r chi.Router, opts *config.HTTP) { } printRoutes(r, "", "") } + +// Sets up default CORS rules to use as a middleware +func handleCORS(next http.Handler) http.Handler { + return cors.New(cors.Options{ + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"}, + AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"}, + AllowCredentials: true, + MaxAge: 300, // Maximum value not ignored by any of major browsers + }).Handler(next) +} diff --git a/crm/start.go b/crm/start.go index eac4e3bbf..c761438ef 100644 --- a/crm/start.go +++ b/crm/start.go @@ -5,46 +5,56 @@ import ( "log" "net" "net/http" + "os" + "github.com/SentimensRG/ctx" "github.com/SentimensRG/ctx/sigctx" - "github.com/go-chi/chi" - "github.com/go-chi/cors" "github.com/pkg/errors" "github.com/titpetric/factory" "github.com/titpetric/factory/resputil" migrate "github.com/crusttech/crust/crm/db" - "github.com/crusttech/crust/crm/rest" - crmService "github.com/crusttech/crust/crm/service" systemService "github.com/crusttech/crust/system/service" + "github.com/crusttech/crust/crm/service" "github.com/crusttech/crust/internal/auth" "github.com/crusttech/crust/internal/mail" "github.com/crusttech/crust/internal/metrics" "github.com/crusttech/crust/internal/version" ) +var ( + jwtVerifier (func(http.Handler) http.Handler) + jwtAuthenticator (func(http.Handler) http.Handler) + jwtEncoder auth.TokenEncoder +) + func Init() error { // validate configuration if err := flags.Validate(); err != nil { return err } + // JWT Auth + if jwtAuth, err := auth.JWT(); err != nil { + return errors.Wrap(err, "Error creating JWT Auth object") + } else { + jwtEncoder = jwtAuth + jwtVerifier = jwtAuth.Verifier() + jwtAuthenticator = jwtAuth.Authenticator() + } mail.SetupDialer(flags.smtp) // start/configure database connection factory.Database.Add("default", flags.db.DSN) - db, err := factory.Database.Get() - if err != nil { - return err - } + db := factory.Database.MustGet() // @todo: profiling as an external service? switch flags.db.Profiler { case "stdout": db.Profiler = &factory.Database.ProfilerStdout default: - fmt.Println("No database query profiler selected") + log.Println("No database query profiler selected") } // migrate database schema @@ -62,56 +72,26 @@ func Init() error { }) systemService.Init() - crmService.Init() + service.Init() return nil } func Start() error { - var deadline = sigctx.New() - - log.Printf("Starting crm, version: %v, built on: %v", version.Version, version.BuildTime) + log.Printf("Starting "+os.Args[0]+", version: %v, built on: %v", version.Version, version.BuildTime) log.Println("Starting http server on address " + flags.http.Addr) listener, err := net.Listen("tcp", flags.http.Addr) if err != nil { return errors.Wrap(err, fmt.Sprintf("Can't listen on addr %s", flags.http.Addr)) } - // JWT Auth - jwtAuth, err := auth.JWT() - if err != nil { - return errors.Wrap(err, "Error creating JWT Auth object") - } - - r := chi.NewRouter() - r.Use(handleCORS) - - // Only protect application routes with JWT - r.Group(func(r chi.Router) { - r.Use(jwtAuth.Verifier(), jwtAuth.Authenticator()) - mountRoutes(r, flags.http, rest.MountRoutes(jwtAuth)) - }) - - printRoutes(r, flags.http) - mountSystemRoutes(r, flags.http) - if flags.monitor.Interval > 0 { go metrics.NewMonitor(flags.monitor.Interval) } - go http.Serve(listener, r) + var deadline = sigctx.New() + go http.Serve(listener, Routes(ctx.AsContext(deadline))) <-deadline.Done() return nil } - -// Sets up default CORS rules to use as a middleware -func handleCORS(next http.Handler) http.Handler { - return cors.New(cors.Options{ - AllowedOrigins: []string{"*"}, - AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"}, - AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"}, - AllowCredentials: true, - MaxAge: 300, // Maximum value not ignored by any of major browsers - }).Handler(next) -} diff --git a/sam/start.go b/sam/start.go index 088590b29..d34ab565d 100644 --- a/sam/start.go +++ b/sam/start.go @@ -13,11 +13,11 @@ import ( "github.com/titpetric/factory" "github.com/titpetric/factory/resputil" - "github.com/crusttech/crust/internal/mail" migrate "github.com/crusttech/crust/sam/db" systemService "github.com/crusttech/crust/system/service" "github.com/crusttech/crust/internal/auth" + "github.com/crusttech/crust/internal/mail" "github.com/crusttech/crust/internal/metrics" "github.com/crusttech/crust/internal/version" "github.com/crusttech/crust/sam/service" diff --git a/system/start.go b/system/start.go index 382c64198..813807d7c 100644 --- a/system/start.go +++ b/system/start.go @@ -13,11 +13,11 @@ import ( "github.com/titpetric/factory" "github.com/titpetric/factory/resputil" - "github.com/crusttech/crust/internal/mail" migrate "github.com/crusttech/crust/system/db" systemService "github.com/crusttech/crust/system/service" "github.com/crusttech/crust/internal/auth" + "github.com/crusttech/crust/internal/mail" "github.com/crusttech/crust/internal/metrics" "github.com/crusttech/crust/internal/version" )