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 (
|
import (
|
||||||
"github.com/matrix-org/dendrite/authorization"
|
"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/setup/config"
|
|
||||||
"github.com/matrix-org/dendrite/zion"
|
"github.com/matrix-org/dendrite/zion"
|
||||||
log "github.com/sirupsen/logrus"
|
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
|
// Load authorization manager for Zion
|
||||||
if cfg.PublicKeyAuthentication.Ethereum.GetEnableAuthZ() {
|
if cfg.PublicKeyAuthentication.Ethereum.GetEnableAuthZ() {
|
||||||
auth, err := zion.NewZionAuthorization(cfg, rsAPI)
|
auth, err := zion.NewZionAuthorization(cfg, roomQueryAPI)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("Failed to initialise Zion authorization manager. Using default.", err)
|
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/config"
|
||||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
zion "github.com/matrix-org/dendrite/zion"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ReleaseVersion string
|
var ReleaseVersion string
|
||||||
|
|
@ -77,8 +76,7 @@ func Setup(
|
||||||
|
|
||||||
rateLimits := httputil.NewRateLimits(&cfg.RateLimiting)
|
rateLimits := httputil.NewRateLimits(&cfg.RateLimiting)
|
||||||
userInteractiveAuth := auth.NewUserInteractive(userAPI, userAPI, cfg)
|
userInteractiveAuth := auth.NewUserInteractive(userAPI, userAPI, cfg)
|
||||||
clientAuthz := zion.ClientRoomserverStruct{ClientRoomserverAPI: rsAPI}
|
authorization := clientApiAuthz.NewRoomserverAuthorization(cfg, rsAPI)
|
||||||
authorization := clientApiAuthz.NewRoomserverAuthorization(cfg, clientAuthz)
|
|
||||||
|
|
||||||
unstableFeatures := map[string]bool{
|
unstableFeatures := map[string]bool{
|
||||||
"org.matrix.e2e_cross_signing": true,
|
"org.matrix.e2e_cross_signing": true,
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,7 @@ func Setup(
|
||||||
lazyLoadCache caching.LazyLoadCache,
|
lazyLoadCache caching.LazyLoadCache,
|
||||||
fts *fulltext.Search,
|
fts *fulltext.Search,
|
||||||
) {
|
) {
|
||||||
syncAuthz := zion.SyncRoomserverStruct{SyncRoomserverAPI: rsAPI}
|
authorization := clientApiAuthz.NewRoomserverAuthorization(clientCfg, crsAPI)
|
||||||
authorization := clientApiAuthz.NewRoomserverAuthorization(clientCfg, syncAuthz)
|
|
||||||
v1unstablemux := csMux.PathPrefix("/{apiversion:(?:v1|unstable)}/").Subrouter()
|
v1unstablemux := csMux.PathPrefix("/{apiversion:(?:v1|unstable)}/").Subrouter()
|
||||||
v3mux := csMux.PathPrefix("/{apiversion:(?:r0|v3)}/").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"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClientRoomserverStore struct {
|
type Store struct {
|
||||||
rsAPI roomserver.ClientRoomserverAPI
|
roomQuery roomserver.QueryEventsAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
type SyncRoomserverStore struct {
|
func NewStore(roomQuery roomserver.QueryEventsAPI) Store {
|
||||||
rsAPI roomserver.SyncRoomserverAPI
|
return Store{
|
||||||
|
roomQuery: roomQuery,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type StoreAPI interface {
|
func (s *Store) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
|
||||||
GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
|
|
||||||
result := RoomInfo{
|
result := RoomInfo{
|
||||||
QueryUserId: userId.MatrixUserId,
|
QueryUserId: userId.MatrixUserId,
|
||||||
SpaceNetworkId: "",
|
SpaceNetworkId: "",
|
||||||
|
|
@ -49,7 +47,7 @@ func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier
|
||||||
}
|
}
|
||||||
|
|
||||||
var roomEvents roomserver.QueryCurrentStateResponse
|
var roomEvents roomserver.QueryCurrentStateResponse
|
||||||
err := s.rsAPI.QueryCurrentState(context.Background(), &roomserver.QueryCurrentStateRequest{
|
err := s.roomQuery.QueryCurrentState(context.Background(), &roomserver.QueryCurrentStateRequest{
|
||||||
RoomID: roomId,
|
RoomID: roomId,
|
||||||
AllowWildcards: true,
|
AllowWildcards: true,
|
||||||
StateTuples: []gomatrixserverlib.StateKeyTuple{
|
StateTuples: []gomatrixserverlib.StateKeyTuple{
|
||||||
|
|
@ -63,9 +61,11 @@ func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
//TODO: replace with HydrateRoomInfoWithStateEvents when you have a practical way to flatten roomEvents map
|
//TODO: replace with HydrateRoomInfoWithStateEvents when you have a practical way to flatten roomEvents map
|
||||||
|
doneSearching := false
|
||||||
for _, state := range roomEvents.StateEvents {
|
for _, state := range roomEvents.StateEvents {
|
||||||
switch state.Type() {
|
switch state.Type() {
|
||||||
case gomatrixserverlib.MRoomCreate:
|
case gomatrixserverlib.MRoomCreate:
|
||||||
|
// Space is created with no children yet.
|
||||||
var creatorEvent CreatorEvent
|
var creatorEvent CreatorEvent
|
||||||
err := json.Unmarshal(roomEvents.StateEvents[createTuple].Content(), &creatorEvent)
|
err := json.Unmarshal(roomEvents.StateEvents[createTuple].Content(), &creatorEvent)
|
||||||
result.IsOwner = strings.HasPrefix(
|
result.IsOwner = strings.HasPrefix(
|
||||||
|
|
@ -77,96 +77,21 @@ func (s *ClientRoomserverStore) GetRoomInfo(roomId string, userId UserIdentifier
|
||||||
result.SpaceNetworkId = roomId
|
result.SpaceNetworkId = roomId
|
||||||
}
|
}
|
||||||
case ConstSpaceChildEventType:
|
case ConstSpaceChildEventType:
|
||||||
|
// Space is created and has one or more children.
|
||||||
result.RoomType = Space
|
result.RoomType = Space
|
||||||
result.SpaceNetworkId = roomId
|
result.SpaceNetworkId = roomId
|
||||||
|
doneSearching = true
|
||||||
case ConstSpaceParentEventType:
|
case ConstSpaceParentEventType:
|
||||||
|
// Channel is created and has a reference to the parent.
|
||||||
result.RoomType = Channel
|
result.RoomType = Channel
|
||||||
result.SpaceNetworkId = *state.StateKey()
|
result.SpaceNetworkId = *state.StateKey()
|
||||||
result.ChannelNetworkId = roomId
|
result.ChannelNetworkId = roomId
|
||||||
|
doneSearching = true
|
||||||
|
}
|
||||||
|
if doneSearching {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
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")
|
var ErrChannelDisabled = errors.New("channel disabled")
|
||||||
|
|
||||||
type ZionAuthorization struct {
|
type ZionAuthorization struct {
|
||||||
store StoreAPI
|
chainId int
|
||||||
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost
|
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost
|
||||||
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli
|
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli
|
||||||
chainId int
|
store Store
|
||||||
}
|
|
||||||
type ClientRoomserverStruct struct {
|
|
||||||
roomserver.ClientRoomserverAPI
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type SyncRoomserverStruct struct {
|
func NewZionAuthorization(cfg *config.ClientAPI, roomQueryAPI roomserver.QueryEventsAPI) (authorization.Authorization, error) {
|
||||||
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) {
|
|
||||||
if cfg.PublicKeyAuthentication.Ethereum.NetworkUrl == "" {
|
if cfg.PublicKeyAuthentication.Ethereum.NetworkUrl == "" {
|
||||||
log.Errorf("No blockchain network url specified in config\n")
|
log.Errorf("No blockchain network url specified in config\n")
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var auth ZionAuthorization
|
auth := ZionAuthorization{
|
||||||
|
store: NewStore(roomQueryAPI),
|
||||||
auth.chainId = cfg.PublicKeyAuthentication.Ethereum.GetChainID()
|
chainId: cfg.PublicKeyAuthentication.Ethereum.GetChainID(),
|
||||||
auth.store = rsAPI.NewRoomserverStore()
|
}
|
||||||
|
|
||||||
switch auth.chainId {
|
switch auth.chainId {
|
||||||
case 1337, 31337:
|
case 1337, 31337:
|
||||||
|
|
@ -106,7 +82,8 @@ func (za *ZionAuthorization) IsAllowed(args authorization.AuthorizationArgs) (bo
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return false, err
|
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:
|
case 5:
|
||||||
// Check if space / channel is disabled.
|
// Check if space / channel is disabled.
|
||||||
disabled, err := za.isSpaceChannelDisabledGoerli(roomInfo)
|
disabled, err := za.isSpaceChannelDisabledGoerli(roomInfo)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue