From 433c7a82884ff956526d41ba35d85472794fc808 Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Wed, 16 Jan 2019 12:39:12 +0100 Subject: [PATCH] upd(sam): restructure routes for consistency --- sam/routes.go | 34 ++++++++++++++++++++++++- sam/start.go | 66 +++++++++++++++++-------------------------------- system/start.go | 4 +-- 3 files changed, 57 insertions(+), 47 deletions(-) diff --git a/sam/routes.go b/sam/routes.go index d7d4b512c..282a19c45 100644 --- a/sam/routes.go +++ b/sam/routes.go @@ -1,22 +1,43 @@ 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" + "github.com/crusttech/crust/sam/websocket" ) -func mountRoutes(r chi.Router, opts *config.HTTP, mounts ...func(r chi.Router)) { +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(), websocket.MountRoutes(ctx, flags.repository)) + }) + + 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) } @@ -59,3 +80,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/sam/start.go b/sam/start.go index e6b77f853..088590b29 100644 --- a/sam/start.go +++ b/sam/start.go @@ -5,25 +5,28 @@ 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" "github.com/crusttech/crust/internal/mail" migrate "github.com/crusttech/crust/sam/db" - "github.com/crusttech/crust/sam/rest" - samService "github.com/crusttech/crust/sam/service" - "github.com/crusttech/crust/sam/websocket" systemService "github.com/crusttech/crust/system/service" "github.com/crusttech/crust/internal/auth" "github.com/crusttech/crust/internal/metrics" "github.com/crusttech/crust/internal/version" + "github.com/crusttech/crust/sam/service" +) + +var ( + jwtVerifier (func(http.Handler) http.Handler) + jwtAuthenticator (func(http.Handler) http.Handler) + jwtEncoder auth.TokenEncoder ) func Init() error { @@ -31,22 +34,27 @@ func Init() error { 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 @@ -64,56 +72,26 @@ func Init() error { }) systemService.Init() - samService.Init() + service.Init() return nil } func Start() error { - deadline := sigctx.New() - - log.Printf("Starting sam, 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(), websocket.MountRoutes(ctx.AsContext(deadline), flags.repository)) - }) - - 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/system/start.go b/system/start.go index 4c697c695..382c64198 100644 --- a/system/start.go +++ b/system/start.go @@ -15,7 +15,7 @@ import ( "github.com/crusttech/crust/internal/mail" migrate "github.com/crusttech/crust/system/db" - "github.com/crusttech/crust/system/service" + systemService "github.com/crusttech/crust/system/service" "github.com/crusttech/crust/internal/auth" "github.com/crusttech/crust/internal/metrics" @@ -70,7 +70,7 @@ func Init() error { }, }) - service.Init() + systemService.Init() return nil }