From 227493cc5d33d748dd3f5a3f7ccb7922d900f75c Mon Sep 17 00:00:00 2001 From: Devon Hudson Date: Mon, 6 Nov 2023 16:54:29 -0700 Subject: [PATCH] Handle cryptoID invites & leaves --- clientapi/routing/leaveroom.go | 13 ++- clientapi/routing/routing.go | 18 ++- clientapi/routing/sendevent.go | 22 ++-- clientapi/routing/server_notices.go | 2 +- federationapi/api/api.go | 2 +- federationapi/internal/perform.go | 1 + internal/eventutil/events.go | 20 +++- roomserver/api/api.go | 2 +- roomserver/internal/api.go | 12 +- roomserver/internal/perform/perform_admin.go | 2 +- roomserver/internal/perform/perform_invite.go | 2 +- roomserver/internal/perform/perform_join.go | 13 +-- roomserver/internal/perform/perform_leave.go | 105 ++++++++++-------- syncapi/types/types.go | 3 + userapi/internal/key_api.go | 8 +- 15 files changed, 139 insertions(+), 86 deletions(-) diff --git a/clientapi/routing/leaveroom.go b/clientapi/routing/leaveroom.go index 7e8c066eb..8a615a207 100644 --- a/clientapi/routing/leaveroom.go +++ b/clientapi/routing/leaveroom.go @@ -15,6 +15,7 @@ package routing import ( + "encoding/json" "net/http" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" @@ -23,11 +24,16 @@ import ( "github.com/matrix-org/util" ) +type leaveRoomCryptoIDsResponse struct { + PDU json.RawMessage `json:"pdu"` +} + func LeaveRoomByID( req *http.Request, device *api.Device, rsAPI roomserverAPI.ClientRoomserverAPI, roomID string, + cryptoIDs bool, ) util.JSONResponse { userID, err := spec.NewUserID(device.UserID, true) if err != nil { @@ -45,7 +51,8 @@ func LeaveRoomByID( leaveRes := roomserverAPI.PerformLeaveResponse{} // Ask the roomserver to perform the leave. - if err := rsAPI.PerformLeave(req.Context(), &leaveReq, &leaveRes); err != nil { + leaveEvent, err := rsAPI.PerformLeave(req.Context(), &leaveReq, &leaveRes, cryptoIDs) + if err != nil { if leaveRes.Code != 0 { return util.JSONResponse{ Code: leaveRes.Code, @@ -60,6 +67,8 @@ func LeaveRoomByID( return util.JSONResponse{ Code: http.StatusOK, - JSON: struct{}{}, + JSON: leaveRoomCryptoIDsResponse{ + PDU: json.RawMessage(leaveEvent.JSON()), + }, } } diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go index 62cdb584e..435c7d45d 100644 --- a/clientapi/routing/routing.go +++ b/clientapi/routing/routing.go @@ -443,7 +443,6 @@ func Setup( return resp.(util.JSONResponse) }, httputil.WithAllowGuests()), ).Methods(http.MethodPost, http.MethodOptions) - // TODO: update for cryptoIDs v3mux.Handle("/rooms/{roomID}/leave", httputil.MakeAuthAPI("membership", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { if r := rateLimits.Limit(req, device); r != nil { @@ -454,7 +453,22 @@ func Setup( return util.ErrorResponse(err) } return LeaveRoomByID( - req, device, rsAPI, vars["roomID"], + req, device, rsAPI, vars["roomID"], false, + ) + }, httputil.WithAllowGuests()), + ).Methods(http.MethodPost, http.MethodOptions) + unstableMux.Handle("/org.matrix.msc_cryptoids/rooms/{roomID}/leave", + httputil.MakeAuthAPI("membership", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { + logrus.Info("Processing request to /org.matrix.msc_cryptoids/rooms/{roomID}/leave") + if r := rateLimits.Limit(req, device); r != nil { + return *r + } + vars, err := httputil.URLDecodeMapValues(mux.Vars(req)) + if err != nil { + return util.ErrorResponse(err) + } + return LeaveRoomByID( + req, device, rsAPI, vars["roomID"], true, ) }, httputil.WithAllowGuests()), ).Methods(http.MethodPost, http.MethodOptions) diff --git a/clientapi/routing/sendevent.go b/clientapi/routing/sendevent.go index 3a0f620ac..184936380 100644 --- a/clientapi/routing/sendevent.go +++ b/clientapi/routing/sendevent.go @@ -32,6 +32,7 @@ import ( "github.com/matrix-org/dendrite/syncapi/synctypes" userapi "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/gomatrixserverlib/fclient" "github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/util" "github.com/prometheus/client_golang/prometheus" @@ -171,7 +172,7 @@ func SendEvent( } } - e, resErr := generateSendEvent(req.Context(), r, device, roomID, eventType, stateKey, rsAPI, evTime) + e, resErr := generateSendEvent(req.Context(), r, device, roomID, eventType, stateKey, rsAPI, evTime, false) if resErr != nil { return *resErr } @@ -362,7 +363,7 @@ func SendEventCryptoIDs( } } - e, resErr := generateSendEvent(req.Context(), r, device, roomID, eventType, stateKey, rsAPI, evTime) + e, resErr := generateSendEvent(req.Context(), r, device, roomID, eventType, stateKey, rsAPI, evTime, true) if resErr != nil { return *resErr } @@ -484,6 +485,7 @@ func generateSendEvent( roomID, eventType string, stateKey *string, rsAPI api.ClientRoomserverAPI, evTime time.Time, + cryptoIDs bool, ) (gomatrixserverlib.PDU, *util.JSONResponse) { // parse the incoming http request fullUserID, err := spec.NewUserID(device.UserID, true) @@ -531,12 +533,18 @@ func generateSendEvent( } } - identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *fullUserID) - if err != nil { - return nil, &util.JSONResponse{ - Code: http.StatusInternalServerError, - JSON: spec.InternalServerError{}, + var identity fclient.SigningIdentity + if !cryptoIDs { + id, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *fullUserID) + if err != nil { + return nil, &util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: spec.InternalServerError{}, + } } + identity = id + } else { + identity.ServerName = spec.ServerName(*senderID) } var queryRes api.QueryLatestEventsAndStateResponse diff --git a/clientapi/routing/server_notices.go b/clientapi/routing/server_notices.go index c711f623d..7cd682967 100644 --- a/clientapi/routing/server_notices.go +++ b/clientapi/routing/server_notices.go @@ -228,7 +228,7 @@ func SendServerNotice( "body": r.Content.Body, "msgtype": r.Content.MsgType, } - e, resErr := generateSendEvent(ctx, request, senderDevice, roomID, "m.room.message", nil, rsAPI, time.Now()) + e, resErr := generateSendEvent(ctx, request, senderDevice, roomID, "m.room.message", nil, rsAPI, time.Now(), false) if resErr != nil { logrus.Errorf("failed to send message: %+v", resErr) return *resErr diff --git a/federationapi/api/api.go b/federationapi/api/api.go index a846bcf39..3be6b61bc 100644 --- a/federationapi/api/api.go +++ b/federationapi/api/api.go @@ -61,7 +61,7 @@ type RoomserverFederationAPI interface { PerformMakeJoin(ctx context.Context, request *PerformJoinRequest) (gomatrixserverlib.PDU, gomatrixserverlib.RoomVersion, spec.ServerName, error) PerformSendJoin(ctx context.Context, request *PerformSendJoinRequestCryptoIDs, response *PerformJoinResponse) // Handle an instruction to make_leave & send_leave with a remote server. - PerformLeave(ctx context.Context, request *PerformLeaveRequest, response *PerformLeaveResponse) error + PerformLeave(ctx context.Context, request *PerformLeaveRequest, response *PerformLeaveResponse, cryptoIDs bool) error // Handle sending an invite to a remote server. SendInvite(ctx context.Context, event gomatrixserverlib.PDU, strippedState []gomatrixserverlib.InviteStrippedState) (gomatrixserverlib.PDU, error) // Handle sending an invite to a remote server. diff --git a/federationapi/internal/perform.go b/federationapi/internal/perform.go index 4d083f56a..5625bc40b 100644 --- a/federationapi/internal/perform.go +++ b/federationapi/internal/perform.go @@ -747,6 +747,7 @@ func (r *FederationInternalAPI) PerformLeave( ctx context.Context, request *api.PerformLeaveRequest, response *api.PerformLeaveResponse, + cryptoIDs bool, ) (err error) { userID, err := spec.NewUserID(request.UserID, true) if err != nil { diff --git a/internal/eventutil/events.go b/internal/eventutil/events.go index 40d62fd68..b2a7af66b 100644 --- a/internal/eventutil/events.go +++ b/internal/eventutil/events.go @@ -85,12 +85,20 @@ func BuildEvent( } builder := verImpl.NewEventBuilderFromProtoEvent(proto) - event, err := builder.Build( - evTime, identity.ServerName, identity.KeyID, - identity.PrivateKey, - ) - if err != nil { - return nil, err + var event gomatrixserverlib.PDU + if identity.PrivateKey != nil { + event, err = builder.Build( + evTime, identity.ServerName, identity.KeyID, + identity.PrivateKey, + ) + if err != nil { + return nil, err + } + } else { + event, err = builder.BuildWithoutSigning(evTime, identity.ServerName) + if err != nil { + return nil, err + } } return &types.HeaderedEvent{PDU: event}, nil diff --git a/roomserver/api/api.go b/roomserver/api/api.go index 2f2ed295d..d3813a5c1 100644 --- a/roomserver/api/api.go +++ b/roomserver/api/api.go @@ -248,7 +248,7 @@ type ClientRoomserverAPI interface { PerformJoin(ctx context.Context, req *PerformJoinRequest) (roomID string, joinedVia spec.ServerName, err error) PerformSendJoinCryptoIDs(ctx context.Context, req *PerformJoinRequestCryptoIDs) error PerformJoinCryptoIDs(ctx context.Context, req *PerformJoinRequest) (join gomatrixserverlib.PDU, roomID string, version gomatrixserverlib.RoomVersion, serverName spec.ServerName, err error) - PerformLeave(ctx context.Context, req *PerformLeaveRequest, res *PerformLeaveResponse) error + PerformLeave(ctx context.Context, req *PerformLeaveRequest, res *PerformLeaveResponse, cryptoIDs bool) (gomatrixserverlib.PDU, error) PerformPublish(ctx context.Context, req *PerformPublishRequest) error // PerformForget forgets a rooms history for a specific user PerformForget(ctx context.Context, req *PerformForgetRequest, resp *PerformForgetResponse) error diff --git a/roomserver/internal/api.go b/roomserver/internal/api.go index 64f7f3c2d..ad22b3cc9 100644 --- a/roomserver/internal/api.go +++ b/roomserver/internal/api.go @@ -262,16 +262,18 @@ func (r *RoomserverInternalAPI) PerformLeave( ctx context.Context, req *api.PerformLeaveRequest, res *api.PerformLeaveResponse, -) error { - outputEvents, err := r.Leaver.PerformLeave(ctx, req, res) + cryptoIDs bool, +) (gomatrixserverlib.PDU, error) { + outputEvents, leaveEvent, err := r.Leaver.PerformLeave(ctx, req, res, cryptoIDs) if err != nil { sentry.CaptureException(err) - return err + return nil, err } if len(outputEvents) == 0 { - return nil + return leaveEvent, nil } - return r.OutputProducer.ProduceRoomEvents(req.RoomID, outputEvents) + // TODO: cryptoIDs - what to do with this? + return leaveEvent, r.OutputProducer.ProduceRoomEvents(req.RoomID, outputEvents) } func (r *RoomserverInternalAPI) PerformForget( diff --git a/roomserver/internal/perform/perform_admin.go b/roomserver/internal/perform/perform_admin.go index ae203854b..8cd63ba1a 100644 --- a/roomserver/internal/perform/perform_admin.go +++ b/roomserver/internal/perform/perform_admin.go @@ -179,7 +179,7 @@ func (r *Admin) PerformAdminEvacuateUser( Leaver: *fullUserID, } leaveRes := &api.PerformLeaveResponse{} - outputEvents, err := r.Leaver.PerformLeave(ctx, leaveReq, leaveRes) + outputEvents, _, err := r.Leaver.PerformLeave(ctx, leaveReq, leaveRes, false) if err != nil { return nil, err } diff --git a/roomserver/internal/perform/perform_invite.go b/roomserver/internal/perform/perform_invite.go index 6f3eb036e..19ae13725 100644 --- a/roomserver/internal/perform/perform_invite.go +++ b/roomserver/internal/perform/perform_invite.go @@ -163,7 +163,7 @@ func (r *Inviter) PerformInvite( isTargetLocal := r.Cfg.Matrix.IsLocalServerName(req.InviteInput.Invitee.Domain()) signingKey := req.InviteInput.PrivateKey - if info.RoomVersion == gomatrixserverlib.RoomVersionPseudoIDs { + if !cryptoIDs && info.RoomVersion == gomatrixserverlib.RoomVersionPseudoIDs { signingKey, err = r.RSAPI.GetOrCreateUserRoomPrivateKey(ctx, req.InviteInput.Inviter, req.InviteInput.RoomID) if err != nil { return nil, err diff --git a/roomserver/internal/perform/perform_join.go b/roomserver/internal/perform/perform_join.go index e23173cf4..2df20618d 100644 --- a/roomserver/internal/perform/perform_join.go +++ b/roomserver/internal/perform/perform_join.go @@ -665,15 +665,8 @@ func (r *Joiner) performJoinRoomByIDCryptoIDs( // at this point we know we have an existing room if inRoomRes.RoomVersion == gomatrixserverlib.RoomVersionPseudoIDs { - var pseudoIDKey ed25519.PrivateKey - pseudoIDKey, err = r.RSAPI.GetOrCreateUserRoomPrivateKey(ctx, *userID, *roomID) - if err != nil { - util.GetLogger(ctx).WithError(err).Error("GetOrCreateUserRoomPrivateKey failed") - return nil, "", "", "", err - } - mapping := &gomatrixserverlib.MXIDMapping{ - UserRoomKey: spec.SenderIDFromPseudoIDKey(pseudoIDKey), + UserRoomKey: senderID, UserID: userID.String(), } @@ -685,9 +678,9 @@ func (r *Joiner) performJoinRoomByIDCryptoIDs( // sign the event with the pseudo ID key identity = fclient.SigningIdentity{ - ServerName: spec.ServerName(spec.SenderIDFromPseudoIDKey(pseudoIDKey)), + ServerName: spec.ServerName(senderID), KeyID: "ed25519:1", - PrivateKey: pseudoIDKey, + PrivateKey: nil, } } diff --git a/roomserver/internal/perform/perform_leave.go b/roomserver/internal/perform/perform_leave.go index 5bea00445..e2897549c 100644 --- a/roomserver/internal/perform/perform_leave.go +++ b/roomserver/internal/perform/perform_leave.go @@ -24,6 +24,7 @@ import ( "github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrixserverlib" + "github.com/matrix-org/gomatrixserverlib/fclient" "github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/util" "github.com/sirupsen/logrus" @@ -52,9 +53,10 @@ func (r *Leaver) PerformLeave( ctx context.Context, req *api.PerformLeaveRequest, res *api.PerformLeaveResponse, -) ([]api.OutputEvent, error) { + cryptoIDs bool, +) ([]api.OutputEvent, gomatrixserverlib.PDU, error) { if !r.Cfg.Matrix.IsLocalServerName(req.Leaver.Domain()) { - return nil, fmt.Errorf("user %q does not belong to this homeserver", req.Leaver.String()) + return nil, nil, fmt.Errorf("user %q does not belong to this homeserver", req.Leaver.String()) } logger := logrus.WithContext(ctx).WithFields(logrus.Fields{ "room_id": req.RoomID, @@ -62,15 +64,15 @@ func (r *Leaver) PerformLeave( }) logger.Info("User requested to leave join") if strings.HasPrefix(req.RoomID, "!") { - output, err := r.performLeaveRoomByID(context.Background(), req, res) + output, event, err := r.performLeaveRoomByID(context.Background(), req, res, cryptoIDs) if err != nil { logger.WithError(err).Error("Failed to leave room") } else { logger.Info("User left room successfully") } - return output, err + return output, event, err } - return nil, fmt.Errorf("room ID %q is invalid", req.RoomID) + return nil, nil, fmt.Errorf("room ID %q is invalid", req.RoomID) } // nolint:gocyclo @@ -78,14 +80,15 @@ func (r *Leaver) performLeaveRoomByID( ctx context.Context, req *api.PerformLeaveRequest, res *api.PerformLeaveResponse, // nolint:unparam -) ([]api.OutputEvent, error) { + cryptoIDs bool, +) ([]api.OutputEvent, gomatrixserverlib.PDU, error) { roomID, err := spec.NewRoomID(req.RoomID) if err != nil { - return nil, err + return nil, nil, err } leaver, err := r.RSAPI.QuerySenderIDForUser(ctx, *roomID, req.Leaver) if err != nil || leaver == nil { - return nil, fmt.Errorf("leaver %s has no matching senderID in this room", req.Leaver.String()) + return nil, nil, fmt.Errorf("leaver %s has no matching senderID in this room", req.Leaver.String()) } // If there's an invite outstanding for the room then respond to @@ -94,7 +97,7 @@ func (r *Leaver) performLeaveRoomByID( if err == nil && isInvitePending { sender, serr := r.RSAPI.QueryUserIDForSender(ctx, *roomID, senderUser) if serr != nil { - return nil, fmt.Errorf("failed looking up userID for sender %q: %w", senderUser, serr) + return nil, nil, fmt.Errorf("failed looking up userID for sender %q: %w", senderUser, serr) } var domain spec.ServerName @@ -107,7 +110,7 @@ func (r *Leaver) performLeaveRoomByID( domain = sender.Domain() } if !r.Cfg.Matrix.IsLocalServerName(domain) { - return r.performFederatedRejectInvite(ctx, req, res, domain, eventID, *leaver) + return r.performFederatedRejectInvite(ctx, req, res, domain, eventID, *leaver, cryptoIDs) } // check that this is not a "server notice room" accData := &userapi.QueryAccountDataResponse{} @@ -116,7 +119,7 @@ func (r *Leaver) performLeaveRoomByID( RoomID: req.RoomID, DataType: "m.tag", }, accData); err != nil { - return nil, fmt.Errorf("unable to query account data: %w", err) + return nil, nil, fmt.Errorf("unable to query account data: %w", err) } if roomData, ok := accData.RoomAccountData[req.RoomID]; ok { @@ -124,13 +127,13 @@ func (r *Leaver) performLeaveRoomByID( if ok { tags := gomatrix.TagContent{} if err = json.Unmarshal(tagData, &tags); err != nil { - return nil, fmt.Errorf("unable to unmarshal tag content") + return nil, nil, fmt.Errorf("unable to unmarshal tag content") } if _, ok = tags.Tags["m.server_notice"]; ok { // mimic the returned values from Synapse res.Message = "You cannot reject this invite" res.Code = 403 - return nil, spec.LeaveServerNoticeError() + return nil, nil, spec.LeaveServerNoticeError() } } } @@ -149,22 +152,22 @@ func (r *Leaver) performLeaveRoomByID( } latestRes := api.QueryLatestEventsAndStateResponse{} if err = helpers.QueryLatestEventsAndState(ctx, r.DB, r.RSAPI, &latestReq, &latestRes); err != nil { - return nil, err + return nil, nil, err } if !latestRes.RoomExists { - return nil, fmt.Errorf("room %q does not exist", req.RoomID) + return nil, nil, fmt.Errorf("room %q does not exist", req.RoomID) } // Now let's see if the user is in the room. if len(latestRes.StateEvents) == 0 { - return nil, fmt.Errorf("user %q is not a member of room %q", req.Leaver.String(), req.RoomID) + return nil, nil, fmt.Errorf("user %q is not a member of room %q", req.Leaver.String(), req.RoomID) } membership, err := latestRes.StateEvents[0].Membership() if err != nil { - return nil, fmt.Errorf("error getting membership: %w", err) + return nil, nil, fmt.Errorf("error getting membership: %w", err) } if membership != spec.Join && membership != spec.Invite { - return nil, fmt.Errorf("user %q is not joined to the room (membership is %q)", req.Leaver.String(), membership) + return nil, nil, fmt.Errorf("user %q is not joined to the room (membership is %q)", req.Leaver.String(), membership) } // Prepare the template for the leave event. @@ -177,10 +180,10 @@ func (r *Leaver) performLeaveRoomByID( Redacts: "", } if err = proto.SetContent(map[string]interface{}{"membership": "leave"}); err != nil { - return nil, fmt.Errorf("eb.SetContent: %w", err) + return nil, nil, fmt.Errorf("eb.SetContent: %w", err) } if err = proto.SetUnsigned(struct{}{}); err != nil { - return nil, fmt.Errorf("eb.SetUnsigned: %w", err) + return nil, nil, fmt.Errorf("eb.SetUnsigned: %w", err) } // We know that the user is in the room at this point so let's build @@ -190,39 +193,50 @@ func (r *Leaver) performLeaveRoomByID( validRoomID, err := spec.NewRoomID(req.RoomID) if err != nil { - return nil, err + return nil, nil, err } var buildRes rsAPI.QueryLatestEventsAndStateResponse - identity, err := r.RSAPI.SigningIdentityFor(ctx, *validRoomID, req.Leaver) - if err != nil { - return nil, fmt.Errorf("SigningIdentityFor: %w", err) + var identity fclient.SigningIdentity + if !cryptoIDs { + identity, err = r.RSAPI.SigningIdentityFor(ctx, *validRoomID, req.Leaver) + if err != nil { + return nil, nil, fmt.Errorf("SigningIdentityFor: %w", err) + } + } else { + identity = fclient.SigningIdentity{ + ServerName: spec.ServerName(*leaver), + KeyID: "ed25519:1", + PrivateKey: nil, + } } event, err := eventutil.QueryAndBuildEvent(ctx, &proto, &identity, time.Now(), r.RSAPI, &buildRes) if err != nil { - return nil, fmt.Errorf("eventutil.QueryAndBuildEvent: %w", err) + return nil, nil, fmt.Errorf("eventutil.QueryAndBuildEvent: %w", err) } - // Give our leave event to the roomserver input stream. The - // roomserver will process the membership change and notify - // downstream automatically. - inputReq := api.InputRoomEventsRequest{ - InputRoomEvents: []api.InputRoomEvent{ - { - Kind: api.KindNew, - Event: event, - Origin: req.Leaver.Domain(), - SendAsServer: string(req.Leaver.Domain()), + if !cryptoIDs { + // Give our leave event to the roomserver input stream. The + // roomserver will process the membership change and notify + // downstream automatically. + inputReq := api.InputRoomEventsRequest{ + InputRoomEvents: []api.InputRoomEvent{ + { + Kind: api.KindNew, + Event: event, + Origin: req.Leaver.Domain(), + SendAsServer: string(req.Leaver.Domain()), + }, }, - }, - } - inputRes := api.InputRoomEventsResponse{} - r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes) - if err = inputRes.Err(); err != nil { - return nil, fmt.Errorf("r.InputRoomEvents: %w", err) + } + inputRes := api.InputRoomEventsResponse{} + r.Inputer.InputRoomEvents(ctx, &inputReq, &inputRes) + if err = inputRes.Err(); err != nil { + return nil, nil, fmt.Errorf("r.InputRoomEvents: %w", err) + } } - return nil, nil + return nil, event, nil } func (r *Leaver) performFederatedRejectInvite( @@ -231,7 +245,8 @@ func (r *Leaver) performFederatedRejectInvite( res *api.PerformLeaveResponse, // nolint:unparam inviteDomain spec.ServerName, eventID string, leaver spec.SenderID, -) ([]api.OutputEvent, error) { + cryptoIDs bool, +) ([]api.OutputEvent, gomatrixserverlib.PDU, error) { // Ask the federation sender to perform a federated leave for us. leaveReq := fsAPI.PerformLeaveRequest{ RoomID: req.RoomID, @@ -239,7 +254,7 @@ func (r *Leaver) performFederatedRejectInvite( ServerNames: []spec.ServerName{inviteDomain}, } leaveRes := fsAPI.PerformLeaveResponse{} - if err := r.FSAPI.PerformLeave(ctx, &leaveReq, &leaveRes); err != nil { + if err := r.FSAPI.PerformLeave(ctx, &leaveReq, &leaveRes, cryptoIDs); err != nil { // failures in PerformLeave should NEVER stop us from telling other components like the // sync API that the invite was withdrawn. Otherwise we can end up with stuck invites. util.GetLogger(ctx).WithError(err).Errorf("failed to PerformLeave, still retiring invite event") @@ -279,5 +294,5 @@ func (r *Leaver) performFederatedRejectInvite( TargetSenderID: leaver, }, }, - }, nil + }, nil, nil } diff --git a/syncapi/types/types.go b/syncapi/types/types.go index e74700a7d..cf5fc99b6 100644 --- a/syncapi/types/types.go +++ b/syncapi/types/types.go @@ -532,6 +532,7 @@ type InviteResponse struct { InviteState struct { Events []json.RawMessage `json:"events"` } `json:"invite_state"` + OneTimePseudoID string `json:"one_time_pseudoid,omitempty"` } // NewInviteResponse creates an empty response with initialised arrays. @@ -539,6 +540,8 @@ func NewInviteResponse(ctx context.Context, rsAPI api.QuerySenderIDAPI, event *t res := InviteResponse{} res.InviteState.Events = []json.RawMessage{} + res.OneTimePseudoID = *event.PDU.StateKey() + // First see if there's invite_room_state in the unsigned key of the invite. // If there is then unmarshal it into the response. This will contain the // partial room state such as join rules, room name etc. diff --git a/userapi/internal/key_api.go b/userapi/internal/key_api.go index 3b538e0b0..584316121 100644 --- a/userapi/internal/key_api.go +++ b/userapi/internal/key_api.go @@ -858,15 +858,15 @@ type Ed25519Key struct { } func (a *UserInternalAPI) ClaimOneTimePseudoID(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (spec.SenderID, error) { - pseudoIDs, err := a.KeyDatabase.ClaimOneTimePseudoID(ctx, userID, "ed25519") + pseudoID, err := a.KeyDatabase.ClaimOneTimePseudoID(ctx, userID, "ed25519") if err != nil { return "", err } - logrus.Infof("Claimed one time pseuodID: %v", pseudoIDs) + logrus.Infof("Claimed one time pseuodID: %s", pseudoID) - if pseudoIDs != nil { - for key, value := range pseudoIDs.KeyJSON { + if pseudoID != nil { + for key, value := range pseudoID.KeyJSON { keyParts := strings.Split(key, ":") if keyParts[0] == "ed25519" { var key_bytes Ed25519Key