From d357615452893cf3440d9dbdf998a2654c439d33 Mon Sep 17 00:00:00 2001 From: Till <2353100+S7evinK@users.noreply.github.com> Date: Sat, 20 Jan 2024 21:20:37 +0100 Subject: [PATCH] Don't send device list updates upon registration (#3307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/matrix-org/dendrite/issues/3273 As we otherwise send down device list updates which are merely useful for the user and causes tests to be flakey: ``` ❌ TestPushSync/Adding_a_push_rule_wakes_up_an_incremental_/sync (10ms) push_test.go:57: no pushrules found in sync response: {"next_batch":"s0_0_0_0_0_1_1_0_1","device_lists":{"changed":["@user-1:hs1"]}} ``` What this does: If a `PerformDeviceCreation` request is coming from registering an account, it does **not** send device list updates, as they are merely useful (no joined rooms, no one to inform) . In all other cases, the behavior is unchanged and device list updates are sent as usual. --- .github/codecov.yaml | 2 +- clientapi/routing/register.go | 2 ++ userapi/api/api.go | 8 ++++++++ userapi/internal/key_api.go | 12 +++++++++--- userapi/internal/user_api.go | 11 ++++++----- 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/.github/codecov.yaml b/.github/codecov.yaml index 78122c990..3462e91ee 100644 --- a/.github/codecov.yaml +++ b/.github/codecov.yaml @@ -7,7 +7,7 @@ coverage: project: default: target: auto - threshold: 0% + threshold: 0.1% base: auto flags: - unittests diff --git a/clientapi/routing/register.go b/clientapi/routing/register.go index 558418a6f..5235e9092 100644 --- a/clientapi/routing/register.go +++ b/clientapi/routing/register.go @@ -630,6 +630,7 @@ func handleGuestRegistration( AccessToken: token, IPAddr: req.RemoteAddr, UserAgent: req.UserAgent(), + FromRegistration: true, }, &devRes) if err != nil { return util.JSONResponse{ @@ -919,6 +920,7 @@ func completeRegistration( DeviceID: deviceID, IPAddr: ipAddr, UserAgent: userAgent, + FromRegistration: true, }, &devRes) if err != nil { return util.JSONResponse{ diff --git a/userapi/api/api.go b/userapi/api/api.go index a0dce9758..d4daec820 100644 --- a/userapi/api/api.go +++ b/userapi/api/api.go @@ -379,6 +379,10 @@ type PerformDeviceCreationRequest struct { // update for this account. Generally the only reason to do this is if the account // is an appservice account. NoDeviceListUpdate bool + + // FromRegistration determines if this request comes from registering a new account + // and is in most cases false. + FromRegistration bool } // PerformDeviceCreationResponse is the response for PerformDeviceCreation @@ -803,6 +807,10 @@ type PerformUploadKeysRequest struct { // itself doesn't change but it's easier to pretend upload new keys and reuse the same code paths. // Without this flag, requests to modify device display names would delete device keys. OnlyDisplayNameUpdates bool + + // FromRegistration is set if this key upload comes right after creating an account + // and determines if we need to inform downstream components. + FromRegistration bool } // PerformUploadKeysResponse is the response to PerformUploadKeys diff --git a/userapi/internal/key_api.go b/userapi/internal/key_api.go index 786a2dcd8..422898c70 100644 --- a/userapi/internal/key_api.go +++ b/userapi/internal/key_api.go @@ -711,9 +711,15 @@ func (a *UserInternalAPI) uploadLocalDeviceKeys(ctx context.Context, req *api.Pe } return } - err = emitDeviceKeyChanges(a.KeyChangeProducer, existingKeys, keysToStore, req.OnlyDisplayNameUpdates) - if err != nil { - util.GetLogger(ctx).Errorf("Failed to emitDeviceKeyChanges: %s", err) + + // If the request does _not_ come right after registering an account + // inform downstream components. However, we're fine with just creating the + // database entries above in other cases. + if !req.FromRegistration { + err = emitDeviceKeyChanges(a.KeyChangeProducer, existingKeys, keysToStore, req.OnlyDisplayNameUpdates) + if err != nil { + util.GetLogger(ctx).Errorf("Failed to emitDeviceKeyChanges: %s", err) + } } } diff --git a/userapi/internal/user_api.go b/userapi/internal/user_api.go index 4e3c2671a..a126dc871 100644 --- a/userapi/internal/user_api.go +++ b/userapi/internal/user_api.go @@ -316,7 +316,7 @@ func (a *UserInternalAPI) PerformDeviceCreation(ctx context.Context, req *api.Pe return nil } // create empty device keys and upload them to trigger device list changes - return a.deviceListUpdate(dev.UserID, []string{dev.ID}) + return a.deviceListUpdate(dev.UserID, []string{dev.ID}, req.FromRegistration) } func (a *UserInternalAPI) PerformDeviceDeletion(ctx context.Context, req *api.PerformDeviceDeletionRequest, res *api.PerformDeviceDeletionResponse) error { @@ -356,10 +356,10 @@ func (a *UserInternalAPI) PerformDeviceDeletion(ctx context.Context, req *api.Pe return fmt.Errorf("a.KeyAPI.PerformDeleteKeys: %w", err) } // create empty device keys and upload them to delete what was once there and trigger device list changes - return a.deviceListUpdate(req.UserID, deletedDeviceIDs) + return a.deviceListUpdate(req.UserID, deletedDeviceIDs, false) } -func (a *UserInternalAPI) deviceListUpdate(userID string, deviceIDs []string) error { +func (a *UserInternalAPI) deviceListUpdate(userID string, deviceIDs []string, fromRegistration bool) error { deviceKeys := make([]api.DeviceKeys, len(deviceIDs)) for i, did := range deviceIDs { deviceKeys[i] = api.DeviceKeys{ @@ -371,8 +371,9 @@ func (a *UserInternalAPI) deviceListUpdate(userID string, deviceIDs []string) er var uploadRes api.PerformUploadKeysResponse if err := a.PerformUploadKeys(context.Background(), &api.PerformUploadKeysRequest{ - UserID: userID, - DeviceKeys: deviceKeys, + UserID: userID, + DeviceKeys: deviceKeys, + FromRegistration: fromRegistration, }, &uploadRes); err != nil { return err }