mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-16 18:43:10 -06:00
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.
This commit is contained in:
parent
a8127f9bdc
commit
8f4d1828b4
|
|
@ -2,16 +2,16 @@ package authorization
|
|||
|
||||
import (
|
||||
"github.com/matrix-org/dendrite/authorization"
|
||||
roomserver "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/dendrite/setup/config"
|
||||
_ "github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/zion"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func NewRoomserverAuthorization(cfg *config.ClientAPI, rsAPI zion.RoomserverStoreAPI) authorization.Authorization {
|
||||
func NewRoomserverAuthorization(cfg *config.ClientAPI, roomQueryAPI roomserver.QueryEventsAPI) authorization.Authorization {
|
||||
// Load authorization manager for Zion
|
||||
if cfg.PublicKeyAuthentication.Ethereum.GetEnableAuthZ() {
|
||||
auth, err := zion.NewZionAuthorization(cfg, rsAPI)
|
||||
auth, err := zion.NewZionAuthorization(cfg, roomQueryAPI)
|
||||
|
||||
if err != nil {
|
||||
log.Errorln("Failed to initialise Zion authorization manager. Using default.", err)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ import (
|
|||
"github.com/matrix-org/dendrite/setup/config"
|
||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||
zion "github.com/matrix-org/dendrite/zion"
|
||||
)
|
||||
|
||||
var ReleaseVersion string
|
||||
|
|
@ -77,8 +76,7 @@ func Setup(
|
|||
|
||||
rateLimits := httputil.NewRateLimits(&cfg.RateLimiting)
|
||||
userInteractiveAuth := auth.NewUserInteractive(userAPI, userAPI, cfg)
|
||||
clientAuthz := zion.ClientRoomserverStruct{ClientRoomserverAPI: rsAPI}
|
||||
authorization := clientApiAuthz.NewRoomserverAuthorization(cfg, clientAuthz)
|
||||
authorization := clientApiAuthz.NewRoomserverAuthorization(cfg, rsAPI)
|
||||
|
||||
unstableFeatures := map[string]bool{
|
||||
"org.matrix.e2e_cross_signing": true,
|
||||
|
|
|
|||
|
|
@ -52,8 +52,7 @@ func Setup(
|
|||
lazyLoadCache caching.LazyLoadCache,
|
||||
fts *fulltext.Search,
|
||||
) {
|
||||
syncAuthz := zion.SyncRoomserverStruct{SyncRoomserverAPI: rsAPI}
|
||||
authorization := clientApiAuthz.NewRoomserverAuthorization(clientCfg, syncAuthz)
|
||||
authorization := clientApiAuthz.NewRoomserverAuthorization(clientCfg, crsAPI)
|
||||
v1unstablemux := csMux.PathPrefix("/{apiversion:(?:v1|unstable)}/").Subrouter()
|
||||
v3mux := csMux.PathPrefix("/{apiversion:(?:r0|v3)}/").Subrouter()
|
||||
|
||||
|
|
|
|||
109
zion/store.go
109
zion/store.go
|
|
@ -12,19 +12,17 @@ import (
|
|||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
type ClientRoomserverStore struct {
|
||||
rsAPI roomserver.ClientRoomserverAPI
|
||||
type Store struct {
|
||||
roomQuery roomserver.QueryEventsAPI
|
||||
}
|
||||
|
||||
type SyncRoomserverStore struct {
|
||||
rsAPI roomserver.SyncRoomserverAPI
|
||||
func NewStore(roomQuery roomserver.QueryEventsAPI) Store {
|
||||
return Store{
|
||||
roomQuery: roomQuery,
|
||||
}
|
||||
}
|
||||
|
||||
type StoreAPI interface {
|
||||
GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo
|
||||
}
|
||||
|
||||
func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
|
||||
func (s *Store) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
|
||||
result := RoomInfo{
|
||||
QueryUserId: userId.MatrixUserId,
|
||||
SpaceNetworkId: "",
|
||||
|
|
@ -49,7 +47,7 @@ func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier
|
|||
}
|
||||
|
||||
var roomEvents roomserver.QueryCurrentStateResponse
|
||||
err := s.rsAPI.QueryCurrentState(context.Background(), &roomserver.QueryCurrentStateRequest{
|
||||
err := s.roomQuery.QueryCurrentState(context.Background(), &roomserver.QueryCurrentStateRequest{
|
||||
RoomID: roomId,
|
||||
AllowWildcards: true,
|
||||
StateTuples: []gomatrixserverlib.StateKeyTuple{
|
||||
|
|
@ -63,9 +61,11 @@ func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier
|
|||
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(
|
||||
|
|
@ -77,96 +77,21 @@ func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier
|
|||
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
|
||||
}
|
||||
|
||||
func (s *SyncRoomserverStore) 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.QueryLatestEventsAndStateResponse
|
||||
err := s.rsAPI.QueryLatestEventsAndState(context.Background(),
|
||||
&roomserver.QueryLatestEventsAndStateRequest{
|
||||
RoomID: roomId,
|
||||
StateToFetch: []gomatrixserverlib.StateKeyTuple{
|
||||
createTuple,
|
||||
spaceParentTuple,
|
||||
spaceChildTuple,
|
||||
},
|
||||
}, &roomEvents)
|
||||
|
||||
if err != nil {
|
||||
return result
|
||||
}
|
||||
|
||||
HydrateRoomInfoWithStateEvents(roomId, userId, &result, roomEvents.StateEvents)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func HydrateRoomInfoWithStateEvents(roomId string, userId UserIdentifier, r *RoomInfo, stateEvents []*gomatrixserverlib.HeaderedEvent) {
|
||||
for _, state := range stateEvents {
|
||||
switch state.Type() {
|
||||
case gomatrixserverlib.MRoomCreate:
|
||||
var creatorEvent CreatorEvent
|
||||
err := json.Unmarshal(state.Content(), &creatorEvent)
|
||||
r.IsOwner = strings.HasPrefix(
|
||||
creatorEvent.Creator,
|
||||
userId.LocalPart,
|
||||
)
|
||||
if err == nil {
|
||||
r.RoomType = Space
|
||||
r.SpaceNetworkId = roomId
|
||||
}
|
||||
case ConstSpaceChildEventType:
|
||||
r.RoomType = Space
|
||||
r.SpaceNetworkId = roomId
|
||||
case ConstSpaceParentEventType:
|
||||
r.RoomType = Channel
|
||||
r.SpaceNetworkId = *state.StateKey()
|
||||
r.ChannelNetworkId = roomId
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func NewClientRoomserverStore(rsAPI roomserver.ClientRoomserverAPI) StoreAPI {
|
||||
return &ClientRoomserverStore{
|
||||
rsAPI: rsAPI,
|
||||
}
|
||||
}
|
||||
|
||||
func NewSyncRoomserverStore(rsAPI roomserver.SyncRoomserverAPI) StoreAPI {
|
||||
return &SyncRoomserverStore{
|
||||
rsAPI: rsAPI,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,46 +23,22 @@ var ErrSpaceDisabled = errors.New("space disabled")
|
|||
var ErrChannelDisabled = errors.New("channel disabled")
|
||||
|
||||
type ZionAuthorization struct {
|
||||
store StoreAPI
|
||||
chainId int
|
||||
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost
|
||||
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli
|
||||
chainId int
|
||||
}
|
||||
type ClientRoomserverStruct struct {
|
||||
roomserver.ClientRoomserverAPI
|
||||
store Store
|
||||
}
|
||||
|
||||
type SyncRoomserverStruct struct {
|
||||
roomserver.SyncRoomserverAPI
|
||||
}
|
||||
|
||||
type RoomserverStoreAPI interface {
|
||||
roomserver.QueryLatestEventsAndStateAPI
|
||||
NewRoomserverStore() StoreAPI
|
||||
}
|
||||
|
||||
func (c ClientRoomserverStruct) NewRoomserverStore() StoreAPI {
|
||||
return &ClientRoomserverStore{
|
||||
rsAPI: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (c SyncRoomserverStruct) NewRoomserverStore() StoreAPI {
|
||||
return &SyncRoomserverStore{
|
||||
rsAPI: c,
|
||||
}
|
||||
}
|
||||
|
||||
func NewZionAuthorization(cfg *config.ClientAPI, rsAPI RoomserverStoreAPI) (authorization.Authorization, error) {
|
||||
func NewZionAuthorization(cfg *config.ClientAPI, roomQueryAPI roomserver.QueryEventsAPI) (authorization.Authorization, error) {
|
||||
if cfg.PublicKeyAuthentication.Ethereum.NetworkUrl == "" {
|
||||
log.Errorf("No blockchain network url specified in config\n")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var auth ZionAuthorization
|
||||
|
||||
auth.chainId = cfg.PublicKeyAuthentication.Ethereum.GetChainID()
|
||||
auth.store = rsAPI.NewRoomserverStore()
|
||||
auth := ZionAuthorization{
|
||||
store: NewStore(roomQueryAPI),
|
||||
chainId: cfg.PublicKeyAuthentication.Ethereum.GetChainID(),
|
||||
}
|
||||
|
||||
switch auth.chainId {
|
||||
case 1337, 31337:
|
||||
|
|
@ -106,7 +82,8 @@ func (za *ZionAuthorization) IsAllowed(args authorization.AuthorizationArgs) (bo
|
|||
} else if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return za.isAllowedLocalhost(roomInfo, userIdentifier.AccountAddress, args.Permission)
|
||||
isAllowed, err := za.isAllowedLocalhost(roomInfo, userIdentifier.AccountAddress, args.Permission)
|
||||
return isAllowed, err
|
||||
case 5:
|
||||
// Check if space / channel is disabled.
|
||||
disabled, err := za.isSpaceChannelDisabledGoerli(roomInfo)
|
||||
|
|
|
|||
Loading…
Reference in a new issue