aboutsummaryrefslogtreecommitdiffhomepage
path: root/backend/api/handlers.go
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-07-31 22:20:35 +0900
committernsfisis <nsfisis@gmail.com>2024-07-31 22:20:35 +0900
commit4aff0feca72da0175dcecb44aca9b3e30c861bc5 (patch)
tree253a3094f3606682982b91b9be7a03f1e4b3f723 /backend/api/handlers.go
parent715651d6d263c5f526e8e13a8e2bb032193c5218 (diff)
parent3840c6d8e4261f182657b11ba55f61da04d70b28 (diff)
downloadiosdc-japan-2024-albatross-4aff0feca72da0175dcecb44aca9b3e30c861bc5.tar.gz
iosdc-japan-2024-albatross-4aff0feca72da0175dcecb44aca9b3e30c861bc5.tar.zst
iosdc-japan-2024-albatross-4aff0feca72da0175dcecb44aca9b3e30c861bc5.zip
Merge branch 'feat/admin-games-page'
Diffstat (limited to 'backend/api/handlers.go')
-rw-r--r--backend/api/handlers.go181
1 files changed, 179 insertions, 2 deletions
diff --git a/backend/api/handlers.go b/backend/api/handlers.go
index 519695f..558949b 100644
--- a/backend/api/handlers.go
+++ b/backend/api/handlers.go
@@ -5,8 +5,10 @@ import (
"errors"
"net/http"
"strings"
+ "time"
"github.com/jackc/pgx/v5"
+ "github.com/jackc/pgx/v5/pgtype"
"github.com/labstack/echo/v4"
"github.com/nsfisis/iosdc-2024-albatross/backend/auth"
@@ -25,6 +27,179 @@ func NewHandler(queries *db.Queries) *ApiHandler {
}
}
+func (h *ApiHandler) GetAdminGames(ctx context.Context, request GetAdminGamesRequestObject) (GetAdminGamesResponseObject, error) {
+ user := ctx.Value("user").(*auth.JWTClaims)
+ if !user.IsAdmin {
+ return GetAdminGames403JSONResponse{
+ Message: "Forbidden",
+ }, nil
+ }
+ gameRows, err := h.q.ListGames(ctx)
+ if err != nil {
+ return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+ }
+ games := make([]Game, len(gameRows))
+ for i, row := range gameRows {
+ var startedAt *int
+ if row.StartedAt.Valid {
+ startedAtTimestamp := int(row.StartedAt.Time.Unix())
+ startedAt = &startedAtTimestamp
+ }
+ var problem *Problem
+ if row.ProblemID != nil {
+ if row.Title == nil || row.Description == nil {
+ panic("inconsistent data")
+ }
+ problem = &Problem{
+ ProblemId: int(*row.ProblemID),
+ Title: *row.Title,
+ Description: *row.Description,
+ }
+ }
+ games[i] = Game{
+ GameId: int(row.GameID),
+ State: GameState(row.State),
+ DisplayName: row.DisplayName,
+ DurationSeconds: int(row.DurationSeconds),
+ StartedAt: startedAt,
+ Problem: problem,
+ }
+ }
+ return GetAdminGames200JSONResponse{
+ Games: games,
+ }, nil
+}
+
+func (h *ApiHandler) GetAdminGamesGameId(ctx context.Context, request GetAdminGamesGameIdRequestObject) (GetAdminGamesGameIdResponseObject, error) {
+ user := ctx.Value("user").(*auth.JWTClaims)
+ if !user.IsAdmin {
+ return GetAdminGamesGameId403JSONResponse{
+ Message: "Forbidden",
+ }, nil
+ }
+ gameId := request.GameId
+ row, err := h.q.GetGameById(ctx, int32(gameId))
+ if err != nil {
+ if errors.Is(err, pgx.ErrNoRows) {
+ return GetAdminGamesGameId404JSONResponse{
+ Message: "Game not found",
+ }, nil
+ } else {
+ return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+ }
+ }
+ var startedAt *int
+ if row.StartedAt.Valid {
+ startedAtTimestamp := int(row.StartedAt.Time.Unix())
+ startedAt = &startedAtTimestamp
+ }
+ var problem *Problem
+ if row.ProblemID != nil {
+ if row.Title == nil || row.Description == nil {
+ panic("inconsistent data")
+ }
+ problem = &Problem{
+ ProblemId: int(*row.ProblemID),
+ Title: *row.Title,
+ Description: *row.Description,
+ }
+ }
+ game := Game{
+ GameId: int(row.GameID),
+ State: GameState(row.State),
+ DisplayName: row.DisplayName,
+ DurationSeconds: int(row.DurationSeconds),
+ StartedAt: startedAt,
+ Problem: problem,
+ }
+ return GetAdminGamesGameId200JSONResponse{
+ Game: game,
+ }, nil
+}
+
+func (h *ApiHandler) PutAdminGamesGameId(ctx context.Context, request PutAdminGamesGameIdRequestObject) (PutAdminGamesGameIdResponseObject, error) {
+ user := ctx.Value("user").(*auth.JWTClaims)
+ if !user.IsAdmin {
+ return PutAdminGamesGameId403JSONResponse{
+ Message: "Forbidden",
+ }, nil
+ }
+ gameID := request.GameId
+ displayName := request.Body.DisplayName
+ durationSeconds := request.Body.DurationSeconds
+ problemID := request.Body.ProblemId
+ startedAt := request.Body.StartedAt
+ state := request.Body.State
+
+ game, err := h.q.GetGameById(ctx, int32(gameID))
+ if err != nil {
+ if err == pgx.ErrNoRows {
+ return PutAdminGamesGameId404JSONResponse{
+ Message: "Game not found",
+ }, nil
+ } else {
+ return nil, echo.NewHTTPError(http.StatusInternalServerError, err.Error())
+ }
+ }
+
+ var changedState string
+ if state != nil {
+ changedState = string(*state)
+ } else {
+ changedState = game.State
+ }
+ var changedDisplayName string
+ if displayName != nil {
+ changedDisplayName = *displayName
+ } else {
+ changedDisplayName = game.DisplayName
+ }
+ var changedDurationSeconds int32
+ if durationSeconds != nil {
+ changedDurationSeconds = int32(*durationSeconds)
+ } else {
+ changedDurationSeconds = game.DurationSeconds
+ }
+ var changedStartedAt pgtype.Timestamp
+ if startedAt != nil {
+ startedAtValue, err := startedAt.Get()
+ if err == nil {
+ changedStartedAt = pgtype.Timestamp{
+ Time: time.Unix(int64(startedAtValue), 0),
+ Valid: true,
+ }
+ }
+ } else {
+ changedStartedAt = game.StartedAt
+ }
+ var changedProblemID *int32
+ if problemID != nil {
+ problemIDValue, err := problemID.Get()
+ if err == nil {
+ changedProblemID = new(int32)
+ *changedProblemID = int32(problemIDValue)
+ }
+ } else {
+ changedProblemID = game.ProblemID
+ }
+
+ err = h.q.UpdateGame(ctx, db.UpdateGameParams{
+ GameID: int32(gameID),
+ State: changedState,
+ DisplayName: changedDisplayName,
+ DurationSeconds: changedDurationSeconds,
+ StartedAt: changedStartedAt,
+ ProblemID: changedProblemID,
+ })
+ if err != nil {
+ return PutAdminGamesGameId400JSONResponse{
+ Message: err.Error(),
+ }, nil
+ }
+
+ return PutAdminGamesGameId204Response{}, nil
+}
+
func (h *ApiHandler) GetAdminUsers(ctx context.Context, request GetAdminUsersRequestObject) (GetAdminUsersResponseObject, error) {
user := ctx.Value("user").(*auth.JWTClaims)
if !user.IsAdmin {
@@ -196,7 +371,7 @@ func (h *ApiHandler) GetGamesGameId(ctx context.Context, request GetGamesGameIdR
if row.Title == nil || row.Description == nil {
panic("inconsistent data")
}
- if user.IsAdmin || (GameState(row.State) != Closed && GameState(row.State) != WaitingEntries) {
+ if user.IsAdmin || (GameState(row.State) != GameStateClosed && GameState(row.State) != GameStateWaitingEntries) {
problem = &Problem{
ProblemId: int(*row.ProblemID),
Title: *row.Title,
@@ -212,7 +387,9 @@ func (h *ApiHandler) GetGamesGameId(ctx context.Context, request GetGamesGameIdR
StartedAt: startedAt,
Problem: problem,
}
- return GetGamesGameId200JSONResponse(game), nil
+ return GetGamesGameId200JSONResponse{
+ Game: game,
+ }, nil
}
func _assertUserResponseIsCompatibleWithJWTClaims() {