package main import ( "fmt" "path" "strings" "time" "git.immae.eu/Cryptoportfolio/Front.git/api" "git.immae.eu/Cryptoportfolio/Front.git/db" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "github.com/jloup/utils" "github.com/wercker/journalhook" ) var log = utils.StandardL().WithField("module", "api") type AppConfig struct { PublicDir string `toml:"public_dir"` } type ApiConfig struct { api.Config } type Config struct { App AppConfig Api ApiConfig Mail api.MailConfig 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) } if C.Mode == "prod" { gin.DisableConsoleColor() gin.SetMode(gin.ReleaseMode) journalhook.Enable() } api.SetConfig(C.Api.Config) api.SetMailConfig(C.Mail) db.Init(C.Db, C.Redis) 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 == "prod" { 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", "/confirm", "/reset-password", "/change-password", "/signout", "/me", "/admin", "/account", "/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}, ":")) }