package main import ( "InfrantrySkillCalculator/controllers" "InfrantrySkillCalculator/models" "InfrantrySkillCalculator/utils" "fmt" "github.com/gin-gonic/gin" "github.com/gorilla/sessions" _ "github.com/gorilla/sessions" "golang.org/x/crypto/bcrypt" "html/template" "io" "log" "net/http" "os" ) var store = sessions.NewCookieStore([]byte("f0q0qew0!)§(ds9713lsda231")) func main() { //gin.SetMode(gin.ReleaseMode) // uncomment upon release router := gin.New() router.LoadHTMLGlob("templates/**/*") protected := router.Group("/") protected.Use(AuthRequired()) models.ConnectDatabase() f, _ := os.OpenFile("isc_rest.log", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660) utils.GinWriter = io.MultiWriter(f, os.Stdout) router.Use( gin.LoggerWithWriter(utils.GinWriter, "/update"), gin.Recovery(), ) router.Static("/static", "./static") router.GET("/login", loginPage) router.POST("/login", loginPost) router.GET("/logout", logout) protected.GET("/", mainPage) protected.GET("/clans", controllers.GetAllClans) protected.GET("/clans_html", controllers.GetAllClansHTML) protected.GET("/clan/:id", controllers.GetClanByID) protected.POST("/clan", controllers.AddClan) protected.PATCH("/clan/:id", controllers.UpdateClanByID) protected.DELETE("/clan/:id", controllers.DeleteClanByID) protected.GET("/players", controllers.GetAllPlayers) protected.GET("/players_html", controllers.GetPlayersByClanHTML) protected.GET("/player/:id", controllers.GetPlayerByID) protected.GET("/playerid/:name", controllers.GetPlayerIDByName) protected.POST("/player", controllers.AddPlayer) protected.PATCH("/player/:id", controllers.UpdatePlayerByID) protected.DELETE("/player/:id", controllers.DeletePlayerByID) log.Println("Running on 8000...") log.Fatal(router.Run(":8000")) } func mainPage(c *gin.Context) { files := []string{ "./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/components/header.html", } tmpl, err := template.ParseFiles(files...) if err != nil { log.Fatal(err) } var clans []models.Clan models.DB.Find(&clans) data := map[string]interface{}{ "clans": clans, } err = tmpl.Execute(c.Writer, data) if err != nil { log.Fatal(err) } } func loginPage(c *gin.Context) { session, _ := store.Get(c.Request, "session-name") if auth, ok := session.Values["authenticated"].(bool); ok && auth { c.Redirect(http.StatusFound, "/") return } tmpl, err := template.ParseFiles([]string{"./templates/login.html", "./templates/components/header.html"}...) if err != nil { log.Fatal(err) } err = tmpl.Execute(c.Writer, nil) if err != nil { log.Fatal(err) } } func loginPost(c *gin.Context) { username := c.PostForm("username") password := c.PostForm("password") if !checkUserCredentials(username, password) { c.HTML(http.StatusOK, "login_error.html", gin.H{"message": "Ungültige Logindaten!"}) return } session, _ := store.Get(c.Request, "session-name") session.Values["authenticated"] = true session.Values["username"] = username err := session.Save(c.Request, c.Writer) if err != nil { c.JSON(http.StatusInternalServerError, nil) return } c.Header("HX-Redirect", "/") c.String(http.StatusOK, "") } func checkUserCredentials(username, password string) bool { var hashedPassword string hashedPassword, err := getUserPassword(username) if err != nil { return false } err = bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password)) return err == nil } func getUserPassword(username string) (string, error) { var user models.User if err := models.DB.Where("username = ?", username).First(&user).Error; err != nil { log.Fatal(err) return "", err } var hashedPW string hashedPW, err := hashPassword(user.Password) if err != nil { log.Fatal(err) return "", err } return hashedPW, nil } func logout(c *gin.Context) { session, _ := store.Get(c.Request, "session-name") session.Values["authenticated"] = false err := session.Save(c.Request, c.Writer) if err != nil { c.JSON(http.StatusInternalServerError, nil) return } c.Redirect(http.StatusFound, "/login") } func hashPassword(password string) (string, error) { hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return "", fmt.Errorf("failed to hash password: %w", err) } return string(hashedPassword), nil } func AuthRequired() gin.HandlerFunc { return func(c *gin.Context) { session, _ := store.Get(c.Request, "session-name") if auth, ok := session.Values["authenticated"].(bool); !ok || !auth { c.Redirect(http.StatusFound, "/login") c.Abort() return } c.Next() } }