package main import ( "InfantrySkillCalculator/controllers" "InfantrySkillCalculator/models" "InfantrySkillCalculator/utils" "github.com/gin-gonic/gin" _ "github.com/gorilla/sessions" "github.com/sirupsen/logrus" "gopkg.in/natefinch/lumberjack.v2" "html/template" "io" "os" "session" "strings" "time" ) func init() { fileLogger := &lumberjack.Logger{ Filename: "isc_rest.log", MaxSize: 50, // megabytes MaxBackups: 3, MaxAge: 28, //days Compress: true, } ginWriter := io.MultiWriter(fileLogger, os.Stdout) logger := logrus.New() logger.SetOutput(ginWriter) logger.SetFormatter(&logrus.TextFormatter{ ForceColors: true, FullTimestamp: true, }) utils.Logger = logger var err error utils.MainPageTemplates, err = template.ParseFiles( "./templates/index.html", "./templates/components/home_clan_bar.html", "./templates/components/opp_clan_bar.html", "./templates/components/home_player_list.html", "./templates/components/opp_player_list.html", "./templates/components/bottom_controls.html", "./templates/modals/delete_clan.html", "./templates/modals/add_clan.html", "./templates/modals/edit_clan.html", "./templates/modals/add_player.html", "./templates/modals/delete_player.html", "./templates/modals/edit_player.html", "./templates/modals/single_calc.html", //"./templates/modals/settings.html", "./templates/modals/full_calc.html", "./templates/components/header.html", ) if err != nil { logger.Fatalf("[MAIN] Error parsing main page templates: %v", err) } utils.LoginPageTemplates, err = template.ParseFiles( "./templates/login.html", "./templates/components/header.html", ) if err != nil { logger.Fatalf("[MAIN] Error parsing login page templates: %v", err) } utils.RegisterPageTemplates, err = template.ParseFiles( "./templates/register.html", "./templates/components/header.html", ) if err != nil { logger.Fatalf("[MAIN] Error parsing register page templates: %v", err) } utils.PlayerItemTemplate, err = template.ParseFiles( "./templates/shards/player_list_item.html", ) if err != nil { logger.Fatalf("[MAIN] Error parsing player list item template: %v", err) } controllers.LoadMetrics() } func customLogrusLogger(logger *logrus.Logger) gin.HandlerFunc { return func(c *gin.Context) { start := time.Now() c.Next() elapsed := time.Since(start) if c.Request.URL.Path == "/static" || c.Request.URL.Path == "/favicon.ico" || strings.Contains(c.Request.URL.Path, "_html") { return } username, exists := session.GetUsername(c) if !exists { username = "Anonymous" } logger.Infof("[GIN] %3d | %10.3fms | %15s | %15s | %15s | %-7s | %s", c.Writer.Status(), float64(elapsed.Microseconds())/1000.0, c.ClientIP(), c.Request.Header.Get("X-Forwarded-For"), username, c.Request.Method, c.Request.RequestURI, ) } } func main() { if os.Getenv("GO_ENV") == "production" { gin.SetMode(gin.ReleaseMode) } router := gin.New() err := router.SetTrustedProxies([]string{"127.0.0.1"}) if err != nil { utils.Logger.Fatalf("[MAIN] Error setting trusted proxies: %v", err) } router.LoadHTMLGlob("templates/**/*") reader := router.Group("/") reader.Use(ReaderAuthRequired()) author := router.Group("/") author.Use(AuthorAuthRequired()) admin := router.Group("/admin") admin.Use(AdminAuthRequired()) models.ConnectDatabase() models.ConnectCache(utils.PlayerCacheLifetime, controllers.UpdateCacheAfterExpiry) var code models.ActivationCode if err := models.DB.First(&code).Error; err != nil { firstCode := utils.GenerateActivationCode() models.DB.Create(&models.ActivationCode{Code: firstCode, UserRole: models.AdminRole}) utils.Logger.Println("[MAIN] Created first activation code with ADMIN role:\n" + firstCode) } router.Static("/static", "./static") middlewares := []gin.HandlerFunc{ customLogrusLogger(utils.Logger), gin.Recovery(), } router.Use(middlewares...) reader.Use(middlewares...) author.Use(middlewares...) admin.Use(middlewares...) router.GET("/login", loginPage) router.POST("/login", loginPost) router.GET("/logout", logout) router.GET("/register", registerPage) router.POST("/register", registerPost) reader.GET("/", mainPage) reader.GET("/clans", controllers.GetAllClans) reader.GET("/clans_html", controllers.GetAllClansHTML) reader.GET("/clan/:id", controllers.GetClanByID) author.POST("/clan", controllers.AddClan) author.PATCH("/clan/:id", controllers.UpdateClanByID) author.DELETE("/clan/:id", controllers.DeleteClanByID) reader.GET("/players", controllers.GetAllPlayers) reader.GET("/players_html", controllers.GetPlayersByClanHTML) reader.GET("/player/:id", controllers.GetPlayerByID) author.POST("/player", controllers.AddPlayer) author.PATCH("/player/:id", controllers.UpdatePlayerByID) author.DELETE("/player/:id", controllers.DeletePlayerByID) reader.GET("/cache/:player_id", controllers.GetCacheByPlayerID) reader.GET("/score/:player_id", controllers.GetScoreByPlayerID) reader.POST("/score/:player_name", controllers.GetScoreByPlayerName) reader.GET("/game", controllers.GetGames) reader.GET("/game_html", controllers.GetGamesHTML) reader.GET("/settings", controllers.GetSettings) reader.PATCH("/settings", controllers.UpdateSettings) admin.DELETE("/clear_cache", controllers.DeleteAllCaches) admin.DELETE("/purge_players", controllers.DeleteAllPlayers) admin.DELETE("/purge_clans", controllers.DeleteAllClans) admin.POST("/create_code", controllers.CreateCode) utils.Logger.Println("[MAIN] Running on 8000...") utils.Logger.Fatalf("[MAIN] %v", router.Run(":8000")) }