mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-16 18:43:10 -06:00
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.
230 lines
6 KiB
Go
230 lines
6 KiB
Go
package zion
|
|
|
|
import (
|
|
_ "embed"
|
|
"errors"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/matrix-org/dendrite/authorization"
|
|
roomserver "github.com/matrix-org/dendrite/roomserver/api"
|
|
"github.com/matrix-org/dendrite/setup/config"
|
|
zion_goerli "github.com/matrix-org/dendrite/zion/contracts/zion_goerli"
|
|
zion_localhost "github.com/matrix-org/dendrite/zion/contracts/zion_localhost"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
//go:embed contracts/zion_localhost/space-manager.json
|
|
var localhostJson []byte
|
|
|
|
//go:embed contracts/zion_goerli/space-manager.json
|
|
var goerliJson []byte
|
|
|
|
var ErrSpaceDisabled = errors.New("space disabled")
|
|
var ErrChannelDisabled = errors.New("channel disabled")
|
|
|
|
type ZionAuthorization struct {
|
|
chainId int
|
|
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost
|
|
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli
|
|
store Store
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
auth := ZionAuthorization{
|
|
store: NewStore(roomQueryAPI),
|
|
chainId: cfg.PublicKeyAuthentication.Ethereum.GetChainID(),
|
|
}
|
|
|
|
switch auth.chainId {
|
|
case 1337, 31337:
|
|
localhost, err := newZionSpaceManagerLocalhost(cfg.PublicKeyAuthentication.Ethereum.NetworkUrl)
|
|
if err != nil {
|
|
log.Errorln("error instantiating ZionSpaceManagerLocalhost", err)
|
|
}
|
|
auth.spaceManagerLocalhost = localhost
|
|
|
|
case 5:
|
|
goerli, err := newZionSpaceManagerGoerli(cfg.PublicKeyAuthentication.Ethereum.NetworkUrl)
|
|
if err != nil {
|
|
log.Errorln("error instantiating ZionSpaceManagerGoerli", err)
|
|
}
|
|
auth.spaceManagerGoerli = goerli
|
|
|
|
default:
|
|
log.Errorf("Unsupported chain id: %d\n", auth.chainId)
|
|
}
|
|
|
|
return &auth, nil
|
|
}
|
|
|
|
func (za *ZionAuthorization) IsAllowed(args authorization.AuthorizationArgs) (bool, error) {
|
|
userIdentifier := CreateUserIdentifier(args.UserId)
|
|
|
|
// Find out if roomId is a space or a channel.
|
|
roomInfo := za.store.GetRoomInfo(args.RoomId, userIdentifier)
|
|
|
|
// Owner of the space / channel is always allowed to proceed.
|
|
if roomInfo.IsOwner {
|
|
return true, nil
|
|
}
|
|
|
|
switch za.chainId {
|
|
case 1337, 31337:
|
|
// Check if space / channel is disabled.
|
|
disabled, err := za.isSpaceChannelDisabledLocalhost(roomInfo)
|
|
if disabled {
|
|
return false, ErrSpaceDisabled
|
|
} else if err != nil {
|
|
return false, err
|
|
}
|
|
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)
|
|
if disabled {
|
|
return false, ErrChannelDisabled
|
|
} else if err != nil {
|
|
return false, err
|
|
}
|
|
return za.isAllowedGoerli(roomInfo, userIdentifier.AccountAddress, args.Permission)
|
|
default:
|
|
log.Errorf("Unsupported chain id: %d", userIdentifier.ChainId)
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
func (za *ZionAuthorization) isSpaceChannelDisabledLocalhost(roomInfo RoomInfo) (bool, error) {
|
|
if za.spaceManagerLocalhost == nil {
|
|
return false, errors.New("error fetching space manager contract")
|
|
}
|
|
switch roomInfo.ChannelNetworkId {
|
|
case "":
|
|
spInfo, err := za.spaceManagerLocalhost.GetSpaceInfoBySpaceId(nil, roomInfo.SpaceNetworkId)
|
|
return spInfo.Disabled, err
|
|
default:
|
|
chInfo, err := za.spaceManagerLocalhost.GetChannelInfoByChannelId(nil, roomInfo.SpaceNetworkId, roomInfo.ChannelNetworkId)
|
|
return chInfo.Disabled, err
|
|
}
|
|
|
|
}
|
|
|
|
func (za *ZionAuthorization) isSpaceChannelDisabledGoerli(roomInfo RoomInfo) (bool, error) {
|
|
if za.spaceManagerGoerli == nil {
|
|
return false, errors.New("error fetching space manager contract")
|
|
}
|
|
switch roomInfo.ChannelNetworkId {
|
|
case "":
|
|
spInfo, err := za.spaceManagerGoerli.GetSpaceInfoBySpaceId(nil, roomInfo.SpaceNetworkId)
|
|
return spInfo.Disabled, err
|
|
default:
|
|
chInfo, err := za.spaceManagerGoerli.GetChannelInfoByChannelId(nil, roomInfo.SpaceNetworkId, roomInfo.ChannelNetworkId)
|
|
return chInfo.Disabled, err
|
|
}
|
|
|
|
}
|
|
|
|
func (za *ZionAuthorization) isAllowedLocalhost(
|
|
roomInfo RoomInfo,
|
|
user common.Address,
|
|
permission authorization.Permission,
|
|
) (bool, error) {
|
|
if za.spaceManagerLocalhost != nil {
|
|
permission := zion_localhost.DataTypesPermission{
|
|
Name: permission.String(),
|
|
}
|
|
|
|
isEntitled, err := za.spaceManagerLocalhost.IsEntitled(
|
|
nil,
|
|
roomInfo.SpaceNetworkId,
|
|
roomInfo.ChannelNetworkId,
|
|
user,
|
|
permission,
|
|
)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return isEntitled, nil
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
func (za *ZionAuthorization) isAllowedGoerli(
|
|
roomInfo RoomInfo,
|
|
user common.Address,
|
|
permission authorization.Permission,
|
|
) (bool, error) {
|
|
if za.spaceManagerGoerli != nil {
|
|
permission := zion_goerli.DataTypesPermission{
|
|
Name: permission.String(),
|
|
}
|
|
|
|
isEntitled, err := za.spaceManagerGoerli.IsEntitled(
|
|
nil,
|
|
roomInfo.SpaceNetworkId,
|
|
roomInfo.ChannelNetworkId,
|
|
user,
|
|
permission,
|
|
)
|
|
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return isEntitled, nil
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
func newZionSpaceManagerLocalhost(endpointUrl string) (*zion_localhost.ZionSpaceManagerLocalhost, error) {
|
|
addresses, err := loadSpaceManagerAddresses(localhostJson)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
address := common.HexToAddress(addresses.Spacemanager)
|
|
|
|
client, err := GetEthClient(endpointUrl)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
spaceManager, err := zion_localhost.NewZionSpaceManagerLocalhost(address, client)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return spaceManager, nil
|
|
}
|
|
|
|
func newZionSpaceManagerGoerli(endpointUrl string) (*zion_goerli.ZionSpaceManagerGoerli, error) {
|
|
addresses, err := loadSpaceManagerAddresses(goerliJson)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
address := common.HexToAddress((addresses.Spacemanager))
|
|
|
|
client, err := GetEthClient(endpointUrl)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
spaceManager, err := zion_goerli.NewZionSpaceManagerGoerli(address, client)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return spaceManager, nil
|
|
}
|