122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
package auth
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
var secret = []byte("test-secret")
|
|
|
|
func sign(t *testing.T, claims jwt.Claims, key []byte) string {
|
|
t.Helper()
|
|
token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(key)
|
|
if err != nil {
|
|
t.Fatalf("sign: %v", err)
|
|
}
|
|
return token
|
|
}
|
|
|
|
func gameToken(t *testing.T, key []byte, exp time.Time) string {
|
|
t.Helper()
|
|
return sign(t, &GameClaims{
|
|
MatchID: "m1",
|
|
Player1ID: 1,
|
|
Player2ID: 2,
|
|
GameServer: "ws://game.example.com/ws",
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
ExpiresAt: jwt.NewNumericDate(exp),
|
|
},
|
|
}, key)
|
|
}
|
|
|
|
func TestParseGameToken(t *testing.T) {
|
|
token := gameToken(t, secret, time.Now().Add(time.Hour))
|
|
claims, err := ParseGameToken(secret, token)
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if claims.MatchID != "m1" || claims.Player1ID != 1 || claims.Player2ID != 2 {
|
|
t.Fatalf("unexpected claims: %+v", claims)
|
|
}
|
|
}
|
|
|
|
func TestParseGameTokenExpired(t *testing.T) {
|
|
token := gameToken(t, secret, time.Now().Add(-time.Hour))
|
|
if _, err := ParseGameToken(secret, token); err == nil {
|
|
t.Fatal("expected error for expired token")
|
|
}
|
|
}
|
|
|
|
func TestParseGameTokenWrongSecret(t *testing.T) {
|
|
token := gameToken(t, []byte("other-secret"), time.Now().Add(time.Hour))
|
|
if _, err := ParseGameToken(secret, token); err == nil {
|
|
t.Fatal("expected error for wrong secret")
|
|
}
|
|
}
|
|
|
|
func TestParseGameTokenMissingExp(t *testing.T) {
|
|
token := sign(t, &GameClaims{MatchID: "m1", Player1ID: 1, Player2ID: 2}, secret)
|
|
if _, err := ParseGameToken(secret, token); err == nil {
|
|
t.Fatal("expected error for token without exp")
|
|
}
|
|
}
|
|
|
|
func TestParseGameTokenNonPositiveIDs(t *testing.T) {
|
|
for _, tc := range [][2]int64{{0, 2}, {-1, 2}, {1, 0}, {1, -5}} {
|
|
token := sign(t, &GameClaims{
|
|
MatchID: "m1",
|
|
Player1ID: tc[0],
|
|
Player2ID: tc[1],
|
|
RegisteredClaims: jwt.RegisteredClaims{
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour)),
|
|
},
|
|
}, secret)
|
|
if _, err := ParseGameToken(secret, token); err == nil {
|
|
t.Fatalf("expected error for non-positive IDs: %+v", tc)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseGameTokenUnverified(t *testing.T) {
|
|
// Works even if expired
|
|
token := gameToken(t, secret, time.Now().Add(-time.Hour))
|
|
claims, err := ParseGameTokenUnverified(token)
|
|
if err != nil {
|
|
t.Fatalf("parse unverified: %v", err)
|
|
}
|
|
if claims.MatchID != "m1" || claims.Player1ID != 1 || claims.Player2ID != 2 {
|
|
t.Fatalf("unexpected claims: %+v", claims)
|
|
}
|
|
if claims.RawToken != token {
|
|
t.Fatalf("raw token mismatch: got %q, want %q", claims.RawToken, token)
|
|
}
|
|
}
|
|
|
|
func TestParseUserToken(t *testing.T) {
|
|
token := sign(t, &UserClaims{
|
|
UserID: 42,
|
|
RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour))},
|
|
}, secret)
|
|
claims, err := ParseUserToken(secret, token)
|
|
if err != nil {
|
|
t.Fatalf("parse: %v", err)
|
|
}
|
|
if claims.UserID != 42 {
|
|
t.Fatalf("user_id = %d, want 42", claims.UserID)
|
|
}
|
|
}
|
|
|
|
func TestParseUserTokenNonPositiveID(t *testing.T) {
|
|
for _, id := range []int64{0, -1, -99} {
|
|
token := sign(t, &UserClaims{
|
|
UserID: id,
|
|
RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour))},
|
|
}, secret)
|
|
if _, err := ParseUserToken(secret, token); err == nil {
|
|
t.Fatalf("expected error for user_id = %d", id)
|
|
}
|
|
}
|
|
}
|