feat: add verified Steam session endpoint

This commit is contained in:
Josh Creek
2026-08-31 22:26:27 +01:00
parent a2a7107dd7
commit 8253d772cb
3 changed files with 106 additions and 1 deletions
+53
View File
@@ -33,10 +33,18 @@ type QueueBackend interface {
type SessionBackend interface {
Authenticate(context.Context, string, string, time.Time) (domain.Session, error)
}
type SteamLoginProvider interface {
Authenticate(context.Context, string, time.Time) (domain.VerifiedIdentity, error)
}
type SessionIssuer interface {
Issue(context.Context, string, time.Duration, time.Time) (domain.Session, string, error)
}
type Service struct {
Sessions *domain.SessionStore
SessionBackend SessionBackend
SessionIssuer SessionIssuer
SteamLogin SteamLoginProvider
Queue *domain.Queue
Candidate CandidateProvider
CandidateV2 CandidateProviderV2
@@ -52,6 +60,7 @@ type Service struct {
func (s *Service) Handler() http.Handler {
mux := http.NewServeMux()
mux.HandleFunc("/healthz", s.health)
mux.HandleFunc("/v1/session/steam", s.steamSession)
mux.HandleFunc("/v1/queue", s.queueCreate)
mux.HandleFunc("/v1/queue/", s.queueMutation)
mux.HandleFunc("/v1/proposals/", s.proposalMutation)
@@ -60,6 +69,50 @@ func (s *Service) Handler() http.Handler {
return mux
}
type steamSessionRequest struct {
WebAPITicket string `json:"web_api_ticket"`
}
func (s *Service) steamSession(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
writeError(w, http.StatusMethodNotAllowed, "method_not_allowed")
return
}
if s.SteamLogin == nil {
writeError(w, http.StatusServiceUnavailable, "auth_unavailable")
return
}
var input steamSessionRequest
if !decodeBody(w, r, &input) {
return
}
if input.WebAPITicket == "" || len(input.WebAPITicket) > 4096 {
writeError(w, http.StatusBadRequest, "invalid_request")
return
}
now := s.now()
identity, err := s.SteamLogin.Authenticate(r.Context(), input.WebAPITicket, now)
if err != nil || identity.PlayerID == "" || identity.SteamID == "" {
writeError(w, http.StatusUnauthorized, "unauthorized")
return
}
var session domain.Session
var token string
if s.SessionIssuer != nil {
session, token, err = s.SessionIssuer.Issue(r.Context(), identity.PlayerID, time.Hour, now)
} else if s.Sessions != nil {
session, token, err = s.Sessions.Issue(identity.PlayerID, time.Hour, now)
} else {
writeError(w, http.StatusServiceUnavailable, "auth_unavailable")
return
}
if err != nil {
writeError(w, http.StatusServiceUnavailable, "auth_unavailable")
return
}
writeJSON(w, http.StatusOK, map[string]any{"player_id": session.PlayerID, "expires_at": session.ExpiresAt, "access_token": session.SessionID + ":" + token})
}
func (s *Service) health(w http.ResponseWriter, _ *http.Request) {
writeJSON(w, http.StatusOK, map[string]string{"status": "ok"})
}