From 37fe76456e6b397cdf5b37f4ba84ff1880ffcb45 Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Fri, 11 Jul 2025 09:03:18 +0300 Subject: [PATCH] Fix: on login add player once --- components/stats.html | 2 +- handlers/auth.go | 37 +++++++++++++++------------- handlers/handlers.go | 4 ++- handlers/middleware.go | 9 ------- migrations/001_initial_schema.up.sql | 4 +-- models/main.go | 2 +- repos/player_stats.go | 6 ++--- 7 files changed, 30 insertions(+), 34 deletions(-) diff --git a/components/stats.html b/components/stats.html index 50df931..e2cdcd6 100644 --- a/components/stats.html +++ b/components/stats.html @@ -35,7 +35,7 @@ {{range .}} - {{.PlayerUsername}} + {{.Username}} {{.GamesPlayed}} {{.GamesWon}} {{.GamesLost}} diff --git a/handlers/auth.go b/handlers/auth.go index a57d92d..2f82578 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -1,7 +1,6 @@ package handlers import ( - "context" "crypto/hmac" "crypto/sha256" "encoding/base64" @@ -9,7 +8,6 @@ import ( "gralias/models" "gralias/utils" "html/template" - "log/slog" "net/http" "strings" "time" @@ -93,7 +91,7 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { } } // login user - cookie, err := makeCookie(cleanName, r.RemoteAddr) + cookie, session, err := makeCookie(cleanName, r.RemoteAddr) if err != nil { log.Error("failed to login", "error", err) abortWithError(w, err.Error()) @@ -136,10 +134,15 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { } } } + if err := repo.SessionCreate(r.Context(), session); err != nil { + log.Error("failed to save session", "error", err) + abortWithError(w, err.Error()) + return + } http.Redirect(w, r, "/", 302) } -func makeCookie(username string, remote string) (*http.Cookie, error) { +func makeCookie(username string, remote string) (*http.Cookie, *models.Session, error) { // secret // Create a new random session token // sessionToken := xid.New().String() @@ -176,19 +179,19 @@ func makeCookie(username string, remote string) (*http.Cookie, error) { cookie.Secure = false log.Info("changing cookie domain", "domain", cookie.Domain) } - player, err := repo.PlayerGetByName(context.Background(), username) - if err != nil || player == nil { - // make player first, since username is fk to players table - player = models.InitPlayer(username) - if err := repo.PlayerAdd(context.Background(), player); err != nil { - slog.Error("failed to create player", "username", username) - return nil, err - } - } - if err := repo.SessionCreate(context.Background(), session); err != nil { - return nil, err - } - return cookie, nil + // player, err := repo.PlayerGetByName(context.Background(), username) + // if err != nil || player == nil { + // // make player first, since username is fk to players table + // player = models.InitPlayer(username) + // if err := repo.PlayerAdd(context.Background(), player); err != nil { + // slog.Error("failed to create player", "username", username) + // return nil, err + // } + // } + // if err := repo.SessionCreate(context.Background(), session); err != nil { + // return nil, err + // } + return cookie, session, nil } func HandleSignout(w http.ResponseWriter, r *http.Request) { diff --git a/handlers/handlers.go b/handlers/handlers.go index 2a34edd..12a94a0 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -128,8 +128,10 @@ func HandleStats(w http.ResponseWriter, r *http.Request) { return } fi, err := getFullInfoByCtx(r.Context()) - if err != nil { + if err != nil || fi == nil { log.Error("failed to fetch fi", "error", err) + http.Redirect(w, r, "/", 302) + return } // there must be a better way if fi != nil && fi.Room != nil && fi.Room.ID != "" && fi.State != nil { diff --git a/handlers/middleware.go b/handlers/middleware.go index 47242a9..ba34d0f 100644 --- a/handlers/middleware.go +++ b/handlers/middleware.go @@ -61,8 +61,6 @@ func GetSession(next http.Handler) http.Handler { return } userSession, err := repo.SessionByToken(r.Context(), sessionToken) - // userSession, err := cacheGetSession(sessionToken) - // log.Debug("userSession from cache", "us", userSession) if err != nil { msg := "auth failed; session does not exists" log.Debug(msg, "error", err, "key", sessionToken) @@ -83,13 +81,6 @@ func GetSession(next http.Handler) http.Handler { models.CtxUsernameKey, userSession.Username) ctx = context.WithValue(ctx, models.CtxSessionKey, userSession) - // if err := cacheSetSession(sessionToken, - // userSession); err != nil { - // msg := "failed to marshal user session" - // log.Warn(msg, "error", err) - // next.ServeHTTP(w, r) - // return - // } next.ServeHTTP(w, r.WithContext(ctx)) }) } diff --git a/migrations/001_initial_schema.up.sql b/migrations/001_initial_schema.up.sql index 6748d11..bae52bd 100644 --- a/migrations/001_initial_schema.up.sql +++ b/migrations/001_initial_schema.up.sql @@ -90,7 +90,7 @@ CREATE TABLE journal( CREATE TABLE player_stats ( id INTEGER PRIMARY KEY AUTOINCREMENT, - player_username TEXT NOT NULL UNIQUE, + username TEXT NOT NULL UNIQUE, games_played INTEGER NOT NULL DEFAULT 0, games_won INTEGER NOT NULL DEFAULT 0, games_lost INTEGER NOT NULL DEFAULT 0, @@ -101,6 +101,6 @@ CREATE TABLE player_stats ( guesser_winrate REAL NOT NULL DEFAULT 0.0, played_as_mime INTEGER NOT NULL DEFAULT 0, played_as_guesser INTEGER NOT NULL DEFAULT 0, - FOREIGN KEY (player_username) REFERENCES players(username) ON DELETE CASCADE + FOREIGN KEY (username) REFERENCES players(username) ON DELETE CASCADE ); diff --git a/models/main.go b/models/main.go index 2e6ccbe..42a3194 100644 --- a/models/main.go +++ b/models/main.go @@ -141,7 +141,7 @@ type Journal struct { type PlayerStats struct { ID uint32 `db:"id"` - PlayerUsername string `db:"player_username"` + Username string `db:"username"` GamesPlayed int `db:"games_played"` GamesWon int `db:"games_won"` GamesLost int `db:"games_lost"` diff --git a/repos/player_stats.go b/repos/player_stats.go index a4cab6d..fbb0495 100644 --- a/repos/player_stats.go +++ b/repos/player_stats.go @@ -16,7 +16,7 @@ type PlayerStatsRepo interface { func (p *RepoProvider) GetPlayerStats(ctx context.Context, username string) (*models.PlayerStats, error) { stats := &models.PlayerStats{} - err := sqlx.GetContext(ctx, p.DB, stats, "SELECT * FROM player_stats WHERE player_username = ?", username) + err := sqlx.GetContext(ctx, p.DB, stats, "SELECT * FROM player_stats WHERE username = ?", username) return stats, err } @@ -38,12 +38,12 @@ func (p *RepoProvider) UpdatePlayerStats(ctx context.Context, stats *models.Play guesser_winrate = :guesser_winrate, played_as_mime = :played_as_mime, played_as_guesser = :played_as_guesser - WHERE player_username = :player_username`, stats) + WHERE username = :username`, stats) return err } func (p *RepoProvider) CreatePlayerStats(ctx context.Context, username string) error { db := getDB(ctx, p.DB) - _, err := db.ExecContext(ctx, "INSERT INTO player_stats (player_username) VALUES (?)", username) + _, err := db.ExecContext(ctx, "INSERT INTO player_stats (username) VALUES (?)", username) return err }