mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-21 22:03:10 -06:00
Fix synchronous invites
This commit is contained in:
parent
96814d436a
commit
db57d7e00b
|
|
@ -371,10 +371,7 @@ func createRoom(
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a direct message then we should invite the participants.
|
// If this is a direct message then we should invite the participants.
|
||||||
fmt.Println("INVITEES:")
|
|
||||||
for _, invitee := range r.Invite {
|
for _, invitee := range r.Invite {
|
||||||
fmt.Println("*", invitee)
|
|
||||||
|
|
||||||
// Build the invite event.
|
// Build the invite event.
|
||||||
inviteEvent, err := buildMembershipEvent(
|
inviteEvent, err := buildMembershipEvent(
|
||||||
req.Context(), invitee, "", accountDB, device, gomatrixserverlib.Invite,
|
req.Context(), invitee, "", accountDB, device, gomatrixserverlib.Invite,
|
||||||
|
|
@ -389,6 +386,10 @@ func createRoom(
|
||||||
var strippedState []gomatrixserverlib.InviteV2StrippedState
|
var strippedState []gomatrixserverlib.InviteV2StrippedState
|
||||||
for _, event := range candidates {
|
for _, event := range candidates {
|
||||||
switch event.Type() {
|
switch event.Type() {
|
||||||
|
case gomatrixserverlib.MRoomName:
|
||||||
|
fallthrough
|
||||||
|
case gomatrixserverlib.MRoomCanonicalAlias:
|
||||||
|
fallthrough
|
||||||
case "m.room.encryption": // TODO: move this to gmsl
|
case "m.room.encryption": // TODO: move this to gmsl
|
||||||
fallthrough
|
fallthrough
|
||||||
case gomatrixserverlib.MRoomMember:
|
case gomatrixserverlib.MRoomMember:
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
"github.com/matrix-org/dendrite/clientapi/threepid"
|
"github.com/matrix-org/dendrite/clientapi/threepid"
|
||||||
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
|
currentstateAPI "github.com/matrix-org/dendrite/currentstateserver/api"
|
||||||
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
|
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/internal/eventutil"
|
"github.com/matrix-org/dendrite/internal/eventutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
|
@ -173,7 +172,6 @@ func SendInvite(
|
||||||
req *http.Request, accountDB accounts.Database, device *userapi.Device,
|
req *http.Request, accountDB accounts.Database, device *userapi.Device,
|
||||||
roomID string, cfg *config.ClientAPI,
|
roomID string, cfg *config.ClientAPI,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI, asAPI appserviceAPI.AppServiceQueryAPI,
|
||||||
fsAPI federationSenderAPI.FederationSenderInternalAPI,
|
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
body, evTime, _, reqErr := extractRequestData(req, roomID, rsAPI)
|
body, evTime, _, reqErr := extractRequestData(req, roomID, rsAPI)
|
||||||
if reqErr != nil {
|
if reqErr != nil {
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ func Setup(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
return SendInvite(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI, federationSender)
|
return SendInvite(req, accountDB, device, vars["roomID"], cfg, rsAPI, asAPI)
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodPost, http.MethodOptions)
|
).Methods(http.MethodPost, http.MethodOptions)
|
||||||
r0mux.Handle("/rooms/{roomID}/kick",
|
r0mux.Handle("/rooms/{roomID}/kick",
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ func processInvite(
|
||||||
|
|
||||||
// Add the invite event to the roomserver.
|
// Add the invite event to the roomserver.
|
||||||
if err := api.SendInvite(
|
if err := api.SendInvite(
|
||||||
ctx, rsAPI, signedEvent.Headered(roomVer), strippedState, event.Origin(), nil,
|
ctx, rsAPI, signedEvent.Headered(roomVer), strippedState, api.DoNotSendToOtherServers, nil,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("producer.SendInvite failed")
|
util.GetLogger(ctx).WithError(err).Error("producer.SendInvite failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
|
@ -100,6 +101,8 @@ func SendInvite(
|
||||||
inviteRoomState []gomatrixserverlib.InviteV2StrippedState,
|
inviteRoomState []gomatrixserverlib.InviteV2StrippedState,
|
||||||
sendAsServer gomatrixserverlib.ServerName, txnID *TransactionID,
|
sendAsServer gomatrixserverlib.ServerName, txnID *TransactionID,
|
||||||
) error {
|
) error {
|
||||||
|
// Start by sending the invite request into the roomserver. This will
|
||||||
|
// trigger the federation request amongst other things if needed.
|
||||||
request := &PerformInviteRequest{
|
request := &PerformInviteRequest{
|
||||||
Event: inviteEvent,
|
Event: inviteEvent,
|
||||||
InviteRoomState: inviteRoomState,
|
InviteRoomState: inviteRoomState,
|
||||||
|
|
@ -108,7 +111,28 @@ func SendInvite(
|
||||||
TransactionID: txnID,
|
TransactionID: txnID,
|
||||||
}
|
}
|
||||||
response := &PerformInviteResponse{}
|
response := &PerformInviteResponse{}
|
||||||
return rsAPI.PerformInvite(ctx, request, response)
|
if err := rsAPI.PerformInvite(ctx, request, response); err != nil {
|
||||||
|
return fmt.Errorf("rsAPI.PerformInvite: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now send the invite event into the roomserver. If the room is known
|
||||||
|
// locally then this will succeed, notifying existing users in the room
|
||||||
|
// about the new invite. If the room isn't known locally then this will
|
||||||
|
// fail - and that's also OK.
|
||||||
|
inputReq := &InputRoomEventsRequest{
|
||||||
|
InputRoomEvents: []InputRoomEvent{
|
||||||
|
{
|
||||||
|
Kind: KindNew,
|
||||||
|
Event: inviteEvent,
|
||||||
|
AuthEventIDs: inviteEvent.AuthEventIDs(),
|
||||||
|
SendAsServer: DoNotSendToOtherServers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
inputRes := &InputRoomEventsResponse{}
|
||||||
|
_ = rsAPI.InputRoomEvents(ctx, inputReq, inputRes)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEvent returns the event or nil, even on errors.
|
// GetEvent returns the event or nil, even on errors.
|
||||||
|
|
|
||||||
|
|
@ -36,26 +36,26 @@ func (r *RoomserverInternalAPI) PerformInvite(
|
||||||
}).Info("processing invite event")
|
}).Info("processing invite event")
|
||||||
|
|
||||||
_, domain, _ := gomatrixserverlib.SplitID('@', targetUserID)
|
_, domain, _ := gomatrixserverlib.SplitID('@', targetUserID)
|
||||||
isTargetLocalUser := domain == r.Cfg.Matrix.ServerName
|
isTargetLocal := domain == r.Cfg.Matrix.ServerName
|
||||||
isOriginLocalUser := event.Origin() == r.Cfg.Matrix.ServerName
|
isOriginLocal := event.Origin() == r.Cfg.Matrix.ServerName
|
||||||
|
|
||||||
// If the invite originated from us and the target isn't local then we
|
inviteState := req.InviteRoomState
|
||||||
// should try and send the invite over federation first. It might be
|
if len(inviteState) == 0 {
|
||||||
// that the remote user doesn't exist, in which case we can give up
|
if is, err := buildInviteStrippedState(ctx, r.DB, req); err == nil {
|
||||||
// processing here.
|
inviteState = is
|
||||||
if isOriginLocalUser && !isTargetLocalUser {
|
|
||||||
fsReq := &federationSenderAPI.PerformInviteRequest{
|
|
||||||
RoomVersion: req.RoomVersion,
|
|
||||||
Event: req.Event,
|
|
||||||
}
|
}
|
||||||
fsRes := &federationSenderAPI.PerformInviteResponse{}
|
|
||||||
if err := r.fsAPI.PerformInvite(ctx, fsReq, fsRes); err != nil {
|
|
||||||
return fmt.Errorf("r.fsAPI.PerformInvite: %w", err)
|
|
||||||
}
|
}
|
||||||
event = fsRes.SignedEvent
|
if len(inviteState) == 0 {
|
||||||
|
if err := event.SetUnsignedField("invite_room_state", struct{}{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := event.SetUnsignedField("invite_room_state", inviteState); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updater, err := r.DB.MembershipUpdater(ctx, roomID, targetUserID, isTargetLocalUser, req.RoomVersion)
|
updater, err := r.DB.MembershipUpdater(ctx, roomID, targetUserID, isTargetLocal, req.RoomVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -101,9 +101,9 @@ func (r *RoomserverInternalAPI) PerformInvite(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isOriginLocal {
|
||||||
// check that the user is allowed to do this. We can only do this check if it is
|
// check that the user is allowed to do this. We can only do this check if it is
|
||||||
// a local invite as we have the auth events, else we have to take it on trust.
|
// a local invite as we have the auth events, else we have to take it on trust.
|
||||||
if isOriginLocalUser {
|
|
||||||
_, err = checkAuthEvents(ctx, r.DB, req.Event, req.Event.AuthEventIDs())
|
_, err = checkAuthEvents(ctx, r.DB, req.Event, req.Event.AuthEventIDs())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).WithField("event_id", event.EventID()).WithField("auth_event_ids", event.AuthEventIDs()).Error(
|
log.WithError(err).WithField("event_id", event.EventID()).WithField("auth_event_ids", event.AuthEventIDs()).Error(
|
||||||
|
|
@ -117,50 +117,22 @@ func (r *RoomserverInternalAPI) PerformInvite(
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if len(req.InviteRoomState) > 0 {
|
// If the invite originated from us and the target isn't local then we
|
||||||
// If we were supplied with some invite room state already (which is
|
// should try and send the invite over federation first. It might be
|
||||||
// most likely to be if the event came in over federation) then use
|
// that the remote user doesn't exist, in which case we can give up
|
||||||
// that.
|
// processing here.
|
||||||
if err = event.SetUnsignedField("invite_room_state", req.InviteRoomState); err != nil {
|
if req.SendAsServer != api.DoNotSendToOtherServers && !isTargetLocal {
|
||||||
return err
|
fsReq := &federationSenderAPI.PerformInviteRequest{
|
||||||
|
RoomVersion: req.RoomVersion,
|
||||||
|
Event: req.Event,
|
||||||
|
InviteRoomState: inviteState,
|
||||||
}
|
}
|
||||||
} else {
|
fsRes := &federationSenderAPI.PerformInviteResponse{}
|
||||||
// There's no invite room state, so let's have a go at building it
|
if err = r.fsAPI.PerformInvite(ctx, fsReq, fsRes); err != nil {
|
||||||
// up from local data (which is most likely to be if the event came
|
return fmt.Errorf("r.fsAPI.PerformInvite: %w", err)
|
||||||
// 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, r.DB, req); ierr == nil {
|
|
||||||
if err = event.SetUnsignedField("invite_room_state", irs); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
} else {
|
event = fsRes.SignedEvent
|
||||||
log.WithError(ierr).Warn("failed to build invite stripped state")
|
|
||||||
// still set the field else synapse deployments don't process the invite
|
|
||||||
if err = event.SetUnsignedField("invite_room_state", struct{}{}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're the sender of the event then we should send the invite
|
|
||||||
// event into the room so that the room state is updated and other
|
|
||||||
// room participants will see the invite.
|
|
||||||
if isOriginLocalUser {
|
|
||||||
inputReq := &api.InputRoomEventsRequest{
|
|
||||||
InputRoomEvents: []api.InputRoomEvent{
|
|
||||||
{
|
|
||||||
Kind: api.KindNew,
|
|
||||||
Event: event,
|
|
||||||
AuthEventIDs: event.AuthEventIDs(),
|
|
||||||
SendAsServer: api.DoNotSendToOtherServers,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
inputRes := &api.InputRoomEventsResponse{}
|
|
||||||
if err = r.InputRoomEvents(ctx, inputReq, inputRes); err != nil {
|
|
||||||
return fmt.Errorf("r.InputRoomEvents: %w", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,7 +165,7 @@ func buildInviteStrippedState(
|
||||||
for _, t := range []string{
|
for _, t := range []string{
|
||||||
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
|
gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias,
|
||||||
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
|
gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules,
|
||||||
"m.room.avatar",
|
"m.room.avatar", "m.room.encryption",
|
||||||
} {
|
} {
|
||||||
stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{
|
stateWanted = append(stateWanted, gomatrixserverlib.StateKeyTuple{
|
||||||
EventType: t,
|
EventType: t,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue