From cea8f0ade10f088c64c7ae9cab557b0bc848d4a5 Mon Sep 17 00:00:00 2001 From: Devon Hudson Date: Fri, 30 Jun 2023 14:17:21 -0600 Subject: [PATCH] Get federated pseudoID invites working --- federationapi/internal/api.go | 5 +++- federationapi/internal/perform.go | 6 +---- federationapi/internal/perform_test.go | 27 ++++++++++++++++--- federationapi/routing/invite.go | 2 +- go.mod | 2 +- go.sum | 6 ++--- roomserver/internal/perform/perform_invite.go | 17 +++++++++++- roomserver/version/version.go | 1 + syncapi/notifier/notifier.go | 2 +- userapi/consumers/roomserver.go | 4 ++- 10 files changed, 54 insertions(+), 18 deletions(-) diff --git a/federationapi/internal/api.go b/federationapi/internal/api.go index aa501f63c..3e6f39566 100644 --- a/federationapi/internal/api.go +++ b/federationapi/internal/api.go @@ -54,11 +54,14 @@ func NewFederationInternalAPI( KeyDatabase: serverKeyDB, } + pubKey := cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey) addDirectFetcher := func() { keyRing.KeyFetchers = append( keyRing.KeyFetchers, &gomatrixserverlib.DirectKeyFetcher{ - Client: federation, + Client: federation, + IsLocalServerName: cfg.Matrix.IsLocalServerName, + LocalPublicKey: []byte(pubKey), }, ) } diff --git a/federationapi/internal/perform.go b/federationapi/internal/perform.go index 6723c7c21..1b2a54455 100644 --- a/federationapi/internal/perform.go +++ b/federationapi/internal/perform.go @@ -616,10 +616,6 @@ func (r *FederationInternalAPI) SendInviteV3( return nil, err } - if event.StateKey == nil { - return nil, errors.New("invite must be a state event") - } - // TODO (devon): This should be allowed via a relay. Currently only transactions // can be sent to relays. Would need to extend relays to handle invites. if !r.shouldAttemptDirectFederation(invitee.Domain()) { @@ -627,7 +623,7 @@ func (r *FederationInternalAPI) SendInviteV3( } logrus.WithFields(logrus.Fields{ - "user_id": *event.StateKey, + "user_id": invitee.String(), "room_id": event.RoomID, "room_version": version, "destination": invitee.Domain(), diff --git a/federationapi/internal/perform_test.go b/federationapi/internal/perform_test.go index 2f61235ae..656755f96 100644 --- a/federationapi/internal/perform_test.go +++ b/federationapi/internal/perform_test.go @@ -16,6 +16,7 @@ package internal import ( "context" + "crypto/ed25519" "testing" "github.com/matrix-org/dendrite/federationapi/api" @@ -53,10 +54,14 @@ func TestPerformWakeupServers(t *testing.T) { assert.NoError(t, err) assert.True(t, offline) + _, key, err := ed25519.GenerateKey(nil) + assert.NoError(t, err) cfg := config.FederationAPI{ Matrix: &config.Global{ SigningIdentity: fclient.SigningIdentity{ ServerName: "relay", + KeyID: "ed25519:1", + PrivateKey: key, }, }, } @@ -95,10 +100,14 @@ func TestQueryRelayServers(t *testing.T) { err := testDB.P2PAddRelayServersForServer(context.Background(), server, relayServers) assert.NoError(t, err) + _, key, err := ed25519.GenerateKey(nil) + assert.NoError(t, err) cfg := config.FederationAPI{ Matrix: &config.Global{ SigningIdentity: fclient.SigningIdentity{ ServerName: "relay", + KeyID: "ed25519:1", + PrivateKey: key, }, }, } @@ -132,10 +141,14 @@ func TestRemoveRelayServers(t *testing.T) { err := testDB.P2PAddRelayServersForServer(context.Background(), server, relayServers) assert.NoError(t, err) + _, key, err := ed25519.GenerateKey(nil) + assert.NoError(t, err) cfg := config.FederationAPI{ Matrix: &config.Global{ SigningIdentity: fclient.SigningIdentity{ ServerName: "relay", + KeyID: "ed25519:1", + PrivateKey: key, }, }, } @@ -168,10 +181,14 @@ func TestRemoveRelayServers(t *testing.T) { func TestPerformDirectoryLookup(t *testing.T) { testDB := test.NewInMemoryFederationDatabase() + _, key, err := ed25519.GenerateKey(nil) + assert.NoError(t, err) cfg := config.FederationAPI{ Matrix: &config.Global{ SigningIdentity: fclient.SigningIdentity{ ServerName: "relay", + KeyID: "ed25519:1", + PrivateKey: key, }, }, } @@ -192,7 +209,7 @@ func TestPerformDirectoryLookup(t *testing.T) { ServerName: "server", } res := api.PerformDirectoryLookupResponse{} - err := fedAPI.PerformDirectoryLookup(context.Background(), &req, &res) + err = fedAPI.PerformDirectoryLookup(context.Background(), &req, &res) assert.NoError(t, err) } @@ -203,10 +220,14 @@ func TestPerformDirectoryLookupRelaying(t *testing.T) { testDB.SetServerAssumedOffline(context.Background(), server) testDB.P2PAddRelayServersForServer(context.Background(), server, []spec.ServerName{"relay"}) + _, key, err := ed25519.GenerateKey(nil) + assert.NoError(t, err) cfg := config.FederationAPI{ Matrix: &config.Global{ SigningIdentity: fclient.SigningIdentity{ - ServerName: server, + ServerName: "relay", + KeyID: "ed25519:1", + PrivateKey: key, }, }, } @@ -227,6 +248,6 @@ func TestPerformDirectoryLookupRelaying(t *testing.T) { ServerName: server, } res := api.PerformDirectoryLookupResponse{} - err := fedAPI.PerformDirectoryLookup(context.Background(), &req, &res) + err = fedAPI.PerformDirectoryLookup(context.Background(), &req, &res) assert.Error(t, err) } diff --git a/federationapi/routing/invite.go b/federationapi/routing/invite.go index 88fbb09bf..cc67bf7fa 100644 --- a/federationapi/routing/invite.go +++ b/federationapi/routing/invite.go @@ -85,7 +85,7 @@ func InviteV3( SenderIDQuerier: func(roomID spec.RoomID, userID spec.UserID) (spec.SenderID, error) { return rsAPI.QuerySenderIDForUser(httpReq.Context(), roomID, userID) }, - SenderIDCreator: func(ctx context.Context, userID spec.UserID, roomID spec.RoomID, roomVersion string) (spec.SenderID, ed25519.PrivateKey, error) { + GetOrCreateSenderID: func(ctx context.Context, userID spec.UserID, roomID spec.RoomID, roomVersion string) (spec.SenderID, ed25519.PrivateKey, error) { // assign a roomNID, otherwise we can't create a private key for the user _, nidErr := rsAPI.AssignRoomNID(ctx, roomID, gomatrixserverlib.RoomVersion(roomVersion)) if nidErr != nil { diff --git a/go.mod b/go.mod index 42de130bc..24a3524a7 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 - github.com/matrix-org/gomatrixserverlib v0.0.0-20230628230042-0bf682015041 + github.com/matrix-org/gomatrixserverlib v0.0.0-20230630201258-2564ca79770c github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 github.com/mattn/go-sqlite3 v1.14.16 diff --git a/go.sum b/go.sum index 889bed4f6..565ab590c 100644 --- a/go.sum +++ b/go.sum @@ -323,10 +323,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= -github.com/matrix-org/gomatrixserverlib v0.0.0-20230628194752-4bac719832e6 h1:VDJPi1u1KvkJTkpAGitvu38/0bzUBBghSsB8++Q4qKQ= -github.com/matrix-org/gomatrixserverlib v0.0.0-20230628194752-4bac719832e6/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU= -github.com/matrix-org/gomatrixserverlib v0.0.0-20230628230042-0bf682015041 h1:nN0v72oM6to3mQkoXV2jdoPSHzyGFzrxvgCmF+E/OuE= -github.com/matrix-org/gomatrixserverlib v0.0.0-20230628230042-0bf682015041/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU= +github.com/matrix-org/gomatrixserverlib v0.0.0-20230630201258-2564ca79770c h1:FgkrAhxHB0i+CDQAi/lq5KSMJO4ceqtbg4IK11+L4rc= +github.com/matrix-org/gomatrixserverlib v0.0.0-20230630201258-2564ca79770c/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU= github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a h1:awrPDf9LEFySxTLKYBMCiObelNx/cBuv/wzllvCCH3A= github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a/go.mod h1:HchJX9oKMXaT2xYFs0Ha/6Zs06mxLU8k6F1ODnrGkeQ= github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y= diff --git a/roomserver/internal/perform/perform_invite.go b/roomserver/internal/perform/perform_invite.go index e55bd7623..278ddd7d8 100644 --- a/roomserver/internal/perform/perform_invite.go +++ b/roomserver/internal/perform/perform_invite.go @@ -163,6 +163,14 @@ func (r *Inviter) PerformInvite( isTargetLocal := r.Cfg.Matrix.IsLocalServerName(req.InviteInput.Invitee.Domain()) + signingKey := req.InviteInput.PrivateKey + if info.RoomVersion == gomatrixserverlib.RoomVersionPseudoIDs { + signingKey, err = r.RSAPI.GetOrCreateUserRoomPrivateKey(ctx, req.InviteInput.Inviter, req.InviteInput.RoomID) + if err != nil { + return err + } + } + input := gomatrixserverlib.PerformInviteInput{ RoomID: req.InviteInput.RoomID, RoomVersion: info.RoomVersion, @@ -172,7 +180,7 @@ func (r *Inviter) PerformInvite( EventTemplate: proto, StrippedState: req.InviteRoomState, KeyID: req.InviteInput.KeyID, - SigningKey: req.InviteInput.PrivateKey, + SigningKey: signingKey, EventTime: req.InviteInput.EventTime, MembershipQuerier: &api.MembershipQuerier{Roomserver: r.RSAPI}, StateQuerier: &QueryState{r.DB, r.RSAPI}, @@ -209,6 +217,13 @@ func (r *Inviter) PerformInvite( Depth: res.Depth, }, nil }, + StoreSenderIDFromPublicID: func(ctx context.Context, senderID spec.SenderID, userIDRaw string, roomID spec.RoomID) error { + storeUserID, userErr := spec.NewUserID(userIDRaw, true) + if userErr != nil { + return userErr + } + return r.RSAPI.StoreUserRoomPublicKey(ctx, senderID, *storeUserID, roomID) + }, } inviteEvent, err := gomatrixserverlib.PerformInvite(ctx, input, r.FSAPI) diff --git a/roomserver/version/version.go b/roomserver/version/version.go index 270d42897..5e44971b0 100644 --- a/roomserver/version/version.go +++ b/roomserver/version/version.go @@ -23,6 +23,7 @@ import ( // DefaultRoomVersion contains the room version that will, by // default, be used to create new rooms on this server. func DefaultRoomVersion() gomatrixserverlib.RoomVersion { + //return gomatrixserverlib.RoomVersionPseudoIDs return gomatrixserverlib.RoomVersionV10 } diff --git a/syncapi/notifier/notifier.go b/syncapi/notifier/notifier.go index af8ab0102..a8733f6fe 100644 --- a/syncapi/notifier/notifier.go +++ b/syncapi/notifier/notifier.go @@ -115,7 +115,7 @@ func (n *Notifier) OnNewEvent( // If this is an invite, also add in the invitee to this list. if ev.Type() == "m.room.member" && ev.StateKey() != nil { targetUserID, err := n.rsAPI.QueryUserIDForSender(context.Background(), *validRoomID, spec.SenderID(*ev.StateKey())) - if err != nil { + if err != nil || targetUserID == nil { log.WithError(err).WithField("event_id", ev.EventID()).Errorf( "Notifier.OnNewEvent: Failed to find the userID for this event", ) diff --git a/userapi/consumers/roomserver.go b/userapi/consumers/roomserver.go index 9cb9419d4..9a9a407ce 100644 --- a/userapi/consumers/roomserver.go +++ b/userapi/consumers/roomserver.go @@ -313,10 +313,12 @@ func (s *OutputRoomEventConsumer) processMessage(ctx context.Context, event *rst sk := event.StateKey() if sk != nil && *sk != "" { - skUserID, queryErr := s.rsAPI.QueryUserIDForSender(ctx, *validRoomID, spec.SenderID(*event.StateKey())) + skUserID, queryErr := s.rsAPI.QueryUserIDForSender(ctx, *validRoomID, spec.SenderID(*sk)) if queryErr == nil && skUserID != nil { skString := skUserID.String() sk = &skString + } else { + return fmt.Errorf("queryUserIDForSender: userID unknown for %s", *sk) } } cevent := synctypes.ToClientEvent(event, synctypes.FormatAll, sender, sk)