aboutsummaryrefslogtreecommitdiff
path: root/cmd/app
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/app')
-rw-r--r--cmd/app/Makefile30
-rw-r--r--cmd/app/conf.toml16
-rw-r--r--cmd/app/main.go155
3 files changed, 201 insertions, 0 deletions
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 @@
1# Go parameters
2GOCMD=go
3GOBUILD=$(GOCMD) build
4GOCLEAN=$(GOCMD) clean
5GOTEST=$(GOCMD) test
6BINARY_NAME=cryptoportfolio-app
7LINUX_ARCHES=amd64 386
8DIST_DIR ?= dist
9
10build:
11 $(GOBUILD) -o $(BINARY_NAME) -v
12
13test:
14 $(GOTEST) -v ./...
15
16clean:
17 $(GOCLEAN)
18 rm -f $(BINARY_NAME)
19 rm -rf dist
20
21run: build
22 ./$(BINARY_NAME)
23
24$(addprefix $(DIST_DIR)/linux_, $(LINUX_ARCHES)):
25 mkdir -p $(@)
26 CGO_ENABLED=0 GOOS=linux GOARCH=$(subst linux_,,$(notdir $@)) $(GOBUILD) -o $@/$(BINARY_NAME) -v
27
28release: $(addprefix $(DIST_DIR)/linux_, $(LINUX_ARCHES))
29
30.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 @@
1log_level="info"
2mode="dev"
3log_out="stdout"
4
5[db]
6user="cryptoportfolio"
7password="cryptoportfolio-dev"
8database="cryptoportfolio"
9address="localhost:5432"
10
11[api]
12domain="localhost"
13jwt_secret="secret"
14
15[app]
16public_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 @@
1package main
2
3import (
4 "fmt"
5 "path"
6 "strings"
7 "time"
8
9 "immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front/api"
10 "immae.eu/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front/db"
11
12 "github.com/gin-contrib/cors"
13 "github.com/gin-gonic/gin"
14 "github.com/jloup/utils"
15)
16
17var log = utils.StandardL().WithField("module", "api")
18
19type AppConfig struct {
20 PublicDir string `toml:"public_dir"`
21}
22
23type ApiConfig struct {
24 Domain string `toml:"domain"`
25 JwtSecret string `toml:"jwt_secret"`
26}
27
28type Config struct {
29 App AppConfig
30 Api ApiConfig
31 Db db.DBConfig
32
33 utils.LogConfiguration
34 Address string
35 Port string
36 Mode string
37}
38
39func (c *Config) SetToDefaults() {
40 *c = Config{
41 Address: "localhost",
42 Port: "8000",
43 Mode: "dev",
44 App: AppConfig{
45 PublicDir: "./public",
46 },
47 Api: ApiConfig{
48 JwtSecret: "secret",
49 },
50 }
51
52 c.LogConfiguration.SetToDefaults()
53}
54
55var C Config
56
57func init() {
58 utils.MustParseStdConfigFile(&C)
59
60 err := utils.ConfigureStdLogger(C.LogConfiguration)
61 if err != nil {
62 panic(err)
63 }
64
65 api.SetJwtSecretKey(C.Api.JwtSecret)
66
67 db.Init(C.Db)
68
69 if C.Mode == "production" {
70 gin.SetMode(gin.ReleaseMode)
71 }
72
73 log.Infof("CONFIG:")
74 log.Infof("LISTEN: %s", strings.Join([]string{C.Address, C.Port}, ":"))
75 log.Infof("PUBLIC_DIR: %s", C.App.PublicDir)
76}
77
78func SetApiRoute(router *gin.RouterGroup, route api.Route) {
79 switch route.Method {
80 case "GET":
81 router.GET(route.Path, route.Handlers...)
82 case "POST":
83 router.POST(route.Path, route.Handlers...)
84 case "OPTIONS":
85 router.OPTIONS(route.Path, route.Handlers...)
86 default:
87 panic(fmt.Errorf("%s method not handled", route.Method))
88 }
89}
90
91func SetGroup(router *gin.RouterGroup, group api.Group) {
92 var r *gin.RouterGroup
93 if group.Root == "" {
94 r = router
95 } else {
96 r = router.Group(group.Root)
97 }
98
99 if group.Middlewares != nil {
100 for _, middleware := range group.Middlewares {
101 r.Use(api.M(middleware))
102 }
103 }
104
105 for _, route := range group.Routes {
106 SetApiRoute(r, route)
107 }
108}
109
110func main() {
111 engine := gin.New()
112
113 apiGroup := engine.Group("/api")
114 appGroup := engine
115
116 engine.Use(gin.Recovery())
117
118 if C.Mode == "production" {
119 engine.Use(api.Logger())
120 apiGroup.Use(api.Logger())
121 } else {
122 engine.Use(gin.Logger())
123 apiGroup.Use(gin.Logger())
124 }
125
126 apiGroup.Use(cors.New(cors.Config{
127 AllowOrigins: []string{fmt.Sprintf("https://%s", C.Api.Domain)},
128 AllowMethods: []string{"POST", "GET", "OPTIONS"},
129 AllowHeaders: []string{"Authorization"},
130 ExposeHeaders: []string{"Authorization"},
131 AllowCredentials: true,
132 MaxAge: 12 * time.Hour,
133 }))
134
135 for _, group := range api.Groups {
136 SetGroup(apiGroup, group)
137 }
138
139 appGroup.Static("/public", C.App.PublicDir)
140 availableRoutes := []string{
141 "/",
142 "/signup",
143 "/signin",
144 "/signout",
145 "/me",
146 "/otp/enroll",
147 "/otp/validate",
148 }
149
150 for _, route := range availableRoutes {
151 appGroup.StaticFile(route, path.Join(C.App.PublicDir, "/index.html"))
152 }
153
154 engine.Run(strings.Join([]string{C.Address, C.Port}, ":"))
155}