sliding-sync/tests-integration/token_management_test.go

187 lines
5.7 KiB
Go
Raw Normal View History

2023-05-12 14:58:10 +01:00
package syncv3
import (
2023-05-15 10:48:40 +01:00
"context"
2023-05-12 14:58:10 +01:00
"encoding/json"
2023-05-15 14:27:22 +01:00
"net/http"
"testing"
"time"
"github.com/tidwall/gjson"
2023-05-12 14:58:10 +01:00
"github.com/matrix-org/sliding-sync/sync2"
"github.com/matrix-org/sliding-sync/sync3"
"github.com/matrix-org/sliding-sync/testutils"
"github.com/matrix-org/sliding-sync/testutils/m"
)
2023-05-12 15:10:25 +01:00
func TestSyncWithNewTokenAfterOldExpires(t *testing.T) {
2023-05-12 14:58:10 +01:00
pqString := testutils.PrepareDBConnectionString()
v2 := runTestV2Server(t)
v3 := runTestServer(t, v2, pqString)
defer v2.close()
defer v3.close()
2023-05-12 14:58:10 +01:00
aliceToken1 := "alice_token_1"
2023-05-15 13:47:09 +01:00
aliceToken2 := "alice_token_2"
2023-05-12 14:58:10 +01:00
roomID := "!room:test"
v2.addAccount(t, alice, aliceToken1)
2023-05-12 14:58:10 +01:00
t.Log("Prepare to tell a poller using aliceToken1 that Alice created a room and that Bob joined it.")
bobJoin := testutils.NewJoinEvent(t, bob)
v2.queueResponse(aliceToken1, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(roomEvents{
roomID: roomID,
state: createRoomState(t, alice, time.Now()),
events: []json.RawMessage{bobJoin},
}),
},
2023-05-15 13:47:09 +01:00
NextBatch: "after_alice_initial_poll",
2023-05-12 14:58:10 +01:00
})
t.Log("Alice makes an initial sliding sync.")
2023-05-15 10:48:40 +01:00
req := sync3.Request{
2023-05-12 14:58:10 +01:00
RoomSubscriptions: map[string]sync3.RoomSubscription{
roomID: {TimelineLimit: 10},
},
2023-05-15 10:48:40 +01:00
}
res := v3.mustDoV3Request(t, aliceToken1, req)
2023-05-12 14:58:10 +01:00
t.Log("Alice should see Bob's membership")
m.MatchResponse(t, res,
m.MatchRoomSubscription(roomID, m.MatchRoomTimelineMostRecent(1, []json.RawMessage{bobJoin})),
)
2023-05-15 13:47:09 +01:00
t.Log("From this point forward, the poller should not make any initial sync requests.")
v2.SetCheckRequest(func(token string, req *http.Request) {
2023-05-15 13:47:09 +01:00
switch token {
case aliceToken1: // this is okay; we should return a token expiry response
case aliceToken2: // this is also okay; we should provide a proper response
t.Logf("Got poll for %s", token)
default:
2023-05-15 15:33:52 +01:00
t.Logf("Got unexpected poll for %s", token)
2023-05-15 13:47:09 +01:00
}
since := req.URL.Query().Get("since")
if since == "" {
t.Errorf("Got unexpected initial sync poll for token %s", token)
}
2023-05-15 14:27:22 +01:00
})
2023-05-15 13:47:09 +01:00
2023-05-12 14:58:10 +01:00
t.Log("Alice refreshes her access token. The old one expires.")
v2.addAccount(t, alice, aliceToken2)
2023-05-12 14:58:10 +01:00
v2.invalidateToken(aliceToken1)
2023-05-15 10:48:40 +01:00
t.Log("Alice makes an incremental sliding sync with the new token.")
_, body, code := v3.doV3Request(t, context.Background(), aliceToken2, res.Pos, sync3.Request{})
// TODO: in principle the proxy could remember the previous Pos and serve this
// request immediately. For now we keep things simple and require the client to make
// a new connection.
t.Log("The connection should be expired.")
if code != 400 {
t.Errorf("got HTTP %d want 400", code)
}
if gjson.ParseBytes(body).Get("errcode").Str != "M_UNKNOWN_POS" {
t.Errorf("got %v want errcode=M_UNKNOWN_POS", string(body))
}
2023-05-15 13:47:09 +01:00
t.Log("Prepare to tell a poller using aliceToken2 that Alice created a room and that Bob joined it.")
bobMsg := testutils.NewMessageEvent(t, bob, "Hello, world!")
v2.queueResponse(aliceToken2, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(roomEvents{
roomID: roomID,
events: []json.RawMessage{bobMsg},
}),
},
NextBatch: "after_alice_incremental_poll",
})
2023-05-15 14:26:51 +01:00
t.Log("Alice makes a new sliding sync connection with her new token.")
res = v3.mustDoV3Request(t, aliceToken2, req)
2023-05-15 10:48:40 +01:00
2023-05-15 14:26:51 +01:00
t.Log("Alice should see Bob's message.")
2023-05-12 14:58:10 +01:00
m.MatchResponse(t, res,
m.MatchRoomSubscription(roomID, m.MatchRoomTimelineMostRecent(1, []json.RawMessage{bobMsg})),
)
}
func TestSyncWithNewTokenBeforeOldExpires(t *testing.T) {
pqString := testutils.PrepareDBConnectionString()
v2 := runTestV2Server(t)
v3 := runTestServer(t, v2, pqString)
defer v2.close()
defer v3.close()
aliceToken1 := "alice_token_1"
aliceToken2 := "alice_token_2"
roomID := "!room:test"
v2.addAccount(t, alice, aliceToken1)
t.Log("Prepare to tell a poller using aliceToken1 that Alice created a room and that Bob joined it.")
bobJoin := testutils.NewJoinEvent(t, bob)
v2.queueResponse(aliceToken1, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(roomEvents{
roomID: roomID,
state: createRoomState(t, alice, time.Now()),
events: []json.RawMessage{bobJoin},
}),
},
NextBatch: "after_alice_initial_poll",
})
t.Log("Alice makes an initial sliding sync.")
req := sync3.Request{
RoomSubscriptions: map[string]sync3.RoomSubscription{
roomID: {TimelineLimit: 10},
},
}
res := v3.mustDoV3Request(t, aliceToken1, req)
t.Log("Alice should see Bob's membership")
m.MatchResponse(t, res,
m.MatchRoomSubscription(roomID, m.MatchRoomTimelineMostRecent(1, []json.RawMessage{bobJoin})),
)
t.Log("From this point forward, the poller should not make any initial sync requests.")
v2.SetCheckRequest(func(token string, req *http.Request) {
switch token {
case aliceToken1: // either is okay
case aliceToken2:
t.Logf("Got poll for %s", token)
default:
t.Errorf("Got unexpected poll for %s", token)
}
since := req.URL.Query().Get("since")
if since == "" {
t.Errorf("Got unexpected initial sync poll for token %s", token)
}
})
t.Log("Alice refreshes her access token. The old one has yet to expire.")
v2.addAccount(t, alice, aliceToken2)
t.Log("Prepare to tell a poller using aliceToken1 that Alice created a room and that Bob joined it.")
bobMsg := testutils.NewMessageEvent(t, bob, "Hello, world!")
v2.queueResponse(aliceToken1, sync2.SyncResponse{
Rooms: sync2.SyncRoomsResponse{
Join: v2JoinTimeline(roomEvents{
roomID: roomID,
events: []json.RawMessage{bobMsg},
}),
},
NextBatch: "after_alice_incremental_poll",
})
t.Log("Alice makes an incremental sliding sync with the new token.")
res = v3.mustDoV3RequestWithPos(t, aliceToken2, res.Pos, req)
t.Log("Alice should see Bob's message.")
m.MatchResponse(t, res,
m.MatchRoomSubscription(roomID, m.MatchRoomTimelineMostRecent(1, []json.RawMessage{bobMsg})),
)
}