aboutsummaryrefslogtreecommitdiff
path: root/keyserver
diff options
context:
space:
mode:
authorKegsay <kegan@matrix.org>2020-07-30 18:00:56 +0100
committerGitHub <noreply@github.com>2020-07-30 18:00:56 +0100
commita7e67e65a8662387f1a5ba6860698743f9dbd60f (patch)
tree90714c83c20fee10ee3c758f3ba00b7f9eee6d1c /keyserver
parent292a9ddd82a7cfc64ed43b70454040fb009601a7 (diff)
Notify clients when devices are deleted (#1233)
* Recheck device lists when join/leave events come in * Add PerformDeviceDeletion * Notify clients when devices are deleted * Unbreak things * Remove debug logging
Diffstat (limited to 'keyserver')
-rw-r--r--keyserver/api/api.go4
-rw-r--r--keyserver/internal/internal.go13
-rw-r--r--keyserver/inthttp/client.go5
-rw-r--r--keyserver/keyserver.go4
-rw-r--r--keyserver/producers/keychange.go9
-rw-r--r--keyserver/storage/interface.go3
6 files changed, 29 insertions, 9 deletions
diff --git a/keyserver/api/api.go b/keyserver/api/api.go
index 98bcd944..6795498f 100644
--- a/keyserver/api/api.go
+++ b/keyserver/api/api.go
@@ -19,9 +19,13 @@ import (
"encoding/json"
"strings"
"time"
+
+ userapi "github.com/matrix-org/dendrite/userapi/api"
)
type KeyInternalAPI interface {
+ // SetUserAPI assigns a user API to query when extracting device names.
+ SetUserAPI(i userapi.UserInternalAPI)
PerformUploadKeys(ctx context.Context, req *PerformUploadKeysRequest, res *PerformUploadKeysResponse)
// PerformClaimKeys claims one-time keys for use in pre-key messages
PerformClaimKeys(ctx context.Context, req *PerformClaimKeysRequest, res *PerformClaimKeysResponse)
diff --git a/keyserver/internal/internal.go b/keyserver/internal/internal.go
index 70371353..480d1084 100644
--- a/keyserver/internal/internal.go
+++ b/keyserver/internal/internal.go
@@ -40,6 +40,10 @@ type KeyInternalAPI struct {
Producer *producers.KeyChange
}
+func (a *KeyInternalAPI) SetUserAPI(i userapi.UserInternalAPI) {
+ a.UserAPI = i
+}
+
func (a *KeyInternalAPI) QueryKeyChanges(ctx context.Context, req *api.QueryKeyChangesRequest, res *api.QueryKeyChangesResponse) {
if req.Partition < 0 {
req.Partition = a.Producer.DefaultPartition()
@@ -272,6 +276,10 @@ func (a *KeyInternalAPI) uploadDeviceKeys(ctx context.Context, req *api.PerformU
var keysToStore []api.DeviceKeys
// assert that the user ID / device ID are not lying for each key
for _, key := range req.DeviceKeys {
+ if len(key.KeyJSON) == 0 {
+ keysToStore = append(keysToStore, key)
+ continue // deleted keys don't need sanity checking
+ }
gotUserID := gjson.GetBytes(key.KeyJSON, "user_id").Str
gotDeviceID := gjson.GetBytes(key.KeyJSON, "device_id").Str
if gotUserID == key.UserID && gotDeviceID == key.DeviceID {
@@ -286,6 +294,7 @@ func (a *KeyInternalAPI) uploadDeviceKeys(ctx context.Context, req *api.PerformU
),
})
}
+
// get existing device keys so we can check for changes
existingKeys := make([]api.DeviceKeys, len(keysToStore))
for i := range keysToStore {
@@ -358,7 +367,9 @@ func (a *KeyInternalAPI) emitDeviceKeyChanges(existing, new []api.DeviceKeys) er
for _, newKey := range new {
exists := false
for _, existingKey := range existing {
- if bytes.Equal(existingKey.KeyJSON, newKey.KeyJSON) {
+ // Do not treat the absence of keys as equal, or else we will not emit key changes
+ // when users delete devices which never had a key to begin with as both KeyJSONs are nil.
+ if bytes.Equal(existingKey.KeyJSON, newKey.KeyJSON) && len(existingKey.KeyJSON) > 0 {
exists = true
break
}
diff --git a/keyserver/inthttp/client.go b/keyserver/inthttp/client.go
index cd9cf70d..3f9690b5 100644
--- a/keyserver/inthttp/client.go
+++ b/keyserver/inthttp/client.go
@@ -21,6 +21,7 @@ import (
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/keyserver/api"
+ userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/opentracing/opentracing-go"
)
@@ -52,6 +53,10 @@ type httpKeyInternalAPI struct {
httpClient *http.Client
}
+func (h *httpKeyInternalAPI) SetUserAPI(i userapi.UserInternalAPI) {
+ // no-op: doesn't need it
+}
+
func (h *httpKeyInternalAPI) PerformClaimKeys(
ctx context.Context,
request *api.PerformClaimKeysRequest,
diff --git a/keyserver/keyserver.go b/keyserver/keyserver.go
index c748d7ce..36bedf34 100644
--- a/keyserver/keyserver.go
+++ b/keyserver/keyserver.go
@@ -23,7 +23,6 @@ import (
"github.com/matrix-org/dendrite/keyserver/inthttp"
"github.com/matrix-org/dendrite/keyserver/producers"
"github.com/matrix-org/dendrite/keyserver/storage"
- userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
"github.com/sirupsen/logrus"
)
@@ -37,7 +36,7 @@ func AddInternalRoutes(router *mux.Router, intAPI api.KeyInternalAPI) {
// NewInternalAPI returns a concerete implementation of the internal API. Callers
// can call functions directly on the returned API or via an HTTP interface using AddInternalRoutes.
func NewInternalAPI(
- cfg *config.Dendrite, fedClient *gomatrixserverlib.FederationClient, userAPI userapi.UserInternalAPI, producer sarama.SyncProducer,
+ cfg *config.Dendrite, fedClient *gomatrixserverlib.FederationClient, producer sarama.SyncProducer,
) api.KeyInternalAPI {
db, err := storage.NewDatabase(
string(cfg.Database.E2EKey),
@@ -55,7 +54,6 @@ func NewInternalAPI(
DB: db,
ThisServer: cfg.Matrix.ServerName,
FedClient: fedClient,
- UserAPI: userAPI,
Producer: keyChangeProducer,
}
}
diff --git a/keyserver/producers/keychange.go b/keyserver/producers/keychange.go
index c51d9f55..6035b67b 100644
--- a/keyserver/producers/keychange.go
+++ b/keyserver/producers/keychange.go
@@ -63,10 +63,11 @@ func (p *KeyChange) ProduceKeyChanges(keys []api.DeviceKeys) error {
return err
}
logrus.WithFields(logrus.Fields{
- "user_id": key.UserID,
- "device_id": key.DeviceID,
- "partition": partition,
- "offset": offset,
+ "user_id": key.UserID,
+ "device_id": key.DeviceID,
+ "partition": partition,
+ "offset": offset,
+ "len_key_bytes": len(key.KeyJSON),
}).Infof("Produced to key change topic '%s'", p.Topic)
}
return nil
diff --git a/keyserver/storage/interface.go b/keyserver/storage/interface.go
index 7a4fce6f..fade7522 100644
--- a/keyserver/storage/interface.go
+++ b/keyserver/storage/interface.go
@@ -32,7 +32,8 @@ type Database interface {
// DeviceKeysJSON populates the KeyJSON for the given keys. If any proided `keys` have a `KeyJSON` already then it will be replaced.
DeviceKeysJSON(ctx context.Context, keys []api.DeviceKeys) error
- // StoreDeviceKeys persists the given keys. Keys with the same user ID and device ID will be replaced.
+ // StoreDeviceKeys persists the given keys. Keys with the same user ID and device ID will be replaced. An empty KeyJSON removes the key
+ // for this (user, device).
// Returns an error if there was a problem storing the keys.
StoreDeviceKeys(ctx context.Context, keys []api.DeviceKeys) error