summaryrefslogtreecommitdiff
path: root/internal/api/handlers/handlers.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/api/handlers/handlers.go')
-rw-r--r--internal/api/handlers/handlers.go197
1 files changed, 197 insertions, 0 deletions
diff --git a/internal/api/handlers/handlers.go b/internal/api/handlers/handlers.go
new file mode 100644
index 0000000..b448502
--- /dev/null
+++ b/internal/api/handlers/handlers.go
@@ -0,0 +1,197 @@
+package handlers
+
+import (
+ "encoding/json"
+ "log/slog"
+ "net/http"
+ "time"
+
+ "github.com/boozec/rahanna/internal/api/auth"
+ "github.com/boozec/rahanna/internal/api/database"
+ "github.com/boozec/rahanna/internal/network"
+ "gorm.io/gorm"
+)
+
+type NewGameRequest struct {
+ IP string `json:"ip"`
+}
+
+func RegisterUser(w http.ResponseWriter, r *http.Request) {
+ slog.Info("POST /auth/register")
+ var user database.User
+ err := json.NewDecoder(r.Body).Decode(&user)
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ if len(user.Password) < 4 {
+ JsonError(&w, "password too short")
+ return
+ }
+
+ var storedUser database.User
+ db, _ := database.GetDb()
+ result := db.Where("username = ?", user.Username).First(&storedUser)
+
+ if result.Error == nil {
+ JsonError(&w, "user with this username already exists")
+ return
+ }
+
+ hashedPassword, err := HashPassword(user.Password)
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+ user.Password = string(hashedPassword)
+
+ result = db.Create(&user)
+ if result.Error != nil {
+ JsonError(&w, result.Error.Error())
+ return
+ }
+
+ token, err := auth.GenerateJWT(user.ID)
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ json.NewEncoder(w).Encode(map[string]string{"token": token})
+}
+
+func LoginUser(w http.ResponseWriter, r *http.Request) {
+ slog.Info("POST /auth/login")
+ var inputUser database.User
+ err := json.NewDecoder(r.Body).Decode(&inputUser)
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ var storedUser database.User
+
+ db, _ := database.GetDb()
+ result := db.Where("username = ?", inputUser.Username).First(&storedUser)
+ if result.Error != nil {
+ JsonError(&w, "invalid credentials")
+ return
+ }
+
+ if err := CheckPasswordHash(storedUser.Password, inputUser.Password); err != nil {
+ JsonError(&w, "invalid credentials")
+ return
+ }
+
+ token, err := auth.GenerateJWT(storedUser.ID)
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ json.NewEncoder(w).Encode(map[string]string{"token": token})
+}
+
+func NewPlay(w http.ResponseWriter, r *http.Request) {
+ slog.Info("POST /play")
+ claims, err := auth.ValidateJWT(r.Header.Get("Authorization"))
+
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ var payload struct {
+ IP string `json:"ip"`
+ }
+
+ if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ db, _ := database.GetDb()
+
+ name := network.NewSession()
+ play := database.Game{
+ Player1ID: claims.UserID,
+ Player2ID: nil,
+ Name: name,
+ IP1: payload.IP,
+ IP2: "",
+ }
+
+ result := db.Create(&play)
+ if result.Error != nil {
+ JsonError(&w, result.Error.Error())
+ return
+ }
+
+ json.NewEncoder(w).Encode(map[string]string{"name": name})
+}
+
+func EnterGame(w http.ResponseWriter, r *http.Request) {
+ slog.Info("POST /enter-game")
+ claims, err := auth.ValidateJWT(r.Header.Get("Authorization"))
+
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ var payload struct {
+ Name string `json:"name"`
+ IP string `json:"ip"`
+ }
+
+ if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ if err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ db, _ := database.GetDb()
+
+ var play database.Game
+
+ result := db.Where("name = ? AND player2_id IS NULL", payload.Name).First(&play)
+ if result.Error != nil {
+ JsonError(&w, result.Error.Error())
+ return
+ }
+
+ play.Player2ID = &claims.UserID
+ play.IP2 = payload.IP
+ play.UpdatedAt = time.Now()
+
+ if err := db.Save(&play).Error; err != nil {
+ JsonError(&w, err.Error())
+ return
+ }
+
+ result = db.Where("id = ?", play.ID).
+ Preload("Player1", func(db *gorm.DB) *gorm.DB {
+ return db.Omit("Password")
+ }).
+ Preload("Player2", func(db *gorm.DB) *gorm.DB {
+ return db.Omit("Password")
+ }).
+ First(&play)
+
+ if result.Error != nil {
+ JsonError(&w, result.Error.Error())
+ return
+ }
+
+ json.NewEncoder(w).Encode(play)
+}