This commit is contained in:
2026-10-11 16:00:18 +07:00
parent 504b49f7cc
commit 030ca56900
77 changed files with 793 additions and 638 deletions
@@ -34,7 +34,7 @@ type IGamePresence interface {
GetGame(context.Context, int) (*game_model.Game, error)
}
type ITeamPresence interface {
CheckPresence(context.Context, int, string) (int, error)
CheckPresence(context.Context, string, string) (int, error)
}
type IScreenPresence interface {
Get(context.Context, int, string) (*screen_service.ScreenSession, error)
@@ -45,7 +45,7 @@ type Heartbeat struct {
DeviceID string
ConnectionID string
OrganizerGameID *int
TeamID *int
TeamID *string
Password string
ScreenID string
ScreenTokenHash string
@@ -64,7 +64,7 @@ type Connection struct {
UserAgent string
Kind string
GameID int
TeamID int
TeamID string
ScreenID int
Connected bool
}
@@ -205,7 +205,7 @@ func (s *DevicePresenceService) verify(ctx context.Context, input Heartbeat) (Co
contexts++
}
}
if contexts > 1 || organizer && *input.OrganizerGameID <= 0 || team && (input.TeamID == nil || *input.TeamID <= 0 || input.Password == "") || screen && (input.ScreenID == "" || input.ScreenTokenHash == "") {
if contexts > 1 || organizer && *input.OrganizerGameID <= 0 || team && (input.TeamID == nil || *input.TeamID == "" || input.Password == "") || screen && (input.ScreenID == "" || input.ScreenTokenHash == "") {
return Connection{}, ErrInvalid
}
connection := Connection{
@@ -25,8 +25,8 @@ func (presenceFixture) GetGame(_ context.Context, id int) (*game_model.Game, err
}
return &game_model.Game{}, nil
}
func (presenceFixture) CheckPresence(_ context.Context, id int, password string) (int, error) {
if id != 2 || password != "secret" {
func (presenceFixture) CheckPresence(_ context.Context, id string, password string) (int, error) {
if id != "019a1234-5678-7abc-8def-000000000002" || password != "secret" {
return 0, team_service.ErrTeamNotFound
}
return 7, nil
@@ -63,7 +63,7 @@ func TestRegistrationAndContext(t *testing.T) {
s, input := newFixture()
now := time.Date(2026, 10, 11, 0, 0, 0, 0, time.UTC)
s.now = func() time.Time { return now }
input.TeamID, input.Password = pointer(2), "secret"
input.TeamID, input.Password = teamPointer("019a1234-5678-7abc-8def-000000000002"), "secret"
send(t, s, input)
now = now.Add(time.Second)
input.IP, input.UserAgent = "192.0.2.1", "updated"
@@ -73,7 +73,7 @@ func TestRegistrationAndContext(t *testing.T) {
t.Fatal(devices)
}
connection := devices[0].Connections[0]
if connection.IP != input.IP || connection.TeamID != 2 || connection.FirstSeenAt.Equal(connection.LastSeenAt) {
if connection.IP != input.IP || connection.TeamID != "019a1234-5678-7abc-8def-000000000002" || connection.FirstSeenAt.Equal(connection.LastSeenAt) {
t.Fatal(connection)
}
tab := input
@@ -88,13 +88,13 @@ func TestRegistrationAndContext(t *testing.T) {
input.ScreenID, input.ScreenTokenHash = "3", "hash"
send(t, s, input)
connection = s.connections[input.ConnectionID]
if connection.TeamID != 0 || connection.ScreenID != 3 || connection.GameID != 7 {
if connection.TeamID != "" || connection.ScreenID != 3 || connection.GameID != 7 {
t.Fatal(connection)
}
input.ScreenID, input.ScreenTokenHash = "", ""
send(t, s, input)
connection = s.connections[input.ConnectionID]
if connection.TeamID != 0 || connection.ScreenID != 0 || connection.GameID != 0 || connection.Kind != "browser" {
if connection.TeamID != "" || connection.ScreenID != 0 || connection.GameID != 0 || connection.Kind != "browser" {
t.Fatal(connection)
}
if len(list(t, s, pointer(7))[0].Connections) != 1 {
@@ -173,9 +173,13 @@ func TestInvalidContextDoesNotOverwrite(t *testing.T) {
{"connection UUID", func(h *Heartbeat) { h.ConnectionID = "" }, ErrInvalid},
{"nil UUID", func(h *Heartbeat) { h.DeviceID = uuid.Nil.String() }, ErrInvalid},
{"device reassignment", func(h *Heartbeat) { h.DeviceID = uuid.NewString() }, ErrInvalid},
{"mixed", func(h *Heartbeat) { h.TeamID = pointer(2); h.Password = "secret"; h.OrganizerGameID = pointer(7) }, ErrInvalid},
{"mixed", func(h *Heartbeat) {
h.TeamID = teamPointer("019a1234-5678-7abc-8def-000000000002")
h.Password = "secret"
h.OrganizerGameID = pointer(7)
}, ErrInvalid},
{"password only", func(h *Heartbeat) { h.Password = "secret" }, ErrInvalid},
{"team only", func(h *Heartbeat) { h.TeamID = pointer(2) }, ErrInvalid},
{"team only", func(h *Heartbeat) { h.TeamID = teamPointer("019a1234-5678-7abc-8def-000000000002") }, ErrInvalid},
{"screen only", func(h *Heartbeat) { h.ScreenID = "3" }, ErrInvalid},
{"token only", func(h *Heartbeat) { h.ScreenTokenHash = "hash" }, ErrInvalid},
{"screen ID", func(h *Heartbeat) { h.ScreenID = "oops"; h.ScreenTokenHash = "hash" }, ErrInvalid},
@@ -183,7 +187,7 @@ func TestInvalidContextDoesNotOverwrite(t *testing.T) {
{"anonymous organizer", func(h *Heartbeat) { h.OrganizerGameID = pointer(7) }, ErrUnauthorized},
{"user organizer", func(h *Heartbeat) { h.OrganizerGameID = pointer(7); h.IsAuthenticated = true }, ErrPermission},
{"missing game", func(h *Heartbeat) { h.OrganizerGameID = pointer(8); h.IsAuthenticated = true; h.CanManage = true }, game_service.ErrGameNotFound},
{"bad team", func(h *Heartbeat) { h.TeamID = pointer(2); h.Password = "bad" }, team_service.ErrTeamNotFound},
{"bad team", func(h *Heartbeat) { h.TeamID = teamPointer("019a1234-5678-7abc-8def-000000000002"); h.Password = "bad" }, team_service.ErrTeamNotFound},
{"bad screen", func(h *Heartbeat) { h.ScreenID = "3"; h.ScreenTokenHash = "bad" }, screen_service.ErrScreenNotFound},
}
for _, test := range tests {
@@ -256,3 +260,5 @@ func TestMetadataUTF8(t *testing.T) {
}
}
}
func teamPointer(id string) *string { return &id }