diff --git a/federationapi/routing/invite.go b/federationapi/routing/invite.go index e8ab6b0be..7241173ec 100644 --- a/federationapi/routing/invite.go +++ b/federationapi/routing/invite.go @@ -37,26 +37,39 @@ func Invite( producer *producers.RoomserverProducer, keys gomatrixserverlib.KeyRing, ) util.JSONResponse { - inviteReq := gomatrixserverlib.InviteV2Request{} - if err := json.Unmarshal(request.Content(), &inviteReq); err != nil { + var intermediate struct { + Event json.RawMessage `json:"event"` + InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"` + RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` + } + + // Unmarshal the request into the intermediate form. + if err := json.Unmarshal(request.Content(), &intermediate); err != nil { return util.JSONResponse{ Code: http.StatusBadRequest, - JSON: jsonerror.NotJSON("The request body could not be decoded into an invite request. " + err.Error()), + JSON: jsonerror.NotJSON("The request body could not be decoded into an invite request: " + err.Error()), } } - event := inviteReq.Event() - // Check if we support the room version for the invite. - roomVersion := inviteReq.RoomVersion() - if _, err := roomserverVersion.SupportedRoomVersion(roomVersion); err != nil { + // Check if we support the supplied room version before doing anything else. + if _, err := roomserverVersion.SupportedRoomVersion(intermediate.RoomVersion); err != nil { return util.JSONResponse{ Code: http.StatusBadRequest, JSON: jsonerror.UnsupportedRoomVersion( - fmt.Sprintf("Users of this server cannot join version %q rooms.", roomVersion), + fmt.Sprintf("Users of this server cannot join version %q rooms.", intermediate.RoomVersion), ), } } + // Unmarshal the event. + event, err := gomatrixserverlib.NewEventFromUntrustedJSON(intermediate.Event, intermediate.RoomVersion) + if err != nil { + return util.JSONResponse{ + Code: http.StatusBadRequest, + JSON: jsonerror.NotJSON("The event in the request body could not be parsed: " + err.Error()), + } + } + // Check that the room ID is correct. if event.RoomID() != roomID { return util.JSONResponse{ @@ -101,8 +114,8 @@ func Invite( // Add the invite event to the roomserver. if err = producer.SendInvite( httpReq.Context(), - signedEvent.Headered(inviteReq.RoomVersion()), - inviteReq.InviteRoomState(), + signedEvent.Headered(intermediate.RoomVersion), + intermediate.InviteRoomState, ); err != nil { util.GetLogger(httpReq.Context()).WithError(err).Error("producer.SendInvite failed") return jsonerror.InternalServerError() diff --git a/federationsender/consumers/roomserver.go b/federationsender/consumers/roomserver.go index c72464932..a36fb3792 100644 --- a/federationsender/consumers/roomserver.go +++ b/federationsender/consumers/roomserver.go @@ -190,12 +190,8 @@ func (s *OutputRoomEventConsumer) processInvite(oie api.OutputNewInviteEvent) er // 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. Initially we'll strip down - // the invite event itself, as this satisfies the membership event in the - // stripped state. - strippedState := []gomatrixserverlib.InviteV2StrippedState{ - gomatrixserverlib.NewInviteV2StrippedState(&oie.Event.Event), - } + // user, like the room name, aliases etc. + strippedState := []gomatrixserverlib.InviteV2StrippedState{} stateWanted := []string{ gomatrixserverlib.MRoomName, gomatrixserverlib.MRoomCanonicalAlias, gomatrixserverlib.MRoomAliases, gomatrixserverlib.MRoomJoinRules, diff --git a/roomserver/input/events.go b/roomserver/input/events.go index 2bb0d0a05..5f67c7f49 100644 --- a/roomserver/input/events.go +++ b/roomserver/input/events.go @@ -247,8 +247,10 @@ func processInviteEvent( event := input.Event.Unwrap() - if err = event.SetUnsignedField("invite_room_state", input.InviteRoomState); err != nil { - return err + if len(input.InviteRoomState) > 0 { + if err = event.SetUnsignedField("invite_room_state", input.InviteRoomState); err != nil { + return err + } } outputUpdates, err := updateToInviteMembership(updater, &event, nil, input.Event.RoomVersion)