mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-17 03:43:11 -06:00
Merge branch 'master' into kegan/backfill-again
This commit is contained in:
commit
1d0da512cc
|
|
@ -106,12 +106,15 @@ func (c *RoomserverProducer) SendInputRoomEvents(
|
|||
func (c *RoomserverProducer) SendInvite(
|
||||
ctx context.Context, inviteEvent gomatrixserverlib.HeaderedEvent,
|
||||
inviteRoomState []gomatrixserverlib.InviteV2StrippedState,
|
||||
sendAsServer gomatrixserverlib.ServerName, txnID *api.TransactionID,
|
||||
) error {
|
||||
request := api.InputRoomEventsRequest{
|
||||
InputInviteEvents: []api.InputInviteEvent{{
|
||||
Event: inviteEvent,
|
||||
InviteRoomState: inviteRoomState,
|
||||
RoomVersion: inviteEvent.RoomVersion,
|
||||
SendAsServer: string(sendAsServer),
|
||||
TransactionID: txnID,
|
||||
}},
|
||||
}
|
||||
var response api.InputRoomEventsResponse
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ var errMissingUserID = errors.New("'user_id' must be supplied")
|
|||
|
||||
// SendMembership implements PUT /rooms/{roomID}/(join|kick|ban|unban|leave|invite)
|
||||
// by building a m.room.member event then sending it to the room server
|
||||
// TODO: Can we improve the cyclo count here? Separate code paths for invites?
|
||||
// nolint:gocyclo
|
||||
func SendMembership(
|
||||
req *http.Request, accountDB accounts.Database, device *authtypes.Device,
|
||||
roomID string, membership string, cfg *config.Dendrite,
|
||||
|
|
@ -104,23 +106,39 @@ func SendMembership(
|
|||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
if _, err := producer.SendEvents(
|
||||
req.Context(),
|
||||
[]gomatrixserverlib.HeaderedEvent{(*event).Headered(verRes.RoomVersion)},
|
||||
cfg.Matrix.ServerName,
|
||||
nil,
|
||||
); err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("producer.SendEvents failed")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
|
||||
var returnData interface{} = struct{}{}
|
||||
|
||||
switch membership {
|
||||
case gomatrixserverlib.Invite:
|
||||
// Invites need to be handled specially
|
||||
err = producer.SendInvite(
|
||||
req.Context(),
|
||||
event.Headered(verRes.RoomVersion),
|
||||
nil, // ask the roomserver to draw up invite room state for us
|
||||
cfg.Matrix.ServerName,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("producer.SendInvite failed")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
case gomatrixserverlib.Join:
|
||||
// The join membership requires the room id to be sent in the response
|
||||
if membership == gomatrixserverlib.Join {
|
||||
returnData = struct {
|
||||
RoomID string `json:"room_id"`
|
||||
}{roomID}
|
||||
fallthrough
|
||||
default:
|
||||
_, err = producer.SendEvents(
|
||||
req.Context(),
|
||||
[]gomatrixserverlib.HeaderedEvent{event.Headered(verRes.RoomVersion)},
|
||||
cfg.Matrix.ServerName,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("producer.SendEvents failed")
|
||||
return jsonerror.InternalServerError()
|
||||
}
|
||||
}
|
||||
|
||||
return util.JSONResponse{
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func main() {
|
|||
asQuery := appservice.SetupAppServiceAPIComponent(
|
||||
&base.Base, accountDB, deviceDB, federation, alias, query, transactions.New(),
|
||||
)
|
||||
fedSenderAPI := federationsender.SetupFederationSenderComponent(&base.Base, federation, query)
|
||||
fedSenderAPI := federationsender.SetupFederationSenderComponent(&base.Base, federation, query, input)
|
||||
|
||||
clientapi.SetupClientAPIComponent(
|
||||
&base.Base, deviceDB, accountDB,
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ func main() {
|
|||
|
||||
federation := base.CreateFederationClient()
|
||||
|
||||
_, _, query := base.CreateHTTPRoomserverAPIs()
|
||||
_, input, query := base.CreateHTTPRoomserverAPIs()
|
||||
|
||||
federationsender.SetupFederationSenderComponent(
|
||||
base, federation, query,
|
||||
base, federation, query, input,
|
||||
)
|
||||
|
||||
base.SetupAndServeHTTP(string(base.Cfg.Bind.FederationSender), string(base.Cfg.Listen.FederationSender))
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ func main() {
|
|||
asQuery := appservice.SetupAppServiceAPIComponent(
|
||||
base, accountDB, deviceDB, federation, alias, query, transactions.New(),
|
||||
)
|
||||
fedSenderAPI := federationsender.SetupFederationSenderComponent(base, federation, query)
|
||||
fedSenderAPI := federationsender.SetupFederationSenderComponent(base, federation, query, input)
|
||||
|
||||
clientapi.SetupClientAPIComponent(
|
||||
base, deviceDB, accountDB,
|
||||
|
|
|
|||
|
|
@ -98,7 +98,10 @@ func Backfill(
|
|||
}
|
||||
|
||||
var eventJSONs []json.RawMessage
|
||||
for _, e := range gomatrixserverlib.ReverseTopologicalOrdering(evs, gomatrixserverlib.TopologicalOrderByPrevEvents) {
|
||||
for _, e := range gomatrixserverlib.ReverseTopologicalOrdering(
|
||||
evs,
|
||||
gomatrixserverlib.TopologicalOrderByPrevEvents,
|
||||
) {
|
||||
eventJSONs = append(eventJSONs, e.JSON())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,13 @@ package routing
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||
"github.com/matrix-org/dendrite/clientapi/producers"
|
||||
"github.com/matrix-org/dendrite/common/config"
|
||||
roomserverVersion "github.com/matrix-org/dendrite/roomserver/version"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
|
@ -44,6 +46,16 @@ func Invite(
|
|||
}
|
||||
event := inviteReq.Event()
|
||||
|
||||
// Check that we can accept invites for this room version.
|
||||
if _, err := roomserverVersion.SupportedRoomVersion(inviteReq.RoomVersion()); err != nil {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: jsonerror.UnsupportedRoomVersion(
|
||||
fmt.Sprintf("Room version %q is not supported by this server.", inviteReq.RoomVersion()),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the room ID is correct.
|
||||
if event.RoomID() != roomID {
|
||||
return util.JSONResponse{
|
||||
|
|
@ -90,6 +102,8 @@ func Invite(
|
|||
httpReq.Context(),
|
||||
signedEvent.Headered(inviteReq.RoomVersion()),
|
||||
inviteReq.InviteRoomState(),
|
||||
event.Origin(),
|
||||
nil,
|
||||
); err != nil {
|
||||
util.GetLogger(httpReq.Context()).WithError(err).Error("producer.SendInvite failed")
|
||||
return jsonerror.InternalServerError()
|
||||
|
|
@ -99,6 +113,6 @@ func Invite(
|
|||
// the other servers in the room that we have been invited.
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusOK,
|
||||
JSON: gomatrixserverlib.RespInvite{Event: signedEvent},
|
||||
JSON: gomatrixserverlib.RespInviteV2{Event: signedEvent},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// OutputRoomEventConsumer consumes events that originated in the room server.
|
||||
|
|
@ -187,49 +188,12 @@ func (s *OutputRoomEventConsumer) processInvite(oie api.OutputNewInviteEvent) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// When sending a v2 invite, the inviting server should try and include
|
||||
// a "stripped down" version of the room state. This is pretty much just
|
||||
// enough information for the remote side to show something useful to the
|
||||
// user, like the room name, aliases etc.
|
||||
// Try to extract the room invite state. The roomserver will have stashed
|
||||
// this for us in invite_room_state if it didn't already exist.
|
||||
strippedState := []gomatrixserverlib.InviteV2StrippedState{}
|
||||
stateWanted := []string{
|
||||
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
|
||||
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
|
||||
}
|
||||
|
||||
// For each of the state keys that we want to try and send, ask the
|
||||
// roomserver if we have a state event for that room that matches the
|
||||
// state key.
|
||||
for _, wanted := range stateWanted {
|
||||
queryReq := api.QueryLatestEventsAndStateRequest{
|
||||
RoomID: oie.Event.RoomID(),
|
||||
StateToFetch: []gomatrixserverlib.StateKeyTuple{
|
||||
gomatrixserverlib.StateKeyTuple{
|
||||
EventType: wanted,
|
||||
StateKey: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
// If this fails then we just move onto the next event - we don't
|
||||
// actually know at this point whether the room even has that type
|
||||
// of state.
|
||||
queryRes := api.QueryLatestEventsAndStateResponse{}
|
||||
if err := s.query.QueryLatestEventsAndState(context.TODO(), &queryReq, &queryRes); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"room_id": queryReq.RoomID,
|
||||
"event_type": wanted,
|
||||
}).WithError(err).Info("couldn't find state to strip")
|
||||
continue
|
||||
}
|
||||
// Append the stripped down copy of the state to our list.
|
||||
for _, headeredEvent := range queryRes.StateEvents {
|
||||
event := headeredEvent.Unwrap()
|
||||
strippedState = append(strippedState, gomatrixserverlib.NewInviteV2StrippedState(&event))
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"room_id": queryReq.RoomID,
|
||||
"event_type": event.Type(),
|
||||
}).Info("adding stripped state")
|
||||
if inviteRoomState := gjson.GetBytes(oie.Event.Unsigned(), "invite_room_state"); inviteRoomState.Exists() {
|
||||
if err := json.Unmarshal([]byte(inviteRoomState.Raw), &strippedState); err != nil {
|
||||
log.WithError(err).Warn("failed to extract invite_room_state from event unsigned")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/common/basecomponent"
|
||||
"github.com/matrix-org/dendrite/federationsender/api"
|
||||
"github.com/matrix-org/dendrite/federationsender/consumers"
|
||||
"github.com/matrix-org/dendrite/federationsender/producers"
|
||||
"github.com/matrix-org/dendrite/federationsender/query"
|
||||
"github.com/matrix-org/dendrite/federationsender/queue"
|
||||
"github.com/matrix-org/dendrite/federationsender/storage"
|
||||
|
|
@ -34,13 +35,16 @@ func SetupFederationSenderComponent(
|
|||
base *basecomponent.BaseDendrite,
|
||||
federation *gomatrixserverlib.FederationClient,
|
||||
rsQueryAPI roomserverAPI.RoomserverQueryAPI,
|
||||
rsInputAPI roomserverAPI.RoomserverInputAPI,
|
||||
) api.FederationSenderQueryAPI {
|
||||
federationSenderDB, err := storage.NewDatabase(string(base.Cfg.Database.FederationSender))
|
||||
if err != nil {
|
||||
logrus.WithError(err).Panic("failed to connect to federation sender db")
|
||||
}
|
||||
|
||||
queues := queue.NewOutgoingQueues(base.Cfg.Matrix.ServerName, federation)
|
||||
roomserverProducer := producers.NewRoomserverProducer(rsInputAPI, base.Cfg.Matrix.ServerName)
|
||||
|
||||
queues := queue.NewOutgoingQueues(base.Cfg.Matrix.ServerName, federation, roomserverProducer)
|
||||
|
||||
rsConsumer := consumers.NewOutputRoomEventConsumer(
|
||||
base.Cfg, base.KafkaConsumer, queues,
|
||||
|
|
|
|||
66
federationsender/producers/roomserver.go
Normal file
66
federationsender/producers/roomserver.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package producers
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
)
|
||||
|
||||
// RoomserverProducer produces events for the roomserver to consume.
|
||||
type RoomserverProducer struct {
|
||||
InputAPI api.RoomserverInputAPI
|
||||
serverName gomatrixserverlib.ServerName
|
||||
}
|
||||
|
||||
// NewRoomserverProducer creates a new RoomserverProducer
|
||||
func NewRoomserverProducer(
|
||||
inputAPI api.RoomserverInputAPI, serverName gomatrixserverlib.ServerName,
|
||||
) *RoomserverProducer {
|
||||
return &RoomserverProducer{
|
||||
InputAPI: inputAPI,
|
||||
serverName: serverName,
|
||||
}
|
||||
}
|
||||
|
||||
// SendInviteResponse drops an invite response back into the roomserver so that users
|
||||
// already in the room will be notified of the new invite. The invite response is signed
|
||||
// by the remote side.
|
||||
func (c *RoomserverProducer) SendInviteResponse(
|
||||
ctx context.Context, res gomatrixserverlib.RespInviteV2, roomVersion gomatrixserverlib.RoomVersion,
|
||||
) (string, error) {
|
||||
ev := res.Event.Headered(roomVersion)
|
||||
ire := api.InputRoomEvent{
|
||||
Kind: api.KindNew,
|
||||
Event: ev,
|
||||
AuthEventIDs: ev.AuthEventIDs(),
|
||||
SendAsServer: string(c.serverName),
|
||||
TransactionID: nil,
|
||||
}
|
||||
return c.SendInputRoomEvents(ctx, []api.InputRoomEvent{ire})
|
||||
}
|
||||
|
||||
// SendInputRoomEvents writes the given input room events to the roomserver input API.
|
||||
func (c *RoomserverProducer) SendInputRoomEvents(
|
||||
ctx context.Context, ires []api.InputRoomEvent,
|
||||
) (eventID string, err error) {
|
||||
request := api.InputRoomEventsRequest{InputRoomEvents: ires}
|
||||
var response api.InputRoomEventsResponse
|
||||
err = c.InputAPI.InputRoomEvents(ctx, &request, &response)
|
||||
eventID = response.EventID
|
||||
return
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationsender/producers"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
|
@ -32,6 +33,7 @@ import (
|
|||
// ensures that only one request is in flight to a given destination
|
||||
// at a time.
|
||||
type destinationQueue struct {
|
||||
rsProducer *producers.RoomserverProducer
|
||||
client *gomatrixserverlib.FederationClient
|
||||
origin gomatrixserverlib.ServerName
|
||||
destination gomatrixserverlib.ServerName
|
||||
|
|
@ -165,18 +167,38 @@ func (oq *destinationQueue) nextInvites() bool {
|
|||
}
|
||||
|
||||
for _, inviteReq := range oq.pendingInvites {
|
||||
ev := inviteReq.Event()
|
||||
ev, roomVersion := inviteReq.Event(), inviteReq.RoomVersion()
|
||||
|
||||
if _, err := oq.client.SendInviteV2(
|
||||
log.WithFields(log.Fields{
|
||||
"event_id": ev.EventID(),
|
||||
"room_version": roomVersion,
|
||||
"destination": oq.destination,
|
||||
}).Info("sending invite")
|
||||
|
||||
inviteRes, err := oq.client.SendInviteV2(
|
||||
context.TODO(),
|
||||
oq.destination,
|
||||
*inviteReq,
|
||||
); err != nil {
|
||||
)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"event_id": ev.EventID(),
|
||||
"state_key": ev.StateKey(),
|
||||
"destination": oq.destination,
|
||||
}).WithError(err).Error("failed to send invite")
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err = oq.rsProducer.SendInviteResponse(
|
||||
context.TODO(),
|
||||
inviteRes,
|
||||
roomVersion,
|
||||
); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"event_id": ev.EventID(),
|
||||
"state_key": ev.StateKey(),
|
||||
"destination": oq.destination,
|
||||
}).WithError(err).Error("failed to return signed invite to roomserver")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/matrix-org/dendrite/federationsender/producers"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
|
@ -25,6 +26,7 @@ import (
|
|||
// OutgoingQueues is a collection of queues for sending transactions to other
|
||||
// matrix servers
|
||||
type OutgoingQueues struct {
|
||||
rsProducer *producers.RoomserverProducer
|
||||
origin gomatrixserverlib.ServerName
|
||||
client *gomatrixserverlib.FederationClient
|
||||
// The queuesMutex protects queues
|
||||
|
|
@ -33,8 +35,13 @@ type OutgoingQueues struct {
|
|||
}
|
||||
|
||||
// NewOutgoingQueues makes a new OutgoingQueues
|
||||
func NewOutgoingQueues(origin gomatrixserverlib.ServerName, client *gomatrixserverlib.FederationClient) *OutgoingQueues {
|
||||
func NewOutgoingQueues(
|
||||
origin gomatrixserverlib.ServerName,
|
||||
client *gomatrixserverlib.FederationClient,
|
||||
rsProducer *producers.RoomserverProducer,
|
||||
) *OutgoingQueues {
|
||||
return &OutgoingQueues{
|
||||
rsProducer: rsProducer,
|
||||
origin: origin,
|
||||
client: client,
|
||||
queues: map[gomatrixserverlib.ServerName]*destinationQueue{},
|
||||
|
|
@ -67,6 +74,7 @@ func (oqs *OutgoingQueues) SendEvent(
|
|||
oq := oqs.queues[destination]
|
||||
if oq == nil {
|
||||
oq = &destinationQueue{
|
||||
rsProducer: oqs.rsProducer,
|
||||
origin: oqs.origin,
|
||||
destination: destination,
|
||||
client: oqs.client,
|
||||
|
|
@ -111,6 +119,7 @@ func (oqs *OutgoingQueues) SendInvite(
|
|||
oq := oqs.queues[destination]
|
||||
if oq == nil {
|
||||
oq = &destinationQueue{
|
||||
rsProducer: oqs.rsProducer,
|
||||
origin: oqs.origin,
|
||||
destination: destination,
|
||||
client: oqs.client,
|
||||
|
|
@ -151,6 +160,7 @@ func (oqs *OutgoingQueues) SendEDU(
|
|||
oq := oqs.queues[destination]
|
||||
if oq == nil {
|
||||
oq = &destinationQueue{
|
||||
rsProducer: oqs.rsProducer,
|
||||
origin: oqs.origin,
|
||||
destination: destination,
|
||||
client: oqs.client,
|
||||
|
|
|
|||
3
go.mod
3
go.mod
|
|
@ -17,7 +17,7 @@ require (
|
|||
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200318135427-31631a9ef51f
|
||||
github.com/matrix-org/go-sqlite3-js v0.0.0-20200325174927-327088cdef10
|
||||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200427152419-6a0535cc473a
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200428095012-a95e289995b1
|
||||
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f
|
||||
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
|
||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible
|
||||
|
|
@ -28,6 +28,7 @@ require (
|
|||
github.com/prometheus/client_golang v1.4.1
|
||||
github.com/prometheus/common v0.9.1
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/tidwall/gjson v1.6.0
|
||||
github.com/uber/jaeger-client-go v2.15.0+incompatible
|
||||
github.com/uber/jaeger-lib v1.5.0
|
||||
go.uber.org/atomic v1.4.0
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -377,6 +377,8 @@ github.com/matrix-org/gomatrixserverlib v0.0.0-20200427134702-21db6d1430e3 h1:aJ
|
|||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200427134702-21db6d1430e3/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200427152419-6a0535cc473a h1:tlXCVU3eab9kksGYBRA3oyrmIRwD/aPujo5KJCdlCVQ=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200427152419-6a0535cc473a/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200428095012-a95e289995b1 h1:TB4V69eOtvmHdFp0+BgLNrDCcCwq6QDUOTjmi8fjC/M=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200428095012-a95e289995b1/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
|
||||
github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1 h1:osLoFdOy+ChQqVUn2PeTDETFftVkl4w9t/OW18g3lnk=
|
||||
github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1/go.mod h1:cXoYQIENbdWIQHt1SyCo6Bl3C3raHwJ0wgVrXHSqf+A=
|
||||
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y=
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ type InputInviteEvent struct {
|
|||
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
||||
Event gomatrixserverlib.HeaderedEvent `json:"event"`
|
||||
InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"`
|
||||
SendAsServer string `json:"send_as_server"`
|
||||
TransactionID *TransactionID `json:"transaction_id"`
|
||||
}
|
||||
|
||||
// InputRoomEventsRequest is a request to InputRoomEvents
|
||||
|
|
|
|||
|
|
@ -194,9 +194,24 @@ func processInviteEvent(
|
|||
|
||||
event := input.Event.Unwrap()
|
||||
|
||||
if len(input.InviteRoomState) > 0 {
|
||||
// If we were supplied with some invite room state already (which is
|
||||
// most likely to be if the event came in over federation) then use
|
||||
// that.
|
||||
if err = event.SetUnsignedField("invite_room_state", input.InviteRoomState); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// There's no invite room state, so let's have a go at building it
|
||||
// up from local data (which is most likely to be if the event came
|
||||
// from the CS API). If we know about the room then we can insert
|
||||
// the invite room state, if we don't then we just fail quietly.
|
||||
if irs, ierr := buildInviteStrippedState(ctx, db, input); ierr == nil {
|
||||
if err = event.SetUnsignedField("invite_room_state", irs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outputUpdates, err := updateToInviteMembership(updater, &event, nil, input.Event.RoomVersion)
|
||||
if err != nil {
|
||||
|
|
@ -210,3 +225,50 @@ func processInviteEvent(
|
|||
succeeded = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildInviteStrippedState(
|
||||
ctx context.Context,
|
||||
db storage.Database,
|
||||
input api.InputInviteEvent,
|
||||
) ([]gomatrixserverlib.InviteV2StrippedState, error) {
|
||||
roomNID, err := db.RoomNID(ctx, input.Event.RoomID())
|
||||
if err != nil || roomNID == 0 {
|
||||
return nil, fmt.Errorf("room %q unknown", input.Event.RoomID())
|
||||
}
|
||||
stateWanted := []gomatrixserverlib.StateKeyTuple{}
|
||||
for _, t := range []string{
|
||||
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
|
||||
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
|
||||
} {
|
||||
stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{
|
||||
EventType: t,
|
||||
StateKey: "",
|
||||
})
|
||||
}
|
||||
_, currentStateSnapshotNID, _, err := db.LatestEventIDs(ctx, roomNID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roomState := state.NewStateResolution(db)
|
||||
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
|
||||
ctx, currentStateSnapshotNID, stateWanted,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stateNIDs := []types.EventNID{}
|
||||
for _, stateNID := range stateEntries {
|
||||
stateNIDs = append(stateNIDs, stateNID.EventNID)
|
||||
}
|
||||
stateEvents, err := db.Events(ctx, stateNIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inviteState := []gomatrixserverlib.InviteV2StrippedState{
|
||||
gomatrixserverlib.NewInviteV2StrippedState(&input.Event.Event),
|
||||
}
|
||||
for _, event := range stateEvents {
|
||||
inviteState = append(inviteState, gomatrixserverlib.NewInviteV2StrippedState(&event.Event))
|
||||
}
|
||||
return inviteState, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ func updateToInviteMembership(
|
|||
// consider a single stream of events when determining whether a user
|
||||
// is invited, rather than having to combine multiple streams themselves.
|
||||
onie := api.OutputNewInviteEvent{
|
||||
Event: (*add).Headered(roomVersion),
|
||||
Event: add.Headered(roomVersion),
|
||||
RoomVersion: roomVersion,
|
||||
}
|
||||
updates = append(updates, api.OutputEvent{
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ func (r *RoomserverQueryAPI) QueryLatestEventsAndState(
|
|||
roomState := state.NewStateResolution(r.DB)
|
||||
|
||||
response.QueryLatestEventsAndStateRequest = *request
|
||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -119,7 +119,7 @@ func (r *RoomserverQueryAPI) QueryStateAfterEvents(
|
|||
roomState := state.NewStateResolution(r.DB)
|
||||
|
||||
response.QueryStateAfterEventsRequest = *request
|
||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -710,7 +710,7 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
|||
response *api.QueryStateAndAuthChainResponse,
|
||||
) error {
|
||||
response.QueryStateAndAuthChainRequest = *request
|
||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||
roomNID, err := r.DB.RoomNIDExcludingStubs(ctx, request.RoomID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,10 @@ type Database interface {
|
|||
GetLatestEventsForUpdate(ctx context.Context, roomNID types.RoomNID) (types.RoomRecentEventsUpdater, error)
|
||||
GetTransactionEventID(ctx context.Context, transactionID string, sessionID int64, userID string) (string, error)
|
||||
RoomNID(ctx context.Context, roomID string) (types.RoomNID, error)
|
||||
// RoomNIDExcludingStubs is a special variation of RoomNID that will return 0 as if the room
|
||||
// does not exist if the room has no latest events. This can happen when we've received an
|
||||
// invite over federation for a room that we don't know anything else about yet.
|
||||
RoomNIDExcludingStubs(ctx context.Context, roomID string) (types.RoomNID, error)
|
||||
LatestEventIDs(ctx context.Context, roomNID types.RoomNID) ([]gomatrixserverlib.EventReference, types.StateSnapshotNID, int64, error)
|
||||
GetInvitesForUser(ctx context.Context, roomNID types.RoomNID, targetUserNID types.EventStateKeyNID) (senderUserIDs []types.EventStateKeyNID, err error)
|
||||
SetRoomAlias(ctx context.Context, alias string, roomID string, creatorUserID string) error
|
||||
|
|
|
|||
|
|
@ -471,6 +471,23 @@ func (d *Database) RoomNID(ctx context.Context, roomID string) (types.RoomNID, e
|
|||
return roomNID, err
|
||||
}
|
||||
|
||||
// RoomNIDExcludingStubs implements query.RoomserverQueryAPIDB
|
||||
func (d *Database) RoomNIDExcludingStubs(ctx context.Context, roomID string) (roomNID types.RoomNID, err error) {
|
||||
roomNID, err = d.RoomNID(ctx, roomID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
latestEvents, _, err := d.statements.selectLatestEventNIDs(ctx, roomNID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(latestEvents) == 0 {
|
||||
roomNID = 0
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// LatestEventIDs implements query.RoomserverQueryAPIDatabase
|
||||
func (d *Database) LatestEventIDs(
|
||||
ctx context.Context, roomNID types.RoomNID,
|
||||
|
|
|
|||
|
|
@ -590,6 +590,23 @@ func (d *Database) RoomNID(ctx context.Context, roomID string) (roomNID types.Ro
|
|||
return
|
||||
}
|
||||
|
||||
// RoomNIDExcludingStubs implements query.RoomserverQueryAPIDB
|
||||
func (d *Database) RoomNIDExcludingStubs(ctx context.Context, roomID string) (roomNID types.RoomNID, err error) {
|
||||
roomNID, err = d.RoomNID(ctx, roomID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
latestEvents, _, err := d.statements.selectLatestEventNIDs(ctx, nil, roomNID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(latestEvents) == 0 {
|
||||
roomNID = 0
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// LatestEventIDs implements query.RoomserverQueryAPIDatabase
|
||||
func (d *Database) LatestEventIDs(
|
||||
ctx context.Context, roomNID types.RoomNID,
|
||||
|
|
|
|||
|
|
@ -210,7 +210,10 @@ func (r *messagesReq) retrieveEvents() (
|
|||
}
|
||||
|
||||
// Sort the events to ensure we send them in the right order.
|
||||
events = gomatrixserverlib.HeaderedReverseTopologicalOrdering(events, gomatrixserverlib.TopologicalOrderByPrevEvents)
|
||||
events = gomatrixserverlib.HeaderedReverseTopologicalOrdering(
|
||||
events,
|
||||
gomatrixserverlib.TopologicalOrderByPrevEvents,
|
||||
)
|
||||
if r.backwardOrdering {
|
||||
// This reverses the array from old->new to new->old
|
||||
sort.SliceStable(events, func(i, j int) bool {
|
||||
|
|
|
|||
|
|
@ -752,11 +752,7 @@ func (d *SyncServerDatasource) addInvitesToResponse(
|
|||
return err
|
||||
}
|
||||
for roomID, inviteEvent := range invites {
|
||||
ir := types.NewInviteResponse()
|
||||
ir.InviteState.Events = gomatrixserverlib.ToClientEvents(
|
||||
[]gomatrixserverlib.Event{inviteEvent.Event}, gomatrixserverlib.FormatSync,
|
||||
)
|
||||
// TODO: add the invite state from the invite event.
|
||||
ir := types.NewInviteResponse(inviteEvent)
|
||||
res.Rooms.Invite[roomID] = *ir
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -799,11 +799,7 @@ func (d *SyncServerDatasource) addInvitesToResponse(
|
|||
return err
|
||||
}
|
||||
for roomID, inviteEvent := range invites {
|
||||
ir := types.NewInviteResponse()
|
||||
ir.InviteState.Events = gomatrixserverlib.HeaderedToClientEvents(
|
||||
[]gomatrixserverlib.HeaderedEvent{inviteEvent}, gomatrixserverlib.FormatSync,
|
||||
)
|
||||
// TODO: add the invite state from the invite event.
|
||||
ir := types.NewInviteResponse(inviteEvent)
|
||||
res.Rooms.Invite[roomID] = *ir
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -247,14 +248,17 @@ func NewJoinResponse() *JoinResponse {
|
|||
// InviteResponse represents a /sync response for a room which is under the 'invite' key.
|
||||
type InviteResponse struct {
|
||||
InviteState struct {
|
||||
Events []gomatrixserverlib.ClientEvent `json:"events"`
|
||||
Events json.RawMessage `json:"events"`
|
||||
} `json:"invite_state"`
|
||||
}
|
||||
|
||||
// NewInviteResponse creates an empty response with initialised arrays.
|
||||
func NewInviteResponse() *InviteResponse {
|
||||
func NewInviteResponse(event gomatrixserverlib.HeaderedEvent) *InviteResponse {
|
||||
res := InviteResponse{}
|
||||
res.InviteState.Events = make([]gomatrixserverlib.ClientEvent, 0)
|
||||
res.InviteState.Events = json.RawMessage{'[', ']'}
|
||||
if inviteRoomState := gjson.GetBytes(event.Unsigned(), "invite_room_state"); inviteRoomState.Exists() {
|
||||
res.InviteState.Events = json.RawMessage(inviteRoomState.Raw)
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -253,3 +253,8 @@ User can invite local user to room with version 3
|
|||
User can invite local user to room with version 4
|
||||
A pair of servers can establish a join in a v2 room
|
||||
Can logout all devices
|
||||
State from remote users is included in the timeline in an incremental sync
|
||||
User can invite remote user to room with version 1
|
||||
User can invite remote user to room with version 2
|
||||
User can invite remote user to room with version 3
|
||||
User can invite remote user to room with version 4
|
||||
|
|
|
|||
Loading…
Reference in a new issue