diff options
author | Kegsay <kegan@matrix.org> | 2020-08-10 12:38:33 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-10 12:38:33 +0100 |
commit | fdabba1851c489d801ea4029bce9dec7d415b2df (patch) | |
tree | 5dcc8e999aafc36a3f6b3d37d93ea12adc180dcb | |
parent | 58998e98746c7d8610fa1e1c3c11de0445393454 (diff) |
bugfix: when a user's key changes, don't notify everyone on the server (#1253)
* bugfix: when a user's key changes, don't notify everyone on the server
Instead just notify the users you share a room with.
* Update whitelist
-rw-r--r-- | syncapi/internal/keychange.go | 27 | ||||
-rw-r--r-- | sytest-whitelist | 2 | ||||
-rw-r--r-- | userapi/internal/api.go | 6 |
3 files changed, 34 insertions, 1 deletions
diff --git a/syncapi/internal/keychange.go b/syncapi/internal/keychange.go index e0379aaf..7623fd9d 100644 --- a/syncapi/internal/keychange.go +++ b/syncapi/internal/keychange.go @@ -95,6 +95,8 @@ func DeviceListCatchup( util.GetLogger(ctx).WithError(queryRes.Error).Error("QueryKeyChanges failed") return hasNew, nil } + // QueryKeyChanges gets ALL users who have changed keys, we want the ones who share rooms with the user. + queryRes.UserIDs = filterSharedUsers(ctx, stateAPI, userID, queryRes.UserIDs) util.GetLogger(ctx).Debugf( "QueryKeyChanges request p=%d,off=%d,to=%d response p=%d off=%d uids=%v", partition, offset, toOffset, queryRes.Partition, queryRes.Offset, queryRes.UserIDs, @@ -217,6 +219,31 @@ func TrackChangedUsers( return changed, left, nil } +func filterSharedUsers( + ctx context.Context, stateAPI currentstateAPI.CurrentStateInternalAPI, userID string, usersWithChangedKeys []string, +) []string { + var result []string + var sharedUsersRes currentstateAPI.QuerySharedUsersResponse + err := stateAPI.QuerySharedUsers(ctx, ¤tstateAPI.QuerySharedUsersRequest{ + UserID: userID, + }, &sharedUsersRes) + if err != nil { + // default to all users so we do needless queries rather than miss some important device update + return usersWithChangedKeys + } + // We forcibly put ourselves in this list because we should be notified about our own device updates + // and if we are in 0 rooms then we don't technically share any room with ourselves so we wouldn't + // be notified about key changes. + sharedUsersRes.UserIDsToCount[userID] = 1 + + for _, uid := range usersWithChangedKeys { + if sharedUsersRes.UserIDsToCount[uid] > 0 { + result = append(result, uid) + } + } + return result +} + func joinedRooms(res *types.Response, userID string) []string { var roomIDs []string for roomID, join := range res.Rooms.Join { diff --git a/sytest-whitelist b/sytest-whitelist index cc49bf38..a726e51e 100644 --- a/sytest-whitelist +++ b/sytest-whitelist @@ -138,7 +138,7 @@ Users receive device_list updates for their own devices Get left notifs for other users in sync and /keys/changes when user leaves Local device key changes get to remote servers Local device key changes get to remote servers with correct prev_id -#Server correctly handles incoming m.device_list_update +Server correctly handles incoming m.device_list_update Can add account data Can add account data to room Can get account data without syncing diff --git a/userapi/internal/api.go b/userapi/internal/api.go index b9d18822..f58c7113 100644 --- a/userapi/internal/api.go +++ b/userapi/internal/api.go @@ -31,6 +31,7 @@ import ( "github.com/matrix-org/dendrite/userapi/storage/devices" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" + "github.com/sirupsen/logrus" ) type UserInternalAPI struct { @@ -98,6 +99,11 @@ func (a *UserInternalAPI) PerformAccountCreation(ctx context.Context, req *api.P return nil } func (a *UserInternalAPI) PerformDeviceCreation(ctx context.Context, req *api.PerformDeviceCreationRequest, res *api.PerformDeviceCreationResponse) error { + util.GetLogger(ctx).WithFields(logrus.Fields{ + "localpart": req.Localpart, + "device_id": req.DeviceID, + "display_name": req.DeviceDisplayName, + }).Info("PerformDeviceCreation") dev, err := a.DeviceDB.CreateDevice(ctx, req.Localpart, req.DeviceID, req.AccessToken, req.DeviceDisplayName) if err != nil { return err |