diff options
| -rw-r--r-- | backend/controllers/modController.go | 55 | ||||
| -rw-r--r-- | backend/models/requests.go | 4 | ||||
| -rw-r--r-- | backend/routes/routes.go | 1 | ||||
| -rw-r--r-- | docs/docs.go | 104 | ||||
| -rw-r--r-- | docs/swagger.json | 104 | ||||
| -rw-r--r-- | docs/swagger.yaml | 63 |
6 files changed, 328 insertions, 3 deletions
diff --git a/backend/controllers/modController.go b/backend/controllers/modController.go index ff79e3e..98fb165 100644 --- a/backend/controllers/modController.go +++ b/backend/controllers/modController.go | |||
| @@ -264,3 +264,58 @@ func DeleteMapSummary(c *gin.Context) { | |||
| 264 | Data: request, | 264 | Data: request, |
| 265 | }) | 265 | }) |
| 266 | } | 266 | } |
| 267 | |||
| 268 | // PUT Map Image | ||
| 269 | // | ||
| 270 | // @Description Edit map image with specified map id. | ||
| 271 | // @Tags maps | ||
| 272 | // @Produce json | ||
| 273 | // @Param Authorization header string true "JWT Token" | ||
| 274 | // @Param id path int true "Map ID" | ||
| 275 | // @Param request body models.EditMapImageRequest true "Body" | ||
| 276 | // @Success 200 {object} models.Response{data=models.EditMapImageRequest} | ||
| 277 | // @Failure 400 {object} models.Response | ||
| 278 | // @Router /maps/{id}/image [put] | ||
| 279 | func EditMapImage(c *gin.Context) { | ||
| 280 | // Check if user exists | ||
| 281 | user, exists := c.Get("user") | ||
| 282 | if !exists { | ||
| 283 | c.JSON(http.StatusUnauthorized, models.ErrorResponse("User not logged in.")) | ||
| 284 | return | ||
| 285 | } | ||
| 286 | var moderator bool | ||
| 287 | for _, title := range user.(models.User).Titles { | ||
| 288 | if title == "Moderator" { | ||
| 289 | moderator = true | ||
| 290 | } | ||
| 291 | } | ||
| 292 | if !moderator { | ||
| 293 | c.JSON(http.StatusUnauthorized, models.ErrorResponse("Insufficient permissions.")) | ||
| 294 | return | ||
| 295 | } | ||
| 296 | // Bind parameter and body | ||
| 297 | id := c.Param("id") | ||
| 298 | mapID, err := strconv.Atoi(id) | ||
| 299 | if err != nil { | ||
| 300 | c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) | ||
| 301 | return | ||
| 302 | } | ||
| 303 | var request models.EditMapImageRequest | ||
| 304 | if err := c.BindJSON(&request); err != nil { | ||
| 305 | c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) | ||
| 306 | return | ||
| 307 | } | ||
| 308 | // Update database with new data | ||
| 309 | sql := `UPDATE maps SET image = $2 WHERE id = $1` | ||
| 310 | _, err = database.DB.Exec(sql, mapID, request.Image) | ||
| 311 | if err != nil { | ||
| 312 | c.JSON(http.StatusBadRequest, models.ErrorResponse(err.Error())) | ||
| 313 | return | ||
| 314 | } | ||
| 315 | // Return response | ||
| 316 | c.JSON(http.StatusOK, models.Response{ | ||
| 317 | Success: true, | ||
| 318 | Message: "Successfully updated map image.", | ||
| 319 | Data: request, | ||
| 320 | }) | ||
| 321 | } | ||
diff --git a/backend/models/requests.go b/backend/models/requests.go index f275203..fac05b6 100644 --- a/backend/models/requests.go +++ b/backend/models/requests.go | |||
| @@ -27,6 +27,10 @@ type DeleteMapSummaryRequest struct { | |||
| 27 | RouteID int `json:"route_id" binding:"required"` | 27 | RouteID int `json:"route_id" binding:"required"` |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | type EditMapImageRequest struct { | ||
| 31 | Image string `json:"image" binding:"required"` | ||
| 32 | } | ||
| 33 | |||
| 30 | type RecordRequest struct { | 34 | type RecordRequest struct { |
| 31 | HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"` | 35 | HostDemo *multipart.FileHeader `json:"host_demo" form:"host_demo" binding:"required" swaggerignore:"true"` |
| 32 | PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"` | 36 | PartnerDemo *multipart.FileHeader `json:"partner_demo" form:"partner_demo" swaggerignore:"true"` |
diff --git a/backend/routes/routes.go b/backend/routes/routes.go index a39c8c4..1377d32 100644 --- a/backend/routes/routes.go +++ b/backend/routes/routes.go | |||
| @@ -29,6 +29,7 @@ func InitRoutes(router *gin.Engine) { | |||
| 29 | v1.POST("/maps/:id/summary", middleware.CheckAuth, controllers.CreateMapSummary) | 29 | v1.POST("/maps/:id/summary", middleware.CheckAuth, controllers.CreateMapSummary) |
| 30 | v1.PUT("/maps/:id/summary", middleware.CheckAuth, controllers.EditMapSummary) | 30 | v1.PUT("/maps/:id/summary", middleware.CheckAuth, controllers.EditMapSummary) |
| 31 | v1.DELETE("/maps/:id/summary", middleware.CheckAuth, controllers.DeleteMapSummary) | 31 | v1.DELETE("/maps/:id/summary", middleware.CheckAuth, controllers.DeleteMapSummary) |
| 32 | v1.PUT("/maps/:id/image", middleware.CheckAuth, controllers.EditMapImage) | ||
| 32 | v1.GET("/maps/:id/leaderboards", controllers.FetchMapLeaderboards) | 33 | v1.GET("/maps/:id/leaderboards", controllers.FetchMapLeaderboards) |
| 33 | v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) | 34 | v1.POST("/maps/:id/record", middleware.CheckAuth, controllers.CreateRecordWithDemo) |
| 34 | v1.GET("/rankings", controllers.Rankings) | 35 | v1.GET("/rankings", controllers.Rankings) |
diff --git a/docs/docs.go b/docs/docs.go index 57984f4..13d4cf6 100644 --- a/docs/docs.go +++ b/docs/docs.go | |||
| @@ -229,6 +229,68 @@ const docTemplate = `{ | |||
| 229 | } | 229 | } |
| 230 | } | 230 | } |
| 231 | }, | 231 | }, |
| 232 | "/maps/{id}/image": { | ||
| 233 | "put": { | ||
| 234 | "description": "Edit map image with specified map id.", | ||
| 235 | "produces": [ | ||
| 236 | "application/json" | ||
| 237 | ], | ||
| 238 | "tags": [ | ||
| 239 | "maps" | ||
| 240 | ], | ||
| 241 | "parameters": [ | ||
| 242 | { | ||
| 243 | "type": "string", | ||
| 244 | "description": "JWT Token", | ||
| 245 | "name": "Authorization", | ||
| 246 | "in": "header", | ||
| 247 | "required": true | ||
| 248 | }, | ||
| 249 | { | ||
| 250 | "type": "integer", | ||
| 251 | "description": "Map ID", | ||
| 252 | "name": "id", | ||
| 253 | "in": "path", | ||
| 254 | "required": true | ||
| 255 | }, | ||
| 256 | { | ||
| 257 | "description": "Body", | ||
| 258 | "name": "request", | ||
| 259 | "in": "body", | ||
| 260 | "required": true, | ||
| 261 | "schema": { | ||
| 262 | "$ref": "#/definitions/models.EditMapImageRequest" | ||
| 263 | } | ||
| 264 | } | ||
| 265 | ], | ||
| 266 | "responses": { | ||
| 267 | "200": { | ||
| 268 | "description": "OK", | ||
| 269 | "schema": { | ||
| 270 | "allOf": [ | ||
| 271 | { | ||
| 272 | "$ref": "#/definitions/models.Response" | ||
| 273 | }, | ||
| 274 | { | ||
| 275 | "type": "object", | ||
| 276 | "properties": { | ||
| 277 | "data": { | ||
| 278 | "$ref": "#/definitions/models.EditMapImageRequest" | ||
| 279 | } | ||
| 280 | } | ||
| 281 | } | ||
| 282 | ] | ||
| 283 | } | ||
| 284 | }, | ||
| 285 | "400": { | ||
| 286 | "description": "Bad Request", | ||
| 287 | "schema": { | ||
| 288 | "$ref": "#/definitions/models.Response" | ||
| 289 | } | ||
| 290 | } | ||
| 291 | } | ||
| 292 | } | ||
| 293 | }, | ||
| 232 | "/maps/{id}/leaderboards": { | 294 | "/maps/{id}/leaderboards": { |
| 233 | "get": { | 295 | "get": { |
| 234 | "description": "Get map leaderboards with specified id.", | 296 | "description": "Get map leaderboards with specified id.", |
| @@ -344,7 +406,19 @@ const docTemplate = `{ | |||
| 344 | "200": { | 406 | "200": { |
| 345 | "description": "OK", | 407 | "description": "OK", |
| 346 | "schema": { | 408 | "schema": { |
| 347 | "$ref": "#/definitions/models.Response" | 409 | "allOf": [ |
| 410 | { | ||
| 411 | "$ref": "#/definitions/models.Response" | ||
| 412 | }, | ||
| 413 | { | ||
| 414 | "type": "object", | ||
| 415 | "properties": { | ||
| 416 | "data": { | ||
| 417 | "$ref": "#/definitions/models.RecordResponse" | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | ] | ||
| 348 | } | 422 | } |
| 349 | }, | 423 | }, |
| 350 | "400": { | 424 | "400": { |
| @@ -1047,6 +1121,17 @@ const docTemplate = `{ | |||
| 1047 | } | 1121 | } |
| 1048 | } | 1122 | } |
| 1049 | }, | 1123 | }, |
| 1124 | "models.EditMapImageRequest": { | ||
| 1125 | "type": "object", | ||
| 1126 | "required": [ | ||
| 1127 | "image" | ||
| 1128 | ], | ||
| 1129 | "properties": { | ||
| 1130 | "image": { | ||
| 1131 | "type": "string" | ||
| 1132 | } | ||
| 1133 | } | ||
| 1134 | }, | ||
| 1050 | "models.EditMapSummaryRequest": { | 1135 | "models.EditMapSummaryRequest": { |
| 1051 | "type": "object", | 1136 | "type": "object", |
| 1052 | "required": [ | 1137 | "required": [ |
| @@ -1084,6 +1169,9 @@ const docTemplate = `{ | |||
| 1084 | "id": { | 1169 | "id": { |
| 1085 | "type": "integer" | 1170 | "type": "integer" |
| 1086 | }, | 1171 | }, |
| 1172 | "is_coop": { | ||
| 1173 | "type": "boolean" | ||
| 1174 | }, | ||
| 1087 | "name": { | 1175 | "name": { |
| 1088 | "type": "string" | 1176 | "type": "string" |
| 1089 | } | 1177 | } |
| @@ -1112,6 +1200,9 @@ const docTemplate = `{ | |||
| 1112 | "image": { | 1200 | "image": { |
| 1113 | "type": "string" | 1201 | "type": "string" |
| 1114 | }, | 1202 | }, |
| 1203 | "is_coop": { | ||
| 1204 | "type": "boolean" | ||
| 1205 | }, | ||
| 1115 | "map_name": { | 1206 | "map_name": { |
| 1116 | "type": "string" | 1207 | "type": "string" |
| 1117 | } | 1208 | } |
| @@ -1242,6 +1333,17 @@ const docTemplate = `{ | |||
| 1242 | } | 1333 | } |
| 1243 | } | 1334 | } |
| 1244 | }, | 1335 | }, |
| 1336 | "models.RecordResponse": { | ||
| 1337 | "type": "object", | ||
| 1338 | "properties": { | ||
| 1339 | "score_count": { | ||
| 1340 | "type": "integer" | ||
| 1341 | }, | ||
| 1342 | "score_time": { | ||
| 1343 | "type": "integer" | ||
| 1344 | } | ||
| 1345 | } | ||
| 1346 | }, | ||
| 1245 | "models.Response": { | 1347 | "models.Response": { |
| 1246 | "type": "object", | 1348 | "type": "object", |
| 1247 | "properties": { | 1349 | "properties": { |
diff --git a/docs/swagger.json b/docs/swagger.json index ef422ab..f644288 100644 --- a/docs/swagger.json +++ b/docs/swagger.json | |||
| @@ -222,6 +222,68 @@ | |||
| 222 | } | 222 | } |
| 223 | } | 223 | } |
| 224 | }, | 224 | }, |
| 225 | "/maps/{id}/image": { | ||
| 226 | "put": { | ||
| 227 | "description": "Edit map image with specified map id.", | ||
| 228 | "produces": [ | ||
| 229 | "application/json" | ||
| 230 | ], | ||
| 231 | "tags": [ | ||
| 232 | "maps" | ||
| 233 | ], | ||
| 234 | "parameters": [ | ||
| 235 | { | ||
| 236 | "type": "string", | ||
| 237 | "description": "JWT Token", | ||
| 238 | "name": "Authorization", | ||
| 239 | "in": "header", | ||
| 240 | "required": true | ||
| 241 | }, | ||
| 242 | { | ||
| 243 | "type": "integer", | ||
| 244 | "description": "Map ID", | ||
| 245 | "name": "id", | ||
| 246 | "in": "path", | ||
| 247 | "required": true | ||
| 248 | }, | ||
| 249 | { | ||
| 250 | "description": "Body", | ||
| 251 | "name": "request", | ||
| 252 | "in": "body", | ||
| 253 | "required": true, | ||
| 254 | "schema": { | ||
| 255 | "$ref": "#/definitions/models.EditMapImageRequest" | ||
| 256 | } | ||
| 257 | } | ||
| 258 | ], | ||
| 259 | "responses": { | ||
| 260 | "200": { | ||
| 261 | "description": "OK", | ||
| 262 | "schema": { | ||
| 263 | "allOf": [ | ||
| 264 | { | ||
| 265 | "$ref": "#/definitions/models.Response" | ||
| 266 | }, | ||
| 267 | { | ||
| 268 | "type": "object", | ||
| 269 | "properties": { | ||
| 270 | "data": { | ||
| 271 | "$ref": "#/definitions/models.EditMapImageRequest" | ||
| 272 | } | ||
| 273 | } | ||
| 274 | } | ||
| 275 | ] | ||
| 276 | } | ||
| 277 | }, | ||
| 278 | "400": { | ||
| 279 | "description": "Bad Request", | ||
| 280 | "schema": { | ||
| 281 | "$ref": "#/definitions/models.Response" | ||
| 282 | } | ||
| 283 | } | ||
| 284 | } | ||
| 285 | } | ||
| 286 | }, | ||
| 225 | "/maps/{id}/leaderboards": { | 287 | "/maps/{id}/leaderboards": { |
| 226 | "get": { | 288 | "get": { |
| 227 | "description": "Get map leaderboards with specified id.", | 289 | "description": "Get map leaderboards with specified id.", |
| @@ -337,7 +399,19 @@ | |||
| 337 | "200": { | 399 | "200": { |
| 338 | "description": "OK", | 400 | "description": "OK", |
| 339 | "schema": { | 401 | "schema": { |
| 340 | "$ref": "#/definitions/models.Response" | 402 | "allOf": [ |
| 403 | { | ||
| 404 | "$ref": "#/definitions/models.Response" | ||
| 405 | }, | ||
| 406 | { | ||
| 407 | "type": "object", | ||
| 408 | "properties": { | ||
| 409 | "data": { | ||
| 410 | "$ref": "#/definitions/models.RecordResponse" | ||
| 411 | } | ||
| 412 | } | ||
| 413 | } | ||
| 414 | ] | ||
| 341 | } | 415 | } |
| 342 | }, | 416 | }, |
| 343 | "400": { | 417 | "400": { |
| @@ -1040,6 +1114,17 @@ | |||
| 1040 | } | 1114 | } |
| 1041 | } | 1115 | } |
| 1042 | }, | 1116 | }, |
| 1117 | "models.EditMapImageRequest": { | ||
| 1118 | "type": "object", | ||
| 1119 | "required": [ | ||
| 1120 | "image" | ||
| 1121 | ], | ||
| 1122 | "properties": { | ||
| 1123 | "image": { | ||
| 1124 | "type": "string" | ||
| 1125 | } | ||
| 1126 | } | ||
| 1127 | }, | ||
| 1043 | "models.EditMapSummaryRequest": { | 1128 | "models.EditMapSummaryRequest": { |
| 1044 | "type": "object", | 1129 | "type": "object", |
| 1045 | "required": [ | 1130 | "required": [ |
| @@ -1077,6 +1162,9 @@ | |||
| 1077 | "id": { | 1162 | "id": { |
| 1078 | "type": "integer" | 1163 | "type": "integer" |
| 1079 | }, | 1164 | }, |
| 1165 | "is_coop": { | ||
| 1166 | "type": "boolean" | ||
| 1167 | }, | ||
| 1080 | "name": { | 1168 | "name": { |
| 1081 | "type": "string" | 1169 | "type": "string" |
| 1082 | } | 1170 | } |
| @@ -1105,6 +1193,9 @@ | |||
| 1105 | "image": { | 1193 | "image": { |
| 1106 | "type": "string" | 1194 | "type": "string" |
| 1107 | }, | 1195 | }, |
| 1196 | "is_coop": { | ||
| 1197 | "type": "boolean" | ||
| 1198 | }, | ||
| 1108 | "map_name": { | 1199 | "map_name": { |
| 1109 | "type": "string" | 1200 | "type": "string" |
| 1110 | } | 1201 | } |
| @@ -1235,6 +1326,17 @@ | |||
| 1235 | } | 1326 | } |
| 1236 | } | 1327 | } |
| 1237 | }, | 1328 | }, |
| 1329 | "models.RecordResponse": { | ||
| 1330 | "type": "object", | ||
| 1331 | "properties": { | ||
| 1332 | "score_count": { | ||
| 1333 | "type": "integer" | ||
| 1334 | }, | ||
| 1335 | "score_time": { | ||
| 1336 | "type": "integer" | ||
| 1337 | } | ||
| 1338 | } | ||
| 1339 | }, | ||
| 1238 | "models.Response": { | 1340 | "models.Response": { |
| 1239 | "type": "object", | 1341 | "type": "object", |
| 1240 | "properties": { | 1342 | "properties": { |
diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 2fed413..3b706ea 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml | |||
| @@ -61,6 +61,13 @@ definitions: | |||
| 61 | required: | 61 | required: |
| 62 | - route_id | 62 | - route_id |
| 63 | type: object | 63 | type: object |
| 64 | models.EditMapImageRequest: | ||
| 65 | properties: | ||
| 66 | image: | ||
| 67 | type: string | ||
| 68 | required: | ||
| 69 | - image | ||
| 70 | type: object | ||
| 64 | models.EditMapSummaryRequest: | 71 | models.EditMapSummaryRequest: |
| 65 | properties: | 72 | properties: |
| 66 | description: | 73 | description: |
| @@ -87,6 +94,8 @@ definitions: | |||
| 87 | properties: | 94 | properties: |
| 88 | id: | 95 | id: |
| 89 | type: integer | 96 | type: integer |
| 97 | is_coop: | ||
| 98 | type: boolean | ||
| 90 | name: | 99 | name: |
| 91 | type: string | 100 | type: string |
| 92 | type: object | 101 | type: object |
| @@ -105,6 +114,8 @@ definitions: | |||
| 105 | type: integer | 114 | type: integer |
| 106 | image: | 115 | image: |
| 107 | type: string | 116 | type: string |
| 117 | is_coop: | ||
| 118 | type: boolean | ||
| 108 | map_name: | 119 | map_name: |
| 109 | type: string | 120 | type: string |
| 110 | type: object | 121 | type: object |
| @@ -189,6 +200,13 @@ definitions: | |||
| 189 | $ref: '#/definitions/models.UserRanking' | 200 | $ref: '#/definitions/models.UserRanking' |
| 190 | type: array | 201 | type: array |
| 191 | type: object | 202 | type: object |
| 203 | models.RecordResponse: | ||
| 204 | properties: | ||
| 205 | score_count: | ||
| 206 | type: integer | ||
| 207 | score_time: | ||
| 208 | type: integer | ||
| 209 | type: object | ||
| 192 | models.Response: | 210 | models.Response: |
| 193 | properties: | 211 | properties: |
| 194 | data: {} | 212 | data: {} |
| @@ -364,6 +382,44 @@ paths: | |||
| 364 | $ref: '#/definitions/models.Response' | 382 | $ref: '#/definitions/models.Response' |
| 365 | tags: | 383 | tags: |
| 366 | - login | 384 | - login |
| 385 | /maps/{id}/image: | ||
| 386 | put: | ||
| 387 | description: Edit map image with specified map id. | ||
| 388 | parameters: | ||
| 389 | - description: JWT Token | ||
| 390 | in: header | ||
| 391 | name: Authorization | ||
| 392 | required: true | ||
| 393 | type: string | ||
| 394 | - description: Map ID | ||
| 395 | in: path | ||
| 396 | name: id | ||
| 397 | required: true | ||
| 398 | type: integer | ||
| 399 | - description: Body | ||
| 400 | in: body | ||
| 401 | name: request | ||
| 402 | required: true | ||
| 403 | schema: | ||
| 404 | $ref: '#/definitions/models.EditMapImageRequest' | ||
| 405 | produces: | ||
| 406 | - application/json | ||
| 407 | responses: | ||
| 408 | "200": | ||
| 409 | description: OK | ||
| 410 | schema: | ||
| 411 | allOf: | ||
| 412 | - $ref: '#/definitions/models.Response' | ||
| 413 | - properties: | ||
| 414 | data: | ||
| 415 | $ref: '#/definitions/models.EditMapImageRequest' | ||
| 416 | type: object | ||
| 417 | "400": | ||
| 418 | description: Bad Request | ||
| 419 | schema: | ||
| 420 | $ref: '#/definitions/models.Response' | ||
| 421 | tags: | ||
| 422 | - maps | ||
| 367 | /maps/{id}/leaderboards: | 423 | /maps/{id}/leaderboards: |
| 368 | get: | 424 | get: |
| 369 | description: Get map leaderboards with specified id. | 425 | description: Get map leaderboards with specified id. |
| @@ -435,7 +491,12 @@ paths: | |||
| 435 | "200": | 491 | "200": |
| 436 | description: OK | 492 | description: OK |
| 437 | schema: | 493 | schema: |
| 438 | $ref: '#/definitions/models.Response' | 494 | allOf: |
| 495 | - $ref: '#/definitions/models.Response' | ||
| 496 | - properties: | ||
| 497 | data: | ||
| 498 | $ref: '#/definitions/models.RecordResponse' | ||
| 499 | type: object | ||
| 439 | "400": | 500 | "400": |
| 440 | description: Bad Request | 501 | description: Bad Request |
| 441 | schema: | 502 | schema: |