mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-31 13:22:46 +00:00
[pseudoIDs] More pseudo ID fixes - Part 2 (#3181)
Fixes include: - Translating state keys that contain user IDs to their respective room keys for both querying and sending state events - **NOTE**: there may be design discussion needed on what should happen when sender keys cannot be found for users - A simple fix for kicking guests from rooms properly - Logic for boundary history visibilities was slightly off (I'm surprised this only manifested in pseudo ID room versions) Signed-off-by: `Sam Wedgwood <sam@wedgwood.dev>`
This commit is contained in:
parent
a721294e2b
commit
9b5be6b9c5
11 changed files with 865 additions and 36 deletions
|
@ -29,6 +29,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/syncapi/synctypes"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
|
@ -92,6 +93,30 @@ func SendEvent(
|
|||
}
|
||||
}
|
||||
|
||||
// Translate user ID state keys to room keys in pseudo ID rooms
|
||||
if roomVersion == gomatrixserverlib.RoomVersionPseudoIDs && stateKey != nil {
|
||||
parsedRoomID, innerErr := spec.NewRoomID(roomID)
|
||||
if innerErr != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: spec.InvalidParam("invalid room ID"),
|
||||
}
|
||||
}
|
||||
|
||||
newStateKey, innerErr := synctypes.FromClientStateKey(*parsedRoomID, *stateKey, func(roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error) {
|
||||
return rsAPI.QuerySenderIDForUser(req.Context(), roomID, userID)
|
||||
})
|
||||
if innerErr != nil {
|
||||
// TODO: work out better logic for failure cases (e.g. sender ID not found)
|
||||
util.GetLogger(req.Context()).WithError(innerErr).Error("synctypes.FromClientStateKey failed")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: spec.Unknown("internal server error"),
|
||||
}
|
||||
}
|
||||
stateKey = newStateKey
|
||||
}
|
||||
|
||||
// create a mutex for the specific user in the specific room
|
||||
// this avoids a situation where events that are received in quick succession are sent to the roomserver in a jumbled order
|
||||
userID := device.UserID
|
||||
|
|
275
clientapi/routing/sendevent_test.go
Normal file
275
clientapi/routing/sendevent_test.go
Normal file
|
@ -0,0 +1,275 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
rsapi "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
uapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/fclient"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
// Mock roomserver API for testing
|
||||
//
|
||||
// Currently pretty specialised for the pseudo ID test, so will need
|
||||
// editing if future (other) sendevent tests are using this.
|
||||
type sendEventTestRoomserverAPI struct {
|
||||
rsapi.ClientRoomserverAPI
|
||||
t *testing.T
|
||||
roomIDStr string
|
||||
roomVersion gomatrixserverlib.RoomVersion
|
||||
roomState []*types.HeaderedEvent
|
||||
|
||||
// userID -> room key
|
||||
senderMapping map[string]ed25519.PrivateKey
|
||||
|
||||
savedInputRoomEvents []rsapi.InputRoomEvent
|
||||
}
|
||||
|
||||
func (s *sendEventTestRoomserverAPI) QueryRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error) {
|
||||
if roomID == s.roomIDStr {
|
||||
return s.roomVersion, nil
|
||||
} else {
|
||||
s.t.Logf("room version queried for %s", roomID)
|
||||
return "", fmt.Errorf("unknown room")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *sendEventTestRoomserverAPI) QueryCurrentState(ctx context.Context, req *rsapi.QueryCurrentStateRequest, res *rsapi.QueryCurrentStateResponse) error {
|
||||
res.StateEvents = map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent{}
|
||||
for _, stateKeyTuple := range req.StateTuples {
|
||||
for _, stateEv := range s.roomState {
|
||||
if stateEv.Type() == stateKeyTuple.EventType && stateEv.StateKey() != nil && *stateEv.StateKey() == stateKeyTuple.StateKey {
|
||||
res.StateEvents[stateKeyTuple] = stateEv
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *sendEventTestRoomserverAPI) QueryLatestEventsAndState(ctx context.Context, req *rsapi.QueryLatestEventsAndStateRequest, res *rsapi.QueryLatestEventsAndStateResponse) error {
|
||||
if req.RoomID == s.roomIDStr {
|
||||
res.RoomExists = true
|
||||
res.RoomVersion = s.roomVersion
|
||||
|
||||
res.StateEvents = make([]*types.HeaderedEvent, len(s.roomState))
|
||||
copy(res.StateEvents, s.roomState)
|
||||
|
||||
res.LatestEvents = []string{}
|
||||
res.Depth = 1
|
||||
return nil
|
||||
} else {
|
||||
s.t.Logf("room event/state queried for %s", req.RoomID)
|
||||
return fmt.Errorf("unknown room")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *sendEventTestRoomserverAPI) QuerySenderIDForUser(
|
||||
ctx context.Context,
|
||||
roomID spec.RoomID,
|
||||
userID spec.UserID,
|
||||
) (*spec.SenderID, error) {
|
||||
if roomID.String() == s.roomIDStr {
|
||||
if s.roomVersion == gomatrixserverlib.RoomVersionPseudoIDs {
|
||||
roomKey, ok := s.senderMapping[userID.String()]
|
||||
if ok {
|
||||
sender := spec.SenderIDFromPseudoIDKey(roomKey)
|
||||
return &sender, nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
} else {
|
||||
senderID := spec.SenderIDFromUserID(userID)
|
||||
return &senderID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("room not found")
|
||||
}
|
||||
|
||||
func (s *sendEventTestRoomserverAPI) QueryUserIDForSender(
|
||||
ctx context.Context,
|
||||
roomID spec.RoomID,
|
||||
senderID spec.SenderID,
|
||||
) (*spec.UserID, error) {
|
||||
if roomID.String() == s.roomIDStr {
|
||||
if s.roomVersion == gomatrixserverlib.RoomVersionPseudoIDs {
|
||||
for uID, roomKey := range s.senderMapping {
|
||||
if string(spec.SenderIDFromPseudoIDKey(roomKey)) == string(senderID) {
|
||||
parsedUserID, err := spec.NewUserID(uID, true)
|
||||
if err != nil {
|
||||
s.t.Fatalf("Mock QueryUserIDForSender failed: %s", err)
|
||||
}
|
||||
return parsedUserID, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
userID := senderID.ToUserID()
|
||||
if userID == nil {
|
||||
return nil, fmt.Errorf("bad sender ID")
|
||||
}
|
||||
return userID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("room not found")
|
||||
}
|
||||
|
||||
func (s *sendEventTestRoomserverAPI) SigningIdentityFor(ctx context.Context, roomID spec.RoomID, sender spec.UserID) (fclient.SigningIdentity, error) {
|
||||
if s.roomIDStr == roomID.String() {
|
||||
if s.roomVersion == gomatrixserverlib.RoomVersionPseudoIDs {
|
||||
roomKey, ok := s.senderMapping[sender.String()]
|
||||
if !ok {
|
||||
s.t.Logf("SigningIdentityFor used with unknown user ID: %v", sender.String())
|
||||
return fclient.SigningIdentity{}, fmt.Errorf("could not get signing identity for %v", sender.String())
|
||||
}
|
||||
return fclient.SigningIdentity{PrivateKey: roomKey}, nil
|
||||
} else {
|
||||
return fclient.SigningIdentity{PrivateKey: ed25519.NewKeyFromSeed(make([]byte, 32))}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return fclient.SigningIdentity{}, fmt.Errorf("room not found")
|
||||
}
|
||||
|
||||
func (s *sendEventTestRoomserverAPI) InputRoomEvents(ctx context.Context, req *rsapi.InputRoomEventsRequest, res *rsapi.InputRoomEventsResponse) {
|
||||
s.savedInputRoomEvents = req.InputRoomEvents
|
||||
}
|
||||
|
||||
// Test that user ID state keys are translated correctly
|
||||
func Test_SendEvent_PseudoIDStateKeys(t *testing.T) {
|
||||
nonpseudoIDRoomVersion := gomatrixserverlib.RoomVersionV10
|
||||
pseudoIDRoomVersion := gomatrixserverlib.RoomVersionPseudoIDs
|
||||
|
||||
senderKeySeed := make([]byte, 32)
|
||||
senderUserID := "@testuser:domain"
|
||||
senderPrivKey := ed25519.NewKeyFromSeed(senderKeySeed)
|
||||
senderPseudoID := string(spec.SenderIDFromPseudoIDKey(senderPrivKey))
|
||||
|
||||
eventType := "com.example.test"
|
||||
roomIDStr := "!id:domain"
|
||||
|
||||
device := &uapi.Device{
|
||||
UserID: senderUserID,
|
||||
}
|
||||
|
||||
t.Run("user ID state key are not translated to room key in non-pseudo ID room", func(t *testing.T) {
|
||||
eventsJSON := []string{
|
||||
fmt.Sprintf(`{"type":"m.room.create","state_key":"","room_id":"%v","sender":"%v","content":{"creator":"%v","room_version":"%v"}}`, roomIDStr, senderUserID, senderUserID, nonpseudoIDRoomVersion),
|
||||
fmt.Sprintf(`{"type":"m.room.member","state_key":"%v","room_id":"%v","sender":"%v","content":{"membership":"join"}}`, senderUserID, roomIDStr, senderUserID),
|
||||
}
|
||||
|
||||
roomState, err := createEvents(eventsJSON, nonpseudoIDRoomVersion)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prepare state events: %s", err.Error())
|
||||
}
|
||||
|
||||
rsAPI := &sendEventTestRoomserverAPI{
|
||||
t: t,
|
||||
roomIDStr: roomIDStr,
|
||||
roomVersion: nonpseudoIDRoomVersion,
|
||||
roomState: roomState,
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", "https://domain", io.NopCloser(strings.NewReader("{}")))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to make new request: %s", err.Error())
|
||||
}
|
||||
|
||||
cfg := &config.ClientAPI{}
|
||||
|
||||
resp := SendEvent(req, device, roomIDStr, eventType, nil, &senderUserID, cfg, rsAPI, nil)
|
||||
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatalf("non-200 HTTP code returned: %v\nfull response: %v", resp.Code, resp)
|
||||
}
|
||||
|
||||
assert.Equal(t, len(rsAPI.savedInputRoomEvents), 1)
|
||||
|
||||
ev := rsAPI.savedInputRoomEvents[0]
|
||||
stateKey := ev.Event.StateKey()
|
||||
if stateKey == nil {
|
||||
t.Fatalf("submitted InputRoomEvent has nil state key, when it should be %v", senderUserID)
|
||||
}
|
||||
if *stateKey != senderUserID {
|
||||
t.Fatalf("expected submitted InputRoomEvent to have user ID state key\nfound: %v\nexpected: %v", *stateKey, senderUserID)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("user ID state key are translated to room key in pseudo ID room", func(t *testing.T) {
|
||||
eventsJSON := []string{
|
||||
fmt.Sprintf(`{"type":"m.room.create","state_key":"","room_id":"%v","sender":"%v","content":{"creator":"%v","room_version":"%v"}}`, roomIDStr, senderPseudoID, senderPseudoID, pseudoIDRoomVersion),
|
||||
fmt.Sprintf(`{"type":"m.room.member","state_key":"%v","room_id":"%v","sender":"%v","content":{"membership":"join"}}`, senderPseudoID, roomIDStr, senderPseudoID),
|
||||
}
|
||||
|
||||
roomState, err := createEvents(eventsJSON, pseudoIDRoomVersion)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prepare state events: %s", err.Error())
|
||||
}
|
||||
|
||||
rsAPI := &sendEventTestRoomserverAPI{
|
||||
t: t,
|
||||
roomIDStr: roomIDStr,
|
||||
roomVersion: pseudoIDRoomVersion,
|
||||
senderMapping: map[string]ed25519.PrivateKey{
|
||||
senderUserID: senderPrivKey,
|
||||
},
|
||||
roomState: roomState,
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", "https://domain", io.NopCloser(strings.NewReader("{}")))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to make new request: %s", err.Error())
|
||||
}
|
||||
|
||||
cfg := &config.ClientAPI{}
|
||||
|
||||
resp := SendEvent(req, device, roomIDStr, eventType, nil, &senderUserID, cfg, rsAPI, nil)
|
||||
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatalf("non-200 HTTP code returned: %v\nfull response: %v", resp.Code, resp)
|
||||
}
|
||||
|
||||
assert.Equal(t, len(rsAPI.savedInputRoomEvents), 1)
|
||||
|
||||
ev := rsAPI.savedInputRoomEvents[0]
|
||||
stateKey := ev.Event.StateKey()
|
||||
if stateKey == nil {
|
||||
t.Fatalf("submitted InputRoomEvent has nil state key, when it should be %v", senderPseudoID)
|
||||
}
|
||||
if *stateKey != senderPseudoID {
|
||||
t.Fatalf("expected submitted InputRoomEvent to have pseudo ID state key\nfound: %v\nexpected: %v", *stateKey, senderPseudoID)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func createEvents(eventsJSON []string, roomVer gomatrixserverlib.RoomVersion) ([]*types.HeaderedEvent, error) {
|
||||
events := make([]*types.HeaderedEvent, len(eventsJSON))
|
||||
|
||||
roomVerImpl, err := gomatrixserverlib.GetRoomVersion(roomVer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("no roomver impl: %s", err.Error())
|
||||
}
|
||||
|
||||
for i, eventJSON := range eventsJSON {
|
||||
pdu, evErr := roomVerImpl.NewEventFromTrustedJSON([]byte(eventJSON), false)
|
||||
if evErr != nil {
|
||||
return nil, fmt.Errorf("failed to make event: %s", err.Error())
|
||||
}
|
||||
ev := types.HeaderedEvent{PDU: pdu}
|
||||
events[i] = &ev
|
||||
}
|
||||
|
||||
return events, nil
|
||||
}
|
|
@ -217,6 +217,37 @@ func OnIncomingStateTypeRequest(
|
|||
var worldReadable bool
|
||||
var wantLatestState bool
|
||||
|
||||
roomVer, err := rsAPI.QueryRoomVersionForRoom(ctx, roomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: spec.Forbidden(fmt.Sprintf("Unknown room %q or user %q has never joined this room", roomID, device.UserID)),
|
||||
}
|
||||
}
|
||||
|
||||
// Translate user ID state keys to room keys in pseudo ID rooms
|
||||
if roomVer == gomatrixserverlib.RoomVersionPseudoIDs {
|
||||
parsedRoomID, err := spec.NewRoomID(roomID)
|
||||
if err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusNotFound,
|
||||
JSON: spec.InvalidParam("invalid room ID"),
|
||||
}
|
||||
}
|
||||
newStateKey, err := synctypes.FromClientStateKey(*parsedRoomID, stateKey, func(roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error) {
|
||||
return rsAPI.QuerySenderIDForUser(ctx, roomID, userID)
|
||||
})
|
||||
if err != nil {
|
||||
// TODO: work out better logic for failure cases (e.g. sender ID not found)
|
||||
util.GetLogger(ctx).WithError(err).Error("synctypes.FromClientStateKey failed")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: spec.Unknown("internal server error"),
|
||||
}
|
||||
}
|
||||
stateKey = *newStateKey
|
||||
}
|
||||
|
||||
// Always fetch visibility so that we can work out whether to show
|
||||
// the latest events or the last event from when the user was joined.
|
||||
// Then include the requested event type and state key, assuming it
|
||||
|
|
253
clientapi/routing/state_test.go
Normal file
253
clientapi/routing/state_test.go
Normal file
|
@ -0,0 +1,253 @@
|
|||
package routing
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
rsapi "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
uapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
||||
"github.com/matrix-org/util"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
var ()
|
||||
|
||||
type stateTestRoomserverAPI struct {
|
||||
rsapi.RoomserverInternalAPI
|
||||
t *testing.T
|
||||
roomState map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent
|
||||
roomIDStr string
|
||||
roomVersion gomatrixserverlib.RoomVersion
|
||||
userIDStr string
|
||||
// userID -> senderID
|
||||
senderMapping map[string]string
|
||||
}
|
||||
|
||||
func (s stateTestRoomserverAPI) QueryRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error) {
|
||||
if roomID == s.roomIDStr {
|
||||
return s.roomVersion, nil
|
||||
} else {
|
||||
s.t.Logf("room version queried for %s", roomID)
|
||||
return "", fmt.Errorf("unknown room")
|
||||
}
|
||||
}
|
||||
|
||||
func (s stateTestRoomserverAPI) QueryLatestEventsAndState(
|
||||
ctx context.Context,
|
||||
req *rsapi.QueryLatestEventsAndStateRequest,
|
||||
res *rsapi.QueryLatestEventsAndStateResponse,
|
||||
) error {
|
||||
res.RoomExists = req.RoomID == s.roomIDStr
|
||||
if !res.RoomExists {
|
||||
return nil
|
||||
}
|
||||
|
||||
res.StateEvents = []*types.HeaderedEvent{}
|
||||
for _, stateKeyTuple := range req.StateToFetch {
|
||||
val, ok := s.roomState[stateKeyTuple]
|
||||
if ok && val != nil {
|
||||
res.StateEvents = append(res.StateEvents, val)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s stateTestRoomserverAPI) QueryMembershipForUser(
|
||||
ctx context.Context,
|
||||
req *rsapi.QueryMembershipForUserRequest,
|
||||
res *rsapi.QueryMembershipForUserResponse,
|
||||
) error {
|
||||
if req.UserID.String() == s.userIDStr {
|
||||
res.HasBeenInRoom = true
|
||||
res.IsInRoom = true
|
||||
res.RoomExists = true
|
||||
res.Membership = spec.Join
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s stateTestRoomserverAPI) QuerySenderIDForUser(
|
||||
ctx context.Context,
|
||||
roomID spec.RoomID,
|
||||
userID spec.UserID,
|
||||
) (*spec.SenderID, error) {
|
||||
sID, ok := s.senderMapping[userID.String()]
|
||||
if ok {
|
||||
sender := spec.SenderID(sID)
|
||||
return &sender, nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s stateTestRoomserverAPI) QueryUserIDForSender(
|
||||
ctx context.Context,
|
||||
roomID spec.RoomID,
|
||||
senderID spec.SenderID,
|
||||
) (*spec.UserID, error) {
|
||||
for uID, sID := range s.senderMapping {
|
||||
if sID == string(senderID) {
|
||||
parsedUserID, err := spec.NewUserID(uID, true)
|
||||
if err != nil {
|
||||
s.t.Fatalf("Mock QueryUserIDForSender failed: %s", err)
|
||||
}
|
||||
return parsedUserID, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s stateTestRoomserverAPI) QueryStateAfterEvents(
|
||||
ctx context.Context,
|
||||
req *rsapi.QueryStateAfterEventsRequest,
|
||||
res *rsapi.QueryStateAfterEventsResponse,
|
||||
) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test_OnIncomingStateTypeRequest(t *testing.T) {
|
||||
var tempRoomServerCfg config.RoomServer
|
||||
tempRoomServerCfg.Defaults(config.DefaultOpts{})
|
||||
defaultRoomVersion := tempRoomServerCfg.DefaultRoomVersion
|
||||
pseudoIDRoomVersion := gomatrixserverlib.RoomVersionPseudoIDs
|
||||
nonPseudoIDRoomVersion := gomatrixserverlib.RoomVersionV10
|
||||
|
||||
userIDStr := "@testuser:domain"
|
||||
eventType := "com.example.test"
|
||||
stateKey := "testStateKey"
|
||||
roomIDStr := "!id:domain"
|
||||
|
||||
device := &uapi.Device{
|
||||
UserID: userIDStr,
|
||||
}
|
||||
|
||||
t.Run("request simple state key", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
rsAPI := stateTestRoomserverAPI{
|
||||
roomVersion: defaultRoomVersion,
|
||||
roomIDStr: roomIDStr,
|
||||
roomState: map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent{
|
||||
{
|
||||
EventType: eventType,
|
||||
StateKey: stateKey,
|
||||
}: mustCreateStatePDU(t, defaultRoomVersion, roomIDStr, eventType, stateKey, map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}),
|
||||
},
|
||||
userIDStr: userIDStr,
|
||||
}
|
||||
|
||||
jsonResp := OnIncomingStateTypeRequest(ctx, device, rsAPI, roomIDStr, eventType, stateKey, false)
|
||||
|
||||
assert.DeepEqual(t, jsonResp, util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: spec.RawJSON(`{"foo":"bar"}`),
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("user ID key translated to room key in pseudo ID rooms", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateSenderUserID := "@sender:domain"
|
||||
stateSenderRoomKey := "testsenderkey"
|
||||
|
||||
rsAPI := stateTestRoomserverAPI{
|
||||
roomVersion: pseudoIDRoomVersion,
|
||||
roomIDStr: roomIDStr,
|
||||
roomState: map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent{
|
||||
{
|
||||
EventType: eventType,
|
||||
StateKey: stateSenderRoomKey,
|
||||
}: mustCreateStatePDU(t, pseudoIDRoomVersion, roomIDStr, eventType, stateSenderRoomKey, map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}),
|
||||
{
|
||||
EventType: eventType,
|
||||
StateKey: stateSenderUserID,
|
||||
}: mustCreateStatePDU(t, pseudoIDRoomVersion, roomIDStr, eventType, stateSenderUserID, map[string]interface{}{
|
||||
"not": "thisone",
|
||||
}),
|
||||
},
|
||||
userIDStr: userIDStr,
|
||||
senderMapping: map[string]string{
|
||||
stateSenderUserID: stateSenderRoomKey,
|
||||
},
|
||||
}
|
||||
|
||||
jsonResp := OnIncomingStateTypeRequest(ctx, device, rsAPI, roomIDStr, eventType, stateSenderUserID, false)
|
||||
|
||||
assert.DeepEqual(t, jsonResp, util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: spec.RawJSON(`{"foo":"bar"}`),
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("user ID key not translated to room key in non-pseudo ID rooms", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
stateSenderUserID := "@sender:domain"
|
||||
stateSenderRoomKey := "testsenderkey"
|
||||
|
||||
rsAPI := stateTestRoomserverAPI{
|
||||
roomVersion: nonPseudoIDRoomVersion,
|
||||
roomIDStr: roomIDStr,
|
||||
roomState: map[gomatrixserverlib.StateKeyTuple]*types.HeaderedEvent{
|
||||
{
|
||||
EventType: eventType,
|
||||
StateKey: stateSenderRoomKey,
|
||||
}: mustCreateStatePDU(t, nonPseudoIDRoomVersion, roomIDStr, eventType, stateSenderRoomKey, map[string]interface{}{
|
||||
"not": "thisone",
|
||||
}),
|
||||
{
|
||||
EventType: eventType,
|
||||
StateKey: stateSenderUserID,
|
||||
}: mustCreateStatePDU(t, nonPseudoIDRoomVersion, roomIDStr, eventType, stateSenderUserID, map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}),
|
||||
},
|
||||
userIDStr: userIDStr,
|
||||
senderMapping: map[string]string{
|
||||
stateSenderUserID: stateSenderUserID,
|
||||
},
|
||||
}
|
||||
|
||||
jsonResp := OnIncomingStateTypeRequest(ctx, device, rsAPI, roomIDStr, eventType, stateSenderUserID, false)
|
||||
|
||||
assert.DeepEqual(t, jsonResp, util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: spec.RawJSON(`{"foo":"bar"}`),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func mustCreateStatePDU(t *testing.T, roomVer gomatrixserverlib.RoomVersion, roomID string, stateType string, stateKey string, stateContent map[string]interface{}) *types.HeaderedEvent {
|
||||
t.Helper()
|
||||
roomVerImpl := gomatrixserverlib.MustGetRoomVersion(roomVer)
|
||||
|
||||
evBytes, err := json.Marshal(map[string]interface{}{
|
||||
"room_id": roomID,
|
||||
"type": stateType,
|
||||
"state_key": stateKey,
|
||||
"content": stateContent,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create event: %v", err)
|
||||
}
|
||||
|
||||
ev, err := roomVerImpl.NewEventFromTrustedJSON(evBytes, false)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create event: %v", err)
|
||||
}
|
||||
|
||||
return &types.HeaderedEvent{PDU: ev}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue