From 502317507b3ff1b8e38ca550bb971241daf4d7fd Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Wed, 9 Jul 2025 12:39:16 +0300 Subject: [PATCH] Feat: add password for player --- components/linklogin.html | 6 +++++- components/login.html | 6 +++++- components/roomlist.html | 3 --- crons/main.go | 12 ++++++------ handlers/auth.go | 25 +++++++++---------------- handlers/handlers.go | 9 +++------ migrations/001_initial_schema.up.sql | 1 + models/main.go | 5 ++--- repos/players.go | 6 +++--- repos/players_test.go | 6 ++++-- 10 files changed, 38 insertions(+), 41 deletions(-) diff --git a/components/linklogin.html b/components/linklogin.html index 2898405..275fcc4 100644 --- a/components/linklogin.html +++ b/components/linklogin.html @@ -8,8 +8,12 @@
this name looks available
+ +
+ +
- +
diff --git a/components/login.html b/components/login.html index 68179b2..e2e52ae 100644 --- a/components/login.html +++ b/components/login.html @@ -2,12 +2,16 @@
- +
this name looks available
+
+ + +
diff --git a/components/roomlist.html b/components/roomlist.html index f0d6bea..b438adf 100644 --- a/components/roomlist.html +++ b/components/roomlist.html @@ -1,9 +1,6 @@ {{define "roomlist"}}
{{range .}} -

- {{.ID}} -

diff --git a/crons/main.go b/crons/main.go index 1bee68a..2a601bf 100644 --- a/crons/main.go +++ b/crons/main.go @@ -4,6 +4,8 @@ import ( "context" "database/sql" "errors" + "gralias/broker" + "gralias/models" "gralias/repos" "log/slog" "time" @@ -61,7 +63,6 @@ func (cm *CronManager) CleanupRooms() { cm.log.Error("failed to get players for room", "room_id", room.ID, "err", err) continue } - if len(players) == 0 { cm.log.Info("deleting empty room", "room_id", room.ID) if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil { @@ -72,7 +73,6 @@ func (cm *CronManager) CleanupRooms() { } continue } - creatorInRoom := false for _, player := range players { if player.Username == room.CreatorName { @@ -80,7 +80,6 @@ func (cm *CronManager) CleanupRooms() { break } } - isInactive := false // If the creator is in the room and the room is more than one hour old, check for inactivity if creatorInRoom && time.Since(room.CreatedAt) > time.Hour { @@ -104,7 +103,6 @@ func (cm *CronManager) CleanupRooms() { reason = "inactive" } cm.log.Info("deleting room", "room_id", room.ID, "reason", reason) - for _, player := range players { if player.IsBot { if err := cm.repo.PlayerDelete(ctx, room.ID); err != nil { @@ -116,14 +114,12 @@ func (cm *CronManager) CleanupRooms() { } } } - if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil { cm.log.Error("failed to delete room", "room_id", room.ID, "reason", reason, "err", err) } if err := cm.repo.SettingsDeleteByRoomID(ctx, room.ID); err != nil { cm.log.Error("failed to delete settings for room", "room_id", room.ID, "reason", reason, "err", err) } - // Move to the next room continue } @@ -131,6 +127,10 @@ func (cm *CronManager) CleanupRooms() { if err := tx.Commit(); err != nil { cm.log.Error("failed to commit transaction", "err", err) } + broker.Notifier.Notifier <- broker.NotificationEvent{ + EventName: models.NotifyRoomListUpdate, + Payload: "", + } } func (cm *CronManager) CleanupActions() { diff --git a/handlers/auth.go b/handlers/auth.go index 6ce22b9..c544ca8 100644 --- a/handlers/auth.go +++ b/handlers/auth.go @@ -37,7 +37,6 @@ func HandleNameCheck(w http.ResponseWriter, r *http.Request) { return } cleanName := utils.RemoveSpacesFromStr(username) - // allNames := getAllNames() allNames, err := repo.PlayerListNames(r.Context()) if err != nil { abortWithError(w, err.Error()) @@ -74,10 +73,12 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { abortWithError(w, msg) return } + password := r.PostFormValue("password") var makeplayer bool roomID := r.PostFormValue("room_id") // make sure username does not exists cleanName := utils.RemoveSpacesFromStr(username) + clearPass := utils.RemoveSpacesFromStr(password) // login user cookie, err := makeCookie(cleanName, r.RemoteAddr) if err != nil { @@ -85,15 +86,19 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { abortWithError(w, err.Error()) return } - http.SetCookie(w, cookie) // check if that user was already in db - // userstate, err := loadState(cleanName) userstate, err := repo.PlayerGetByName(r.Context(), cleanName) if err != nil || userstate == nil { log.Debug("making new player", "error", err, "state", userstate) userstate = models.InitPlayer(cleanName) makeplayer = true } + if userstate.Password != clearPass { + log.Error("wrong password", "username", cleanName, "password", clearPass) + abortWithError(w, "wrong password") + return + } + http.SetCookie(w, cookie) fi := &models.FullInfo{ State: userstate, } @@ -106,20 +111,12 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { abortWithError(w, err.Error()) return } - // room.PlayerList = append(room.PlayerList, fi.State.Username) - // fi.Room = room fi.List = nil fi.State.RoomID = &room.ID if err := repo.PlayerSetRoomID(r.Context(), room.ID, fi.State.Username); err != nil { abortWithError(w, err.Error()) return } - // repo.RoomUpdate() - // save full info instead - // if err := saveFullInfo(r.Context(), fi); err != nil { - // abortWithError(w, err.Error()) - // return - // } } else { log.Debug("no room_id in login") // fi.List = listRooms(false) @@ -129,19 +126,15 @@ func HandleFrontLogin(w http.ResponseWriter, r *http.Request) { return } // save state to cache - // if err := saveState(cleanName, userstate); err != nil { if makeplayer { + userstate.Password = clearPass if err := repo.PlayerAdd(r.Context(), userstate); err != nil { - // if err := saveFullInfo(r.Context(), fi); err != nil { log.Error("failed to save state", "error", err) abortWithError(w, err.Error()) return } } } - // if err := tmpl.ExecuteTemplate(w, "base", fi); err != nil { - // log.Error("failed to execute base template", "error", err) - // } http.Redirect(w, r, "/", 302) } diff --git a/handlers/handlers.go b/handlers/handlers.go index bb6c9c7..b2df877 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -94,19 +94,16 @@ func HandleExit(w http.ResponseWriter, r *http.Request) { } notify(models.NotifyRoomListUpdate, "") } - // scary to update the whole room - fiToSave := &models.FullInfo{ - Room: exitedRoom, - } if err := repo.PlayerExitRoom(r.Context(), fi.State.Username); err != nil { + log.Error("failed to exit room", "error", err) abortWithError(w, err.Error()) return } - if err := saveFullInfo(r.Context(), fiToSave); err != nil { + if err := repo.RoomUpdate(r.Context(), exitedRoom); err != nil { + log.Error("failed to update room", "error", err) abortWithError(w, err.Error()) return } - // fi.List = listRooms(false) fi.List, err = repo.RoomList(r.Context()) if err != nil { abortWithError(w, err.Error()) diff --git a/migrations/001_initial_schema.up.sql b/migrations/001_initial_schema.up.sql index 9bd3f79..6748d11 100644 --- a/migrations/001_initial_schema.up.sql +++ b/migrations/001_initial_schema.up.sql @@ -21,6 +21,7 @@ CREATE TABLE players ( id INTEGER PRIMARY KEY AUTOINCREMENT, room_id TEXT, -- nullable username TEXT NOT NULL UNIQUE, + password TEXT NOT NULL DEFAULT '', team TEXT NOT NULL DEFAULT '', -- 'red' or 'blue' role TEXT NOT NULL DEFAULT '', -- 'guesser' or 'mime' is_bot BOOLEAN NOT NULL DEFAULT FALSE, diff --git a/models/main.go b/models/main.go index 1e7aa8f..2e6ccbe 100644 --- a/models/main.go +++ b/models/main.go @@ -106,6 +106,7 @@ type Player struct { ID uint32 `json:"id" db:"id"` RoomID *string `json:"room_id" db:"room_id"` Username string `json:"username" db:"username"` + Password string `json:"-" db:"password"` Team UserTeam `json:"team" db:"team"` Role UserRole `json:"role" db:"role"` IsBot bool `json:"is_bot" db:"is_bot"` @@ -153,7 +154,6 @@ type PlayerStats struct { PlayedAsGuesser int `db:"played_as_guesser"` } - type Room struct { ID string `json:"id" db:"id"` CreatedAt time.Time `json:"created_at" db:"created_at"` @@ -465,7 +465,6 @@ type FullInfo struct { } func (f *FullInfo) ExitRoom() *Room { - // f.Room.PlayerList = utils.RemoveFromSlice(f.State.Username, f.Room.PlayerList) f.Room.RedTeam.Guessers = utils.RemoveFromSlice(f.State.Username, f.Room.RedTeam.Guessers) f.Room.BlueTeam.Guessers = utils.RemoveFromSlice(f.State.Username, f.Room.BlueTeam.Guessers) if f.Room.RedTeam.Mime == f.State.Username { @@ -474,7 +473,7 @@ func (f *FullInfo) ExitRoom() *Room { if f.Room.BlueTeam.Mime == f.State.Username { f.Room.BlueTeam.Mime = "" } - // f.State.ExitRoom() + f.State.RoomID = nil resp := f.Room f.Room = nil return resp diff --git a/repos/players.go b/repos/players.go index 5694675..b736c05 100644 --- a/repos/players.go +++ b/repos/players.go @@ -32,7 +32,7 @@ func (p *RepoProvider) PlayerListNames(ctx context.Context) ([]string, error) { func (p *RepoProvider) PlayerGetByName(ctx context.Context, username string) (*models.Player, error) { var player models.Player - err := sqlx.GetContext(ctx, p.DB, &player, "SELECT id, room_id, username, team, role, is_bot FROM players WHERE username = ?", username) + err := sqlx.GetContext(ctx, p.DB, &player, "SELECT id, room_id, username, team, role, is_bot, password FROM players WHERE username = ?", username) if err != nil { return nil, err } @@ -44,8 +44,8 @@ func (p *RepoProvider) PlayerGetByName(ctx context.Context, username string) (*m func (p *RepoProvider) PlayerAdd(ctx context.Context, player *models.Player) error { db := getDB(ctx, p.DB) - _, err := db.ExecContext(ctx, "INSERT INTO players (room_id, username, team, role, is_bot) VALUES (?, ?, ?, ?, ?)", - player.RoomID, player.Username, player.Team, player.Role, player.IsBot) + _, err := db.ExecContext(ctx, "INSERT INTO players (room_id, username, team, role, is_bot, password) VALUES (?, ?, ?, ?, ?, ?)", + player.RoomID, player.Username, player.Team, player.Role, player.IsBot, player.Password) return err } diff --git a/repos/players_test.go b/repos/players_test.go index 383fcb4..e532194 100644 --- a/repos/players_test.go +++ b/repos/players_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/jmoiron/sqlx" - "github.com/stretchr/testify/assert" _ "github.com/mattn/go-sqlite3" + "github.com/stretchr/testify/assert" ) func setupPlayersTestDB(t *testing.T) (*sqlx.DB, func()) { @@ -19,6 +19,7 @@ func setupPlayersTestDB(t *testing.T) (*sqlx.DB, func()) { id INTEGER PRIMARY KEY AUTOINCREMENT, room_id TEXT, username TEXT, + password TEXT NOT NULL DEFAULT '', team TEXT, role TEXT, is_bot BOOLEAN @@ -105,4 +106,5 @@ func TestPlayersRepo_DeletePlayer(t *testing.T) { err = db.Get(&count, "SELECT COUNT(*) FROM players WHERE room_id = ? AND username = ?", player.RoomID, player.Username) assert.NoError(t, err) assert.Equal(t, 0, count) -} \ No newline at end of file +} +