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 { api.Config Domain string `toml:"domain"` } type Config struct { App AppConfig Api ApiConfig Db db.DBConfig Redis db.RedisConfig utils.LogConfiguration Address string Port string Mode string } func (c *Config) SetToDefaults() { *c = Config{ Address: "localhost", Port: "8000", Mode: "dev", App: AppConfig{ PublicDir: "./public", }, } c.LogConfiguration.SetToDefaults() } var C Config func init() { utils.MustParseStdConfigFile(&C) err := utils.ConfigureStdLogger(C.LogConfiguration) if err != nil { panic(err) } api.SetConfig(C.Api.Config) db.Init(C.Db, C.Redis) 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", "/reset-password", "/change-password", "/signout", "/me", "/otp/enroll", "/otp/validate", "/not_confirmed", } for _, route := range availableRoutes { appGroup.StaticFile(route, path.Join(C.App.PublicDir, "/index.html")) } engine.Run(strings.Join([]string{C.Address, C.Port}, ":")) }