From 8cce8b446e63d03161f0807c76721b40d851b50d Mon Sep 17 00:00:00 2001 From: Arda Serdar Pektezol <1669855+pektezol@users.noreply.github.com> Date: Wed, 28 Jun 2023 23:27:22 +0300 Subject: feat: mod edit for map summary Former-commit-id: dbef520658347a8c23546371ced24f1c0271749d --- backend/controllers/modController.go | 91 ++++++++++++++++++++++++++++++++++++ backend/middleware/auth.go | 10 +++- backend/models/models.go | 1 + backend/models/requests.go | 29 ++++++++++-- backend/routes/routes.go | 1 + 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 backend/controllers/modController.go (limited to 'backend') diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go new file mode 100644 index 0000000..ebf1cb7 --- /dev/null +++ b/backend/controllers/modController.go @@ -0,0 +1,91 @@ +package controllers + +import ( + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/pektezol/leastportals/backend/database" + "github.com/pektezol/leastportals/backend/models" +) + +// PUT Map Summary +// +// @Summary Edit map summary with specified map id. +// @Tags maps +// @Produce json +// @Param id path int true "Map ID" +// @Success 200 {object} models.Response{data=models.EditMapSummaryRequest} +// @Failure 400 {object} models.Response +// @Router /maps/{id}/summary [put] +func EditMapSummary(c *gin.Context) { + // Check if user exists + user, exists := c.Get("user") + if !exists { + c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) + return + } + var moderator bool + for _, title := range user.(models.User).Titles { + if title == "Moderator" { + moderator = true + } + } + if !moderator { + c.JSON(http.StatusUnauthorized, "Insufficient permissions.") + return + } + // Bind parameter and body + id := c.Param("id") + mapID, err := strconv.Atoi(id) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + var request models.EditMapSummaryRequest + if err := c.BindJSON(&request); err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Fetch route category and score count + var categoryID, scoreCount int + sql := `SELECT mr.category_id, mr.score_count + FROM map_routes mr + INNER JOIN maps m + WHERE m.id = $1 AND mr.id = $2` + err = database.DB.QueryRow(sql, mapID, request.RouteID).Scan(&categoryID, &scoreCount) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + // Start database transaction + tx, err := database.DB.Begin() + if err != nil { + c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) + return + } + defer tx.Rollback() + // Update database with new data + sql = `UPDATE map_routes SET score_count = $2, description = $3, showcase = $4 WHERE id = $1` + _, err = tx.Exec(sql, request.RouteID, request.ScoreCount, request.Description, request.Showcase) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + sql = `UPDATE map_history SET user_name = $3, score_count = $4, record_date = $5 WHERE map_id = $1 AND category_id = $2` + _, err = tx.Exec(sql, mapID, categoryID, request.UserName, request.ScoreCount, request.RecordDate) + if err != nil { + c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) + return + } + if err = tx.Commit(); err != nil { + c.JSON(http.StatusInternalServerError, models.ErrorResponse(err.Error())) + return + } + // Return response + c.JSON(http.StatusOK, models.Response{ + Success: true, + Message: "Successfully updated map summary.", + Data: request, + }) +} diff --git a/backend/middleware/auth.go b/backend/middleware/auth.go index 14a0b78..86e79d9 100644 --- a/backend/middleware/auth.go +++ b/backend/middleware/auth.go @@ -36,13 +36,21 @@ func CheckAuth(c *gin.Context) { } // Get user from DB var user models.User - database.DB.QueryRow(`SELECT * FROM users WHERE steam_id = $1`, claims["sub"]).Scan( + database.DB.QueryRow(`SELECT u.steam_id, u.user_name, u.avatar_link, u.country_code, u.created_at, u.updated_at, array_agg(t.) FROM users u WHERE steam_id = $1`, claims["sub"]).Scan( &user.SteamID, &user.UserName, &user.AvatarLink, &user.CountryCode, &user.CreatedAt, &user.UpdatedAt) if user.SteamID == "" { c.Next() return } + // Get user titles from DB + user.Titles = []string{} + rows, _ := database.DB.Query(`SELECT t.title_name FROM titles t WHERE t.user_id = $1`, user.SteamID) + for rows.Next() { + var title string + rows.Scan(&title) + user.Titles = append(user.Titles, title) + } c.Set("user", user) c.Next() } else { diff --git a/backend/models/models.go b/backend/models/models.go index 7b8cbc4..5355a9f 100644 --- a/backend/models/models.go +++ b/backend/models/models.go @@ -11,6 +11,7 @@ type User struct { CountryCode string `json:"country_code"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` + Titles []string `json:"titles"` } type UserShort struct { diff --git a/backend/models/requests.go b/backend/models/requests.go index 49b2d75..e95eab6 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go @@ -1,8 +1,29 @@ package models +import ( + "mime/multipart" + "time" +) + +type EditMapSummaryRequest struct { + RouteID int `json:"route_id" binding:"required"` + Description string `json:"description" binding:"required"` + Showcase string `json:"showcase" binding:"required"` + UserName string `json:"user_name" binding:"required"` + ScoreCount int `json:"score_count" binding:"required"` + RecordDate time.Time `json:"record_date" binding:"required"` +} + +type CreateMapHistoryRequest struct { + CategoryID int `json:"category_id" binding:"required"` + UserName string `json:"user_name" binding:"required"` + ScoreCount int `json:"score_count" binding:"required"` + RecordDate time.Time `json:"record_date" binding:"required"` +} + type RecordRequest struct { - ScoreCount int `json:"score_count" form:"score_count" binding:"required"` - ScoreTime int `json:"score_time" form:"score_time" binding:"required"` - PartnerID string `json:"partner_id" form:"partner_id" binding:"required"` - IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange" binding:"required"` + HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required"` + PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo"` + IsPartnerOrange bool `json:"is_partner_orange" form:"is_partner_orange"` + PartnerID string `json:"partner_id" form:"partner_id"` } diff --git a/backend/routes/routes.go b/backend/routes/routes.go index bf8a995..93dc1dd 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go @@ -26,6 +26,7 @@ func InitRoutes(router *gin.Engine) { v1.GET("/users/:id", middleware.CheckAuth, controllers.FetchUser) v1.GET("/demos", controllers.DownloadDemoWithID) v1.GET("/maps/:id/summary", middleware.CheckAuth, controllers.FetchMapSummary) + v1.PUT("/maps/:id/summary", middleware.CheckAuth, controllers.EditMapSummary) v1.GET("/maps/:id/leaderboards", middleware.CheckAuth, controllers.FetchMapLeaderboards) v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) v1.GET("/rankings", middleware.CheckAuth, controllers.Rankings) -- cgit v1.2.3