diff options
| author | nsfisis <nsfisis@gmail.com> | 2024-07-28 17:13:01 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2024-07-28 17:13:01 +0900 |
| commit | aadc8cf037855b99cb82798c7b0ebaafc5bb025b (patch) | |
| tree | 4ea9f9db9dbe7cf1b7720205ae281a6b8bcca8e9 /backend/api/handlers.go | |
| parent | 90741e8336b4ffba090bf08c3b899992860e2d98 (diff) | |
| parent | 2d5f913a431c4223a16c88551ffff4100ac483c4 (diff) | |
| download | iosdc-japan-2024-albatross-aadc8cf037855b99cb82798c7b0ebaafc5bb025b.tar.gz iosdc-japan-2024-albatross-aadc8cf037855b99cb82798c7b0ebaafc5bb025b.tar.zst iosdc-japan-2024-albatross-aadc8cf037855b99cb82798c7b0ebaafc5bb025b.zip | |
Merge branch 'game-entry'
Diffstat (limited to 'backend/api/handlers.go')
| -rw-r--r-- | backend/api/handlers.go | 128 |
1 files changed, 118 insertions, 10 deletions
diff --git a/backend/api/handlers.go b/backend/api/handlers.go index c435d72..9856ce9 100644 --- a/backend/api/handlers.go +++ b/backend/api/handlers.go @@ -3,6 +3,7 @@ package api import ( "context" "net/http" + "strings" "github.com/labstack/echo/v4" @@ -10,6 +11,8 @@ import ( "github.com/nsfisis/iosdc-2024-albatross-backend/db" ) +var _ StrictServerInterface = (*ApiHandler)(nil) + type ApiHandler struct { q *db.Queries } @@ -20,43 +23,148 @@ func NewHandler(queries *db.Queries) *ApiHandler { } } -func (h *ApiHandler) PostApiLogin(ctx context.Context, request PostApiLoginRequestObject) (PostApiLoginResponseObject, error) { +func (h *ApiHandler) PostLogin(ctx context.Context, request PostLoginRequestObject) (PostLoginResponseObject, error) { username := request.Body.Username password := request.Body.Password userId, err := auth.Login(ctx, h.q, username, password) if err != nil { - return PostApiLogin401JSONResponse{ + return PostLogin401JSONResponse{ Message: "Invalid username or password", - }, echo.NewHTTPError(http.StatusUnauthorized, "Invalid username or password") + }, nil } user, err := h.q.GetUserById(ctx, int32(userId)) if err != nil { - return PostApiLogin401JSONResponse{ + return PostLogin401JSONResponse{ Message: "Invalid username or password", - }, echo.NewHTTPError(http.StatusUnauthorized, "Invalid username or password") + }, nil } jwt, err := auth.NewJWT(&user) if err != nil { // TODO - return PostApiLogin401JSONResponse{ - Message: "Internal Server Error", - }, echo.NewHTTPError(http.StatusInternalServerError, "Internal Server Error") + return nil, echo.NewHTTPError(http.StatusInternalServerError) } - return PostApiLogin200JSONResponse{ + return PostLogin200JSONResponse{ Token: jwt, }, nil } +func (h *ApiHandler) GetGames(ctx context.Context, request GetGamesRequestObject) (GetGamesResponseObject, error) { + user := ctx.Value("user").(*auth.JWTClaims) + playerId := request.Params.PlayerId + if !user.IsAdmin { + if playerId == nil || *playerId != user.UserID { + return GetGames403JSONResponse{ + Message: "Forbidden", + }, nil + } + } + if playerId == nil { + gameRows, err := h.q.ListGames(ctx) + if err != nil { + return nil, echo.NewHTTPError(http.StatusInternalServerError) + } + 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.Valid { + if !row.Title.Valid || !row.Description.Valid { + panic("inconsistent data") + } + problem = &Problem{ + ProblemId: int(row.ProblemID.Int32), + Title: row.Title.String, + Description: row.Description.String, + } + } + games[i] = Game{ + GameId: int(row.GameID), + State: GameState(row.State), + DisplayName: row.DisplayName, + DurationSeconds: int(row.DurationSeconds), + StartedAt: startedAt, + Problem: problem, + } + } + return GetGames200JSONResponse{ + Games: games, + }, nil + } else { + gameRows, err := h.q.ListGamesForPlayer(ctx, int32(*playerId)) + if err != nil { + return nil, echo.NewHTTPError(http.StatusInternalServerError) + } + 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.Valid { + if !row.Title.Valid || !row.Description.Valid { + panic("inconsistent data") + } + problem = &Problem{ + ProblemId: int(row.ProblemID.Int32), + Title: row.Title.String, + Description: row.Description.String, + } + } + games[i] = Game{ + GameId: int(row.GameID), + State: GameState(row.State), + DisplayName: row.DisplayName, + DurationSeconds: int(row.DurationSeconds), + StartedAt: startedAt, + Problem: problem, + } + } + return GetGames200JSONResponse{ + Games: games, + }, nil + } +} + func _assertJwtPayloadIsCompatibleWithJWTClaims() { var c auth.JWTClaims var p JwtPayload - p.UserId = float32(c.UserID) + p.UserId = c.UserID p.Username = c.Username p.DisplayName = c.DisplayName p.IconPath = c.IconPath p.IsAdmin = c.IsAdmin _ = p } + +func NewJWTMiddleware() StrictMiddlewareFunc { + return func(handler StrictHandlerFunc, operationID string) StrictHandlerFunc { + if operationID == "PostLogin" { + return handler + } else { + return func(c echo.Context, request interface{}) (response interface{}, err error) { + authorization := c.Request().Header.Get("Authorization") + const prefix = "Bearer " + if !strings.HasPrefix(authorization, prefix) { + return nil, echo.NewHTTPError(http.StatusUnauthorized) + } + token := authorization[len(prefix):] + + claims, err := auth.ParseJWT(token) + if err != nil { + return nil, echo.NewHTTPError(http.StatusUnauthorized) + } + c.SetRequest(c.Request().WithContext(context.WithValue(c.Request().Context(), "user", claims))) + return handler(c, request) + } + } + } +} |
