]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git/blob - cmd/app/main.go
65e8b5a49af92b4dbda73472595b33883aebea77
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git] / cmd / app / main.go
1 package main
2
3 import (
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
17 var log = utils.StandardL().WithField("module", "api")
18
19 type AppConfig struct {
20 PublicDir string `toml:"public_dir"`
21 }
22
23 type ApiConfig struct {
24 Domain string `toml:"domain"`
25 JwtSecret string `toml:"jwt_secret"`
26 }
27
28 type Config struct {
29 App AppConfig
30 Api ApiConfig
31 Db db.DBConfig
32 Redis db.RedisConfig
33
34 utils.LogConfiguration
35 Address string
36 Port string
37 Mode string
38 }
39
40 func (c *Config) SetToDefaults() {
41 *c = Config{
42 Address: "localhost",
43 Port: "8000",
44 Mode: "dev",
45 App: AppConfig{
46 PublicDir: "./public",
47 },
48 Api: ApiConfig{
49 JwtSecret: "secret",
50 },
51 }
52
53 c.LogConfiguration.SetToDefaults()
54 }
55
56 var C Config
57
58 func init() {
59 utils.MustParseStdConfigFile(&C)
60
61 err := utils.ConfigureStdLogger(C.LogConfiguration)
62 if err != nil {
63 panic(err)
64 }
65
66 api.SetJwtSecretKey(C.Api.JwtSecret)
67
68 db.Init(C.Db, C.Redis)
69
70 if C.Mode == "production" {
71 gin.SetMode(gin.ReleaseMode)
72 }
73
74 log.Infof("CONFIG:")
75 log.Infof("LISTEN: %s", strings.Join([]string{C.Address, C.Port}, ":"))
76 log.Infof("PUBLIC_DIR: %s", C.App.PublicDir)
77 }
78
79 func SetApiRoute(router *gin.RouterGroup, route api.Route) {
80 switch route.Method {
81 case "GET":
82 router.GET(route.Path, route.Handlers...)
83 case "POST":
84 router.POST(route.Path, route.Handlers...)
85 case "OPTIONS":
86 router.OPTIONS(route.Path, route.Handlers...)
87 default:
88 panic(fmt.Errorf("%s method not handled", route.Method))
89 }
90 }
91
92 func SetGroup(router *gin.RouterGroup, group api.Group) {
93 var r *gin.RouterGroup
94 if group.Root == "" {
95 r = router
96 } else {
97 r = router.Group(group.Root)
98 }
99
100 if group.Middlewares != nil {
101 for _, middleware := range group.Middlewares {
102 r.Use(api.M(middleware))
103 }
104 }
105
106 for _, route := range group.Routes {
107 SetApiRoute(r, route)
108 }
109 }
110
111 func main() {
112 engine := gin.New()
113
114 apiGroup := engine.Group("/api")
115 appGroup := engine
116
117 engine.Use(gin.Recovery())
118
119 if C.Mode == "production" {
120 engine.Use(api.Logger())
121 apiGroup.Use(api.Logger())
122 } else {
123 engine.Use(gin.Logger())
124 apiGroup.Use(gin.Logger())
125 }
126
127 apiGroup.Use(cors.New(cors.Config{
128 AllowOrigins: []string{fmt.Sprintf("https://%s", C.Api.Domain)},
129 AllowMethods: []string{"POST", "GET", "OPTIONS"},
130 AllowHeaders: []string{"Authorization"},
131 ExposeHeaders: []string{"Authorization"},
132 AllowCredentials: true,
133 MaxAge: 12 * time.Hour,
134 }))
135
136 for _, group := range api.Groups {
137 SetGroup(apiGroup, group)
138 }
139
140 appGroup.Static("/public", C.App.PublicDir)
141 availableRoutes := []string{
142 "/",
143 "/signup",
144 "/signin",
145 "/signout",
146 "/me",
147 "/otp/enroll",
148 "/otp/validate",
149 "/not_confirmed",
150 }
151
152 for _, route := range availableRoutes {
153 appGroup.StaticFile(route, path.Join(C.App.PublicDir, "/index.html"))
154 }
155
156 engine.Run(strings.Join([]string{C.Address, C.Port}, ":"))
157 }