From 7a9e5112eaaea58d55f181d3e5296e4ff839921c Mon Sep 17 00:00:00 2001 From: jloup Date: Wed, 14 Feb 2018 14:19:09 +0100 Subject: initial commit --- cmd/app/Makefile | 30 +++++++++++ cmd/app/conf.toml | 16 ++++++ cmd/app/main.go | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 cmd/app/Makefile create mode 100644 cmd/app/conf.toml create mode 100644 cmd/app/main.go (limited to 'cmd/app') diff --git a/cmd/app/Makefile b/cmd/app/Makefile new file mode 100644 index 0000000..628910f --- /dev/null +++ b/cmd/app/Makefile @@ -0,0 +1,30 @@ +# Go parameters +GOCMD=go +GOBUILD=$(GOCMD) build +GOCLEAN=$(GOCMD) clean +GOTEST=$(GOCMD) test +BINARY_NAME=cryptoportfolio-app +LINUX_ARCHES=amd64 386 +DIST_DIR ?= dist + +build: + $(GOBUILD) -o $(BINARY_NAME) -v + +test: + $(GOTEST) -v ./... + +clean: + $(GOCLEAN) + rm -f $(BINARY_NAME) + rm -rf dist + +run: build + ./$(BINARY_NAME) + +$(addprefix $(DIST_DIR)/linux_, $(LINUX_ARCHES)): + mkdir -p $(@) + CGO_ENABLED=0 GOOS=linux GOARCH=$(subst linux_,,$(notdir $@)) $(GOBUILD) -o $@/$(BINARY_NAME) -v + +release: $(addprefix $(DIST_DIR)/linux_, $(LINUX_ARCHES)) + +.PHONY: clean release diff --git a/cmd/app/conf.toml b/cmd/app/conf.toml new file mode 100644 index 0000000..47964b4 --- /dev/null +++ b/cmd/app/conf.toml @@ -0,0 +1,16 @@ +log_level="info" +mode="dev" +log_out="stdout" + +[db] +user="cryptoportfolio" +password="cryptoportfolio-dev" +database="cryptoportfolio" +address="localhost:5432" + +[api] +domain="localhost" +jwt_secret="secret" + +[app] +public_dir="../web/build/static" diff --git a/cmd/app/main.go b/cmd/app/main.go new file mode 100644 index 0000000..e769401 --- /dev/null +++ b/cmd/app/main.go @@ -0,0 +1,155 @@ +package main + +import ( + "fmt" + "path" + "strings" + "time" + + "immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front/api" + "immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front/db" + + "github.com/gin-contrib/cors" + "github.com/gin-gonic/gin" + "github.com/jloup/utils" +) + +var log = utils.StandardL().WithField("module", "api") + +type AppConfig struct { + PublicDir string `toml:"public_dir"` +} + +type ApiConfig struct { + Domain string `toml:"domain"` + JwtSecret string `toml:"jwt_secret"` +} + +type Config struct { + App AppConfig + Api ApiConfig + Db db.DBConfig + + utils.LogConfiguration + Address string + Port string + Mode string +} + +func (c *Config) SetToDefaults() { + *c = Config{ + Address: "localhost", + Port: "8000", + Mode: "dev", + App: AppConfig{ + PublicDir: "./public", + }, + Api: ApiConfig{ + JwtSecret: "secret", + }, + } + + c.LogConfiguration.SetToDefaults() +} + +var C Config + +func init() { + utils.MustParseStdConfigFile(&C) + + err := utils.ConfigureStdLogger(C.LogConfiguration) + if err != nil { + panic(err) + } + + api.SetJwtSecretKey(C.Api.JwtSecret) + + db.Init(C.Db) + + if C.Mode == "production" { + gin.SetMode(gin.ReleaseMode) + } + + log.Infof("CONFIG:") + log.Infof("LISTEN: %s", strings.Join([]string{C.Address, C.Port}, ":")) + log.Infof("PUBLIC_DIR: %s", C.App.PublicDir) +} + +func SetApiRoute(router *gin.RouterGroup, route api.Route) { + switch route.Method { + case "GET": + router.GET(route.Path, route.Handlers...) + case "POST": + router.POST(route.Path, route.Handlers...) + case "OPTIONS": + router.OPTIONS(route.Path, route.Handlers...) + default: + panic(fmt.Errorf("%s method not handled", route.Method)) + } +} + +func SetGroup(router *gin.RouterGroup, group api.Group) { + var r *gin.RouterGroup + if group.Root == "" { + r = router + } else { + r = router.Group(group.Root) + } + + if group.Middlewares != nil { + for _, middleware := range group.Middlewares { + r.Use(api.M(middleware)) + } + } + + for _, route := range group.Routes { + SetApiRoute(r, route) + } +} + +func main() { + engine := gin.New() + + apiGroup := engine.Group("/api") + appGroup := engine + + engine.Use(gin.Recovery()) + + if C.Mode == "production" { + engine.Use(api.Logger()) + apiGroup.Use(api.Logger()) + } else { + engine.Use(gin.Logger()) + apiGroup.Use(gin.Logger()) + } + + apiGroup.Use(cors.New(cors.Config{ + AllowOrigins: []string{fmt.Sprintf("https://%s", C.Api.Domain)}, + AllowMethods: []string{"POST", "GET", "OPTIONS"}, + AllowHeaders: []string{"Authorization"}, + ExposeHeaders: []string{"Authorization"}, + AllowCredentials: true, + MaxAge: 12 * time.Hour, + })) + + for _, group := range api.Groups { + SetGroup(apiGroup, group) + } + + appGroup.Static("/public", C.App.PublicDir) + availableRoutes := []string{ + "/", + "/signup", + "/signin", + "/signout", + "/me", + "/otp/enroll", + "/otp/validate", + } + + for _, route := range availableRoutes { + appGroup.StaticFile(route, path.Join(C.App.PublicDir, "/index.html")) + } + + engine.Run(strings.Join([]string{C.Address, C.Port}, ":")) +} -- cgit v1.2.3