fix player/session id distinction and add /user/me api endpoint
This commit is contained in:
parent
61db7de4cb
commit
a044844d8b
3
main.go
3
main.go
@ -38,6 +38,7 @@ func main() {
|
||||
r := chi.NewRouter()
|
||||
r.Post("/user/register", s.Register)
|
||||
r.Post("/user/login", s.Login)
|
||||
r.With(serve.WithPlayerID(sessions)).Get("/queue", s.Queue)
|
||||
r.With(serve.WithSession(sessions)).Get("/user/me", s.Me)
|
||||
r.With(serve.WithSession(sessions)).Get("/queue", s.Queue)
|
||||
http.ListenAndServe(":8080", r)
|
||||
}
|
||||
|
@ -34,25 +34,25 @@ func SetSession(w http.ResponseWriter, s player.Session) {
|
||||
})
|
||||
}
|
||||
|
||||
// WithPlayerID is a middleware that adds a player ID to the request context
|
||||
// WithSession is a middleware that adds a player ID to the request context
|
||||
// based on the session cookie content. If there is no such cookie, or its
|
||||
// value is invalid, the request fails with a 403 error.
|
||||
func WithPlayerID(sessions player.RowQuerier) func(http.Handler) http.Handler {
|
||||
// value is invalid, the request fails with a 401 error.
|
||||
func WithSession(sessions player.RowQuerier) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
c, err := r.Cookie(sessionCookie)
|
||||
if err != nil {
|
||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
id, err := player.ParseSession(c.Value)
|
||||
if err != nil {
|
||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
p, err := player.FromSession(r.Context(), sessions, id, time.Now())
|
||||
if err != nil {
|
||||
http.Error(w, "Forbidden", http.StatusForbidden)
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
ctx := with(r.Context(), p)
|
||||
@ -61,7 +61,7 @@ func WithPlayerID(sessions player.RowQuerier) func(http.Handler) http.Handler {
|
||||
}
|
||||
}
|
||||
|
||||
// Player returns the player ID set by WithPlayerID in the request context.
|
||||
func PlayerID(ctx context.Context) player.ID {
|
||||
return value[player.ID](ctx)
|
||||
// Session returns the session ID set by WithSession in the request context.
|
||||
func Session(ctx context.Context) player.Session {
|
||||
return value[player.Session](ctx)
|
||||
}
|
||||
|
30
server.go
30
server.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
@ -20,14 +21,14 @@ import (
|
||||
type Server struct {
|
||||
l *lobby.Lobby
|
||||
|
||||
creds credsDB
|
||||
sessions player.Execer
|
||||
creds db
|
||||
sessions db
|
||||
|
||||
mu sync.Mutex
|
||||
pp map[player.ID]*websocket.Conn
|
||||
}
|
||||
|
||||
type credsDB interface {
|
||||
type db interface {
|
||||
player.RowQuerier
|
||||
player.Execer
|
||||
}
|
||||
@ -133,13 +134,32 @@ func (s *Server) Login(w http.ResponseWriter, r *http.Request) {
|
||||
slog.InfoContext(ctx, "logged in", "player", p, "id", id)
|
||||
}
|
||||
|
||||
func (s *Server) Me(w http.ResponseWriter, r *http.Request) {
|
||||
id := serve.Session(r.Context())
|
||||
if id == (player.Session{}) {
|
||||
panic("missing player ID")
|
||||
}
|
||||
p, err := player.FromSession(r.Context(), s.sessions, id, time.Now())
|
||||
if err != nil {
|
||||
panic("session with no player id: " + err.Error())
|
||||
}
|
||||
q := struct {
|
||||
ID player.ID `json:"id"`
|
||||
}{p}
|
||||
json.NewEncoder(w).Encode(q)
|
||||
}
|
||||
|
||||
// Queue connects players to games. The connection immediately upgrades.
|
||||
// This handler MUST be wrapped in [serve.WithPlayerID].
|
||||
func (s *Server) Queue(w http.ResponseWriter, r *http.Request) {
|
||||
p := serve.PlayerID(r.Context())
|
||||
if p == (player.ID{}) {
|
||||
id := serve.Session(r.Context())
|
||||
if id == (player.Session{}) {
|
||||
panic("missing player ID")
|
||||
}
|
||||
p, err := player.FromSession(r.Context(), s.sessions, id, time.Now())
|
||||
if p == (player.ID{}) {
|
||||
panic("session with no player id: " + err.Error())
|
||||
}
|
||||
person, err := s.accept(w, r, p)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
|
Loading…
Reference in New Issue
Block a user