mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-16 18:43:10 -06:00
Merge pull request #56 from HereNotThere/jterzis/hnt-272-gate-msg-sync
message sync gating
This commit is contained in:
commit
f2d6888452
|
|
@ -2,13 +2,13 @@ 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 NewAuthorization(cfg *config.ClientAPI, rsAPI roomserver.ClientRoomserverAPI) authorization.Authorization {
|
func NewRoomserverAuthorization(cfg *config.ClientAPI, rsAPI zion.RoomserverStoreAPI) 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, rsAPI)
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ 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
|
||||||
|
|
@ -76,7 +77,8 @@ func Setup(
|
||||||
|
|
||||||
rateLimits := httputil.NewRateLimits(&cfg.RateLimiting)
|
rateLimits := httputil.NewRateLimits(&cfg.RateLimiting)
|
||||||
userInteractiveAuth := auth.NewUserInteractive(userAPI, userAPI, cfg)
|
userInteractiveAuth := auth.NewUserInteractive(userAPI, userAPI, cfg)
|
||||||
authorization := clientApiAuthz.NewAuthorization(cfg, rsAPI)
|
clientAuthz := zion.ClientRoomserverStruct{ClientRoomserverAPI: 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,
|
||||||
|
|
@ -396,6 +398,20 @@ func Setup(
|
||||||
v3mux.Handle("/rooms/{roomID}/send/{eventType}",
|
v3mux.Handle("/rooms/{roomID}/send/{eventType}",
|
||||||
httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
|
||||||
|
isAllowed, _ := authorization.IsAllowed(authz.AuthorizationArgs{
|
||||||
|
RoomId: vars["roomID"],
|
||||||
|
UserId: device.UserID,
|
||||||
|
Permission: authz.PermissionWrite,
|
||||||
|
})
|
||||||
|
|
||||||
|
if !isAllowed {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusUnauthorized,
|
||||||
|
JSON: jsonerror.Forbidden("Unauthorised"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
@ -405,6 +421,20 @@ func Setup(
|
||||||
v3mux.Handle("/rooms/{roomID}/send/{eventType}/{txnID}",
|
v3mux.Handle("/rooms/{roomID}/send/{eventType}/{txnID}",
|
||||||
httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
httputil.MakeAuthAPI("send_message", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
|
||||||
|
isAllowed, _ := authorization.IsAllowed(authz.AuthorizationArgs{
|
||||||
|
RoomId: vars["roomID"],
|
||||||
|
UserId: device.UserID,
|
||||||
|
Permission: authz.PermissionWrite,
|
||||||
|
})
|
||||||
|
|
||||||
|
if !isAllowed {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusUnauthorized,
|
||||||
|
JSON: jsonerror.Forbidden("Unauthorised to send event"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
@ -525,7 +555,6 @@ func Setup(
|
||||||
return GetVisibility(req, rsAPI, vars["roomID"])
|
return GetVisibility(req, rsAPI, vars["roomID"])
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodGet, http.MethodOptions)
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
|
||||||
v3mux.Handle("/directory/list/room/{roomID}",
|
v3mux.Handle("/directory/list/room/{roomID}",
|
||||||
httputil.MakeAuthAPI("directory_list", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
httputil.MakeAuthAPI("directory_list", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,11 @@ import (
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/syncapi/storage"
|
"github.com/matrix-org/dendrite/syncapi/storage"
|
||||||
"github.com/matrix-org/dendrite/syncapi/sync"
|
"github.com/matrix-org/dendrite/syncapi/sync"
|
||||||
|
|
||||||
|
authz "github.com/matrix-org/dendrite/authorization"
|
||||||
|
clientApiAuthz "github.com/matrix-org/dendrite/clientapi/authorization"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
zion "github.com/matrix-org/dendrite/zion"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup configures the given mux with sync-server listeners
|
// Setup configures the given mux with sync-server listeners
|
||||||
|
|
@ -42,9 +46,12 @@ func Setup(
|
||||||
userAPI userapi.SyncUserAPI,
|
userAPI userapi.SyncUserAPI,
|
||||||
rsAPI api.SyncRoomserverAPI,
|
rsAPI api.SyncRoomserverAPI,
|
||||||
cfg *config.SyncAPI,
|
cfg *config.SyncAPI,
|
||||||
|
clientCfg *config.ClientAPI,
|
||||||
lazyLoadCache caching.LazyLoadCache,
|
lazyLoadCache caching.LazyLoadCache,
|
||||||
fts *fulltext.Search,
|
fts *fulltext.Search,
|
||||||
) {
|
) {
|
||||||
|
syncAuthz := zion.SyncRoomserverStruct{SyncRoomserverAPI: rsAPI}
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
@ -55,6 +62,19 @@ func Setup(
|
||||||
|
|
||||||
v3mux.Handle("/rooms/{roomID}/messages", httputil.MakeAuthAPI("room_messages", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
v3mux.Handle("/rooms/{roomID}/messages", httputil.MakeAuthAPI("room_messages", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
|
||||||
|
isAllowed, _ := authorization.IsAllowed(authz.AuthorizationArgs{
|
||||||
|
RoomId: vars["roomID"],
|
||||||
|
UserId: device.UserID,
|
||||||
|
Permission: authz.PermissionRead,
|
||||||
|
})
|
||||||
|
|
||||||
|
if !isAllowed {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusUnauthorized,
|
||||||
|
JSON: jsonerror.Forbidden("Unauthorised"),
|
||||||
|
}
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ func AddPublicRoutes(
|
||||||
keyAPI keyapi.SyncKeyAPI,
|
keyAPI keyapi.SyncKeyAPI,
|
||||||
) {
|
) {
|
||||||
cfg := &base.Cfg.SyncAPI
|
cfg := &base.Cfg.SyncAPI
|
||||||
|
clientCfg := &base.Cfg.ClientAPI
|
||||||
|
|
||||||
js, natsClient := base.NATS.Prepare(base.ProcessContext, &cfg.Matrix.JetStream)
|
js, natsClient := base.NATS.Prepare(base.ProcessContext, &cfg.Matrix.JetStream)
|
||||||
|
|
||||||
|
|
@ -132,6 +133,6 @@ func AddPublicRoutes(
|
||||||
|
|
||||||
routing.Setup(
|
routing.Setup(
|
||||||
base.PublicClientAPIMux, requestPool, syncDB, userAPI,
|
base.PublicClientAPIMux, requestPool, syncDB, userAPI,
|
||||||
rsAPI, cfg, base.Caches, base.Fulltext,
|
rsAPI, cfg, clientCfg, base.Caches, base.Fulltext,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,19 @@ import (
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Store struct {
|
type ClientRoomserverStore struct {
|
||||||
rsAPI roomserver.ClientRoomserverAPI
|
rsAPI roomserver.ClientRoomserverAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStore(rsAPI roomserver.ClientRoomserverAPI) Store {
|
type SyncRoomserverStore struct {
|
||||||
return Store{
|
rsAPI roomserver.SyncRoomserverAPI
|
||||||
rsAPI: rsAPI,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
|
type StoreAPI interface {
|
||||||
|
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: "",
|
||||||
|
|
@ -60,7 +62,7 @@ func (s *Store) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
//TODO: replace with HydrateRoomInfoWithStateEvents when you have a practical way to flatten roomEvents map
|
||||||
for _, state := range roomEvents.StateEvents {
|
for _, state := range roomEvents.StateEvents {
|
||||||
switch state.Type() {
|
switch state.Type() {
|
||||||
case gomatrixserverlib.MRoomCreate:
|
case gomatrixserverlib.MRoomCreate:
|
||||||
|
|
@ -86,3 +88,85 @@ func (s *Store) GetRoomInfo(roomId string, userId UserIdentifier) RoomInfo {
|
||||||
|
|
||||||
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,37 @@ var localhostJson []byte
|
||||||
var goerliJson []byte
|
var goerliJson []byte
|
||||||
|
|
||||||
type ZionAuthorization struct {
|
type ZionAuthorization struct {
|
||||||
store Store
|
store StoreAPI
|
||||||
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost
|
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost
|
||||||
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli
|
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli
|
||||||
chainId int
|
chainId int
|
||||||
}
|
}
|
||||||
|
type ClientRoomserverStruct struct {
|
||||||
|
roomserver.ClientRoomserverAPI
|
||||||
|
}
|
||||||
|
|
||||||
func NewZionAuthorization(
|
type SyncRoomserverStruct struct {
|
||||||
cfg *config.ClientAPI,
|
roomserver.SyncRoomserverAPI
|
||||||
rsAPI roomserver.ClientRoomserverAPI,
|
}
|
||||||
) (authorization.Authorization, error) {
|
|
||||||
|
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
|
||||||
|
|
@ -37,7 +58,7 @@ func NewZionAuthorization(
|
||||||
var auth ZionAuthorization
|
var auth ZionAuthorization
|
||||||
|
|
||||||
auth.chainId = cfg.PublicKeyAuthentication.Ethereum.GetChainID()
|
auth.chainId = cfg.PublicKeyAuthentication.Ethereum.GetChainID()
|
||||||
auth.store = NewStore(rsAPI)
|
auth.store = rsAPI.NewRoomserverStore()
|
||||||
|
|
||||||
switch auth.chainId {
|
switch auth.chainId {
|
||||||
case 1337, 31337:
|
case 1337, 31337:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue