32 files changed, 125 insertions(+), 111 deletions(-)
R sdbapi/Dockerfile => api/Dockerfile
R sdbapi/LICENSE => api/LICENSE
R sdbapi/README.md => api/README.md
R sdbapi/apierror/apierror.go => api/apierror/apierror.go
R sdbapi/auth/auth.go => api/auth/auth.go
R sdbapi/db/db.go => api/db/db.go
R sdbapi/db/game.go => api/db/game.go
R sdbapi/db/user.go => api/db/user.go
R sdbapi/dev-launch-alpine.sh => api/dev-launch-alpine.sh
R sdbapi/dev-launch.sh => api/dev-launch.sh
R sdbapi/docker-compose.yaml => api/docker-compose.yaml
R sdbapi/go.mod => api/go.mod
R sdbapi/go.sum => api/go.sum
R sdbapi/handlers/allforming.go => api/handlers/allforming.go
A api/handlers/createaction.go
R sdbapi/handlers/gamecreate.go => api/handlers/gamecreate.go
R sdbapi/handlers/gameinfo.go => api/handlers/gameinfo.go
R sdbapi/handlers/joingame.go => api/handlers/joingame.go
R sdbapi/handlers/misc.go => api/handlers/misc.go
R sdbapi/handlers/mygames.go => api/handlers/mygames.go
R sdbapi/handlers/patchgamestate.go => api/handlers/patchgamestate.go
R sdbapi/handlers/usercreate.go => api/handlers/usercreate.go
R sdbapi/handlers/userinfo.go => api/handlers/userinfo.go
R sdbapi/handlers/userinfop.go => api/handlers/userinfop.go
R sdbapi/handlers/usertoken.go => api/handlers/usertoken.go
R sdbapi/main.go => api/main.go
R sdbapi/main_test.go => api/main_test.go
R sdbapi/middlewares/auth.go => api/middlewares/auth.go
R sdbapi/models/action.go => api/models/action.go
R sdbapi/models/game.go => api/models/game.go
R sdbapi/models/user.go => api/models/user.go
D sdbapi/models/gamedata.go
R sdbapi/Dockerfile => api/Dockerfile +0 -0
R sdbapi/LICENSE => api/LICENSE +2 -2
@@ 1,5 1,5 @@
-sdbapi is an API for a deck building game.
-Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+The API for Laurelin.
+Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
R sdbapi/README.md => api/README.md +2 -2
@@ 1,7 1,7 @@
-# Deck Builder API
+# Laurelin API
## Deployment
-Configure `SDBAPI_JWT_SECRET` in `docker-compose.yaml` to be randomized.
+Configure `LAURELINAPI_JWT_SECRET` in `docker-compose.yaml` to be randomized.
## API Doc
Paths may change in the future.
R sdbapi/apierror/apierror.go => api/apierror/apierror.go +6 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
@@ 42,6 42,11 @@ var (
GameFull APIError = APIError{3007, "GameFull", "game is full"}
)
+// action related errors
+var (
+ ActionCreationFailed APIError = APIError{4000, "ActionCreationFailed", "action creation failed"}
+)
+
type APIError struct {
ID uint16 `json:"id"`
Name string `json:"name"`
R sdbapi/auth/auth.go => api/auth/auth.go +3 -3
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
@@ 17,7 17,7 @@ import (
"github.com/golang-jwt/jwt/v4"
)
-var JWTSecret = []byte(os.Getenv("SDBAPI_JWT_SECRET"))
+var JWTSecret = []byte(os.Getenv("LAURELINAPI_JWT_SECRET"))
type JWTClaims struct {
Username string `json:"username"`
R sdbapi/db/db.go => api/db/db.go +2 -3
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
@@ 33,5 33,4 @@ func Migrate() {
DbConn.AutoMigrate(&models.User{})
DbConn.AutoMigrate(&models.Game{})
DbConn.AutoMigrate(&models.Action{})
- DbConn.AutoMigrate(&models.GameData{})
}
R sdbapi/db/game.go => api/db/game.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
R sdbapi/db/user.go => api/db/user.go +2 -2
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
R sdbapi/dev-launch-alpine.sh => api/dev-launch-alpine.sh +0 -0
R sdbapi/dev-launch.sh => api/dev-launch.sh +2 -2
@@ 1,6 1,6 @@
#!/bin/bash
-export COMPOSE_PROJECT_NAME=sdbapi
+export COMPOSE_PROJECT_NAME=laurelinapi
function confirm() {
echo -n "$@ [y/N]: "
@@ 18,7 18,7 @@ function confirm() {
}
confirm reset containers? && docker compose down
-confirm reset database? && docker volume rm sdbapi_apidb_data
+confirm reset database? && docker volume rm laurelinapi_apidb_data
confirm rebuild api? && docker compose build
R sdbapi/docker-compose.yaml => api/docker-compose.yaml +11 -11
@@ 9,9 9,9 @@ volumes:
driver: local
services:
- sdbapidb:
+ laurelinapidb:
image: postgres:15.1-alpine
- container_name: sdbapidb
+ container_name: laurelinapidb
restart: always
networks:
- internal
@@ 20,14 20,14 @@ services:
volumes:
- apidb_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER: sdbapi
- POSTGRES_PASSWORD: sdbapi
- POSTGRES_DB: sdbapi
+ POSTGRES_USER: lau
+ POSTGRES_PASSWORD: lau
+ POSTGRES_DB: laurelinapi
- sdbapi:
+ laurelinapi:
build: .
- image: sdbapi
- container_name: sdbapi
+ image: laurelinapi
+ container_name: laurelinapi
restart: always
networks:
- internal
@@ 35,7 35,7 @@ services:
- "8080:3000"
environment:
GIN_MODE: "release" # or "debug" for debug logs
- SDBAPI_JWT_SECRET: "XpNYdG7vgvgPPuezrtZqt4CJIUuxNP7c"
- GORM_DB_STRING: "host=sdbapidb user=sdbapi password=sdbapi dbname=sdbapi port=5432 sslmode=disable"
+ LAURELINAPI_JWT_SECRET: "XpNYdG7vgvgPPuezrtZqt4CJIUuxNP7c"
+ GORM_DB_STRING: "host=laurelinapidb user=lau password=lau dbname=laurelinapi port=5432 sslmode=disable"
depends_on:
- - sdbapidb
+ - laurelinapidb
R sdbapi/go.mod => api/go.mod +0 -0
R sdbapi/go.sum => api/go.sum +0 -0
R sdbapi/handlers/allforming.go => api/handlers/allforming.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
A api/handlers/createaction.go => api/handlers/createaction.go +44 -0
@@ 0,0 1,44 @@
+/*
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+package handlers
+
+import (
+ "api/db"
+ "api/models"
+ "api/apierror"
+ "net/http"
+
+ "gorm.io/datatypes"
+ "github.com/gin-gonic/gin"
+)
+
+func CreateAction(c *gin.Context) {
+ var input models.PostAction
+ if err := c.ShouldBindJSON(&input); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": apierror.InvalidInput})
+ c.Abort()
+ return
+ }
+
+ var action models.Action
+
+ action.GameID = input.GameID
+ action.Invoker = input.Invoker
+ action.Target = input.Target
+ action.Command = datatypes.JSON(input.Command)
+
+ entry := db.DbConn.Create(&action)
+ if entry.Error != nil {
+ c.JSON(http.StatusInternalServerError, gin.H{"error": apierror.ActionCreationFailed})
+ c.Abort()
+ return
+ }
+
+ c.JSON(http.StatusCreated, action)
+}
R sdbapi/handlers/gamecreate.go => api/handlers/gamecreate.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
R sdbapi/handlers/gameinfo.go => api/handlers/gameinfo.go +2 -2
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
@@ 22,7 22,7 @@ func GameInfo(c *gin.Context) {
// check if the game exists
var game models.Game
- record := db.DbConn.Preload("Host").Preload("Guest").Where("id = ?", id).First(&game)
+ record := db.DbConn.Preload("Host").Preload("Guest").Preload("Actions").Where("id = ?", id).First(&game)
if record.Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": apierror.GameNotFound})
c.Abort()
R sdbapi/handlers/joingame.go => api/handlers/joingame.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
R sdbapi/handlers/misc.go => api/handlers/misc.go +2 -2
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
R sdbapi/handlers/mygames.go => api/handlers/mygames.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
R sdbapi/handlers/patchgamestate.go => api/handlers/patchgamestate.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
R sdbapi/handlers/usercreate.go => api/handlers/usercreate.go +2 -2
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
R sdbapi/handlers/userinfo.go => api/handlers/userinfo.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
R sdbapi/handlers/userinfop.go => api/handlers/userinfop.go +2 -2
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
R sdbapi/handlers/usertoken.go => api/handlers/usertoken.go +2 -2
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
R sdbapi/main.go => api/main.go +8 -19
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
@@ 14,7 14,6 @@ import (
"api/middlewares"
"log"
"os"
- "syscall"
"github.com/gin-gonic/gin"
)
@@ 23,11 22,6 @@ func main() {
// stores various errors during startup
var err error
- err = setUlimits()
- if err != nil {
- log.Fatal("failed to set Ulimits")
- }
-
dbConnectionString := os.Getenv("GORM_DB_STRING")
if dbConnectionString == "" {
log.Fatal("environment variable 'GORM_DB_STRING' is not set")
@@ 52,7 46,7 @@ func createRouter() *gin.Engine {
api.GET("/info", handlers.Info)
user := api.Group("/user")
{
- user.POST("/register", handlers.CreateUser)
+ user.POST("/", handlers.CreateUser)
user.POST("/token", handlers.GenerateToken)
user.GET("/:id", handlers.UserInfo)
userp := user.Group("/_").Use(middlewares.Auth())
@@ 64,21 58,16 @@ func createRouter() *gin.Engine {
{
game.GET("/:id", handlers.GameInfo)
game.GET("/all_forming", handlers.FormingGames)
- game.POST("/create", handlers.CreateGame)
+ game.POST("/", handlers.CreateGame)
game.PATCH("/:id/state", handlers.PatchGameState)
game.GET("/my_games", handlers.MyGames)
game.POST("/:id/join", handlers.JoinGame)
}
+ action := api.Group("/game/action").Use(middlewares.Auth())
+ {
+ action.POST("/", handlers.CreateAction)
+ }
}
return router
}
-// Set NOFILE limit to max, to allow more concurrent websocket connections
-func setUlimits() error {
- var rlimit syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit); err != nil {
- return err
- }
- rlimit.Cur = rlimit.Max
- return syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit)
-}
R sdbapi/main_test.go => api/main_test.go +2 -2
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
R sdbapi/middlewares/auth.go => api/middlewares/auth.go +2 -2
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
R sdbapi/models/action.go => api/models/action.go +12 -5
@@ 1,6 1,6 @@
/*
- * This file is part of sdbapi
- * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
+ * This file is part of laurelin_api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
@@ 20,8 20,15 @@ type Action struct {
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
- GameDataID string `json:"game_data_id"`
+ GameID string `json:"game_id"`
Invoker string `json:"invoker"`
- Data datatypes.JSON `json:"data"`
- Timestamp time.Time `json:"timestamp" gorm:"type:timestamptz"`
+ Target string `json:"target"`
+ Command datatypes.JSON `json:"command"`
+}
+
+type PostAction struct {
+ GameID string `json:"game_id"`
+ Invoker string `json:"invoker"`
+ Target string `json:"target"`
+ Command string `json:"command"`
}
R sdbapi/models/game.go => api/models/game.go +9 -4
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
@@ 21,17 21,22 @@ const (
GAMESTATE_CANCELLED uint8 = 3
)
+const (
+ GAMETURN_HOST uint8 = 0
+ GAMETURN_GUEST uint8 = 1
+)
+
type Game struct {
ID string `json:"id" gorm:"primarykey;type:uuid;default:gen_random_uuid()"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
+ EndedAt time.Time `json:"ended_at" gorm:"type:timestamptz"`
HostID string `json:"host_id"`
Host User `json:"host" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
GuestID string `json:"guest_id" gorm:"default:NULL;"`
Guest User `json:"guest" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
State uint8 `json:"state" gorm:"type:smallint"`
- EndedAt time.Time `json:"ended_at" gorm:"type:timestamptz"`
- GameDataID string `json:"game_data_id" gorm:"default:NULL;"`
- GameData GameData `json:"game_data" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
+ Turn uint8 `json:"turn" gorm:"type:smallint"`
+ Actions []Action `json:"actions" gorm:"foreignKey:GameID"`
}
R sdbapi/models/user.go => api/models/user.go +1 -1
@@ 1,5 1,5 @@
/*
- * This file is part of sdbapi
+ * This file is part of laurelin_api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
D sdbapi/models/gamedata.go => sdbapi/models/gamedata.go +0 -35
@@ 1,35 0,0 @@
-/*
- * This file is part of sdbapi
- * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
- *
- * Licensed under GPL-3.0-only.
- * See LICENSE for licensing information.
- */
-
-package models
-
-import (
- "time"
-
- "gorm.io/datatypes"
- "gorm.io/gorm"
-)
-
-const (
- GAMETURN_HOST uint8 = 0
- GAMETURN_GUEST uint8 = 1
-)
-
-type GameData struct {
- ID string `json:"id" gorm:"primarykey;type:uuid;default:gen_random_uuid()"`
- CreatedAt time.Time `json:"created_at"`
- UpdatedAt time.Time `json:"updated_at"`
- DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
- Actions []Action `json:"actions" gorm:"foreignKey:GameDataID"`
- Turn uint8 `json:"turn" gorm:"type:smallint"`
- // NOTE: These are not final
- HostHand datatypes.JSON `json:"host_hand"`
- HostDeck datatypes.JSON `json:"host_deck"`
- GuestHand datatypes.JSON `json:"guest_hand"`
- GuestDeck datatypes.JSON `json:"guest_deck"`
-}