dendrite/zion/store.go
Tak Wai Wong 8f4d1828b4 matrix room Id does not resolve to channelId or spaceId correctly (#1010)
Issue: matrix room id does not always resolve to spaceId or channelId
correctly.

Root cause: The clientApi routing endpoint and the syncapi routing
endpoint uses different stores to query for the current room states.

One is correct, the other has incomplete events. Fix the issue by using
the correct store in both routing code paths.
2022-11-30 20:12:00 -08:00

98 lines
2.4 KiB
Go

/*
Convenient function for space info mapping between Matrix room and Space contract
*/
package zion
import (
"context"
"encoding/json"
"strings"
roomserver "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib"
)
type Store struct {
roomQuery roomserver.QueryEventsAPI
}
func NewStore(roomQuery roomserver.QueryEventsAPI) Store {
return Store{
roomQuery: roomQuery,
}
}
func (s *Store) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
result := RoomInfo{
QueryUserId: userId.MatrixUserId,
SpaceNetworkId: "",
ChannelNetworkId: "",
RoomType: Unknown,
IsOwner: false,
}
createTuple := gomatrixserverlib.StateKeyTuple{
EventType: gomatrixserverlib.MRoomCreate,
StateKey: "",
}
spaceChildTuple := gomatrixserverlib.StateKeyTuple{
EventType: ConstSpaceChildEventType,
StateKey: "*",
}
spaceParentTuple := gomatrixserverlib.StateKeyTuple{
EventType: ConstSpaceParentEventType,
StateKey: "*",
}
var roomEvents roomserver.QueryCurrentStateResponse
err := s.roomQuery.QueryCurrentState(context.Background(), &roomserver.QueryCurrentStateRequest{
RoomID: roomId,
AllowWildcards: true,
StateTuples: []gomatrixserverlib.StateKeyTuple{
createTuple,
spaceParentTuple,
spaceChildTuple,
},
}, &roomEvents)
if err != nil {
return result
}
//TODO: replace with HydrateRoomInfoWithStateEvents when you have a practical way to flatten roomEvents map
doneSearching := false
for _, state := range roomEvents.StateEvents {
switch state.Type() {
case gomatrixserverlib.MRoomCreate:
// Space is created with no children yet.
var creatorEvent CreatorEvent
err := json.Unmarshal(roomEvents.StateEvents[createTuple].Content(), &creatorEvent)
result.IsOwner = strings.HasPrefix(
creatorEvent.Creator,
userId.LocalPart,
)
if err == nil {
result.RoomType = Space
result.SpaceNetworkId = roomId
}
case ConstSpaceChildEventType:
// Space is created and has one or more children.
result.RoomType = Space
result.SpaceNetworkId = roomId
doneSearching = true
case ConstSpaceParentEventType:
// Channel is created and has a reference to the parent.
result.RoomType = Channel
result.SpaceNetworkId = *state.StateKey()
result.ChannelNetworkId = roomId
doneSearching = true
}
if doneSearching {
break
}
}
return result
}