make black happy
This commit is contained in:
@@ -423,9 +423,7 @@ class DeviceHandler(DeviceWorkerHandler):
|
||||
from_user_id, user_ids
|
||||
)
|
||||
|
||||
self.notifier.on_new_event(
|
||||
"device_list_key", position, users=[from_user_id],
|
||||
)
|
||||
self.notifier.on_new_event("device_list_key", position, users=[from_user_id])
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def on_federation_query_user_devices(self, user_id):
|
||||
|
||||
@@ -227,16 +227,22 @@ class E2eKeysHandler(object):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
yield make_deferred_yieldable(defer.gatherResults([
|
||||
run_in_background(get_cross_signing_key, user_id)
|
||||
for user_id in query.keys()
|
||||
]))
|
||||
yield make_deferred_yieldable(
|
||||
defer.gatherResults(
|
||||
[
|
||||
run_in_background(get_cross_signing_key, user_id)
|
||||
for user_id in query.keys()
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
defer.returnValue({
|
||||
"master": master_keys,
|
||||
"self_signing": self_signing_keys,
|
||||
"user_signing": user_signing_keys,
|
||||
})
|
||||
defer.returnValue(
|
||||
{
|
||||
"master": master_keys,
|
||||
"self_signing": self_signing_keys,
|
||||
"user_signing": user_signing_keys,
|
||||
}
|
||||
)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def query_local_devices(self, query):
|
||||
@@ -455,11 +461,7 @@ class E2eKeysHandler(object):
|
||||
# if there is no master key, then we can't do anything, because all the
|
||||
# other cross-signing keys need to be signed by the master key
|
||||
if not master_key:
|
||||
raise SynapseError(
|
||||
400,
|
||||
"No master key available",
|
||||
Codes.MISSING_PARAM
|
||||
)
|
||||
raise SynapseError(400, "No master key available", Codes.MISSING_PARAM)
|
||||
|
||||
master_key_id, master_verify_key = get_verify_key_from_cross_signing_key(
|
||||
master_key
|
||||
@@ -484,9 +486,7 @@ class E2eKeysHandler(object):
|
||||
# if everything checks out, then store the keys and send notifications
|
||||
deviceids = []
|
||||
if "master_key" in keys:
|
||||
yield self.store.set_e2e_cross_signing_key(
|
||||
user_id, "master", master_key
|
||||
)
|
||||
yield self.store.set_e2e_cross_signing_key(user_id, "master", master_key)
|
||||
deviceids.append(master_verify_key.version)
|
||||
if "self_signing_key" in keys:
|
||||
yield self.store.set_e2e_cross_signing_key(
|
||||
@@ -523,22 +523,20 @@ def _check_cross_signing_key(key, user_id, key_type, signing_key=None):
|
||||
signing_key (VerifyKey): (optional) the signing key that the key should
|
||||
be signed with. If omitted, signatures will not be checked.
|
||||
"""
|
||||
if "user_id" not in key or key["user_id"] != user_id \
|
||||
or "usage" not in key or key_type not in key["usage"]:
|
||||
raise SynapseError(
|
||||
400,
|
||||
("Invalid %s key" % key_type),
|
||||
Codes.INVALID_PARAM
|
||||
)
|
||||
if (
|
||||
"user_id" not in key
|
||||
or key["user_id"] != user_id
|
||||
or "usage" not in key
|
||||
or key_type not in key["usage"]
|
||||
):
|
||||
raise SynapseError(400, ("Invalid %s key" % key_type), Codes.INVALID_PARAM)
|
||||
|
||||
if signing_key:
|
||||
try:
|
||||
verify_signed_json(key, user_id, signing_key)
|
||||
except SignatureVerifyException:
|
||||
raise SynapseError(
|
||||
400,
|
||||
("Invalid signature or %s key" % key_type),
|
||||
Codes.INVALID_SIGNATURE
|
||||
400, ("Invalid signature or %s key" % key_type), Codes.INVALID_SIGNATURE
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -237,6 +237,7 @@ class SigningKeyUploadServlet(RestServlet):
|
||||
{
|
||||
}
|
||||
"""
|
||||
|
||||
PATTERNS = client_patterns("/keys/device_signing/upload$")
|
||||
|
||||
def __init__(self, hs):
|
||||
@@ -258,12 +259,10 @@ class SigningKeyUploadServlet(RestServlet):
|
||||
body = parse_json_object_from_request(request)
|
||||
|
||||
yield self.auth_handler.validate_user_via_ui_auth(
|
||||
requester, body, self.hs.get_ip_from_request(request),
|
||||
requester, body, self.hs.get_ip_from_request(request)
|
||||
)
|
||||
|
||||
result = yield self.e2e_keys_handler.upload_signing_keys_for_user(
|
||||
user_id, body
|
||||
)
|
||||
result = yield self.e2e_keys_handler.upload_signing_keys_for_user(user_id, body)
|
||||
defer.returnValue((200, result))
|
||||
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ class DataStore(
|
||||
"DeviceListStreamChangeCache", device_list_max
|
||||
)
|
||||
self._user_signature_stream_cache = StreamChangeCache(
|
||||
"UserSignatureStreamChangeCache", device_list_max,
|
||||
"UserSignatureStreamChangeCache", device_list_max
|
||||
)
|
||||
self._device_list_federation_stream_cache = StreamChangeCache(
|
||||
"DeviceListFederationStreamChangeCache", device_list_max
|
||||
|
||||
@@ -314,15 +314,19 @@ class DeviceWorkerStore(SQLBaseStore):
|
||||
|
||||
with self._device_list_id_gen.get_next() as stream_id:
|
||||
yield self.runInteraction(
|
||||
"add_user_sig_change_to_streams", self._add_user_signature_change_txn,
|
||||
from_user_id, user_ids, stream_id,
|
||||
"add_user_sig_change_to_streams",
|
||||
self._add_user_signature_change_txn,
|
||||
from_user_id,
|
||||
user_ids,
|
||||
stream_id,
|
||||
)
|
||||
defer.returnValue(stream_id)
|
||||
|
||||
def _add_user_signature_change_txn(self, txn, from_user_id, user_ids, stream_id):
|
||||
txn.call_after(
|
||||
self._user_signature_stream_cache.entity_has_changed,
|
||||
from_user_id, stream_id,
|
||||
from_user_id,
|
||||
stream_id,
|
||||
)
|
||||
self._simple_insert_txn(
|
||||
txn,
|
||||
@@ -614,7 +618,7 @@ class DeviceStore(DeviceWorkerStore, BackgroundUpdateStore):
|
||||
"user_id": user_id,
|
||||
"device_id": device_id,
|
||||
"display_name": initial_device_display_name,
|
||||
"hidden": False
|
||||
"hidden": False,
|
||||
},
|
||||
desc="store_device",
|
||||
or_ignore=True,
|
||||
@@ -624,16 +628,11 @@ class DeviceStore(DeviceWorkerStore, BackgroundUpdateStore):
|
||||
# if the device ID is reserved by something else
|
||||
hidden = yield self._simple_select_one_onecol(
|
||||
"devices",
|
||||
keyvalues={
|
||||
"user_id": user_id,
|
||||
"device_id": device_id
|
||||
},
|
||||
retcol="hidden"
|
||||
keyvalues={"user_id": user_id, "device_id": device_id},
|
||||
retcol="hidden",
|
||||
)
|
||||
if hidden:
|
||||
raise StoreError(
|
||||
400, "The device ID is in use", Codes.FORBIDDEN
|
||||
)
|
||||
raise StoreError(400, "The device ID is in use", Codes.FORBIDDEN)
|
||||
self.device_id_exists_cache.prefill(key, True)
|
||||
defer.returnValue(inserted)
|
||||
except StoreError as e:
|
||||
@@ -686,7 +685,9 @@ class DeviceStore(DeviceWorkerStore, BackgroundUpdateStore):
|
||||
sql = """
|
||||
DELETE FROM devices
|
||||
WHERE user_id = ? AND device_id IN (%s) AND NOT COALESCE(hidden, ?)
|
||||
""" % (",".join("?" for _ in device_ids))
|
||||
""" % (
|
||||
",".join("?" for _ in device_ids)
|
||||
)
|
||||
values = [user_id]
|
||||
values.extend(device_ids)
|
||||
values.append(False)
|
||||
|
||||
@@ -325,9 +325,9 @@ class EndToEndKeyStore(EndToEndKeyWorkerStore, SQLBaseStore):
|
||||
"user_id": user_id,
|
||||
"device_id": pubkey,
|
||||
"display_name": key_type + " signing key",
|
||||
"hidden": True
|
||||
"hidden": True,
|
||||
},
|
||||
desc="store_master_key_device"
|
||||
desc="store_master_key_device",
|
||||
)
|
||||
|
||||
# and finally, store the key itself
|
||||
@@ -337,9 +337,9 @@ class EndToEndKeyStore(EndToEndKeyWorkerStore, SQLBaseStore):
|
||||
"user_id": user_id,
|
||||
"keytype": key_type,
|
||||
"keydata": json.dumps(key),
|
||||
"ts": time.time() * 1000
|
||||
"ts": time.time() * 1000,
|
||||
},
|
||||
desc="store_master_key"
|
||||
desc="store_master_key",
|
||||
)
|
||||
|
||||
def set_e2e_cross_signing_key(self, user_id, key_type, key):
|
||||
@@ -353,7 +353,9 @@ class EndToEndKeyStore(EndToEndKeyWorkerStore, SQLBaseStore):
|
||||
return self.runInteraction(
|
||||
"add_e2e_cross_signing_key",
|
||||
self._set_e2e_cross_signing_key_txn,
|
||||
user_id, key_type, key
|
||||
user_id,
|
||||
key_type,
|
||||
key,
|
||||
)
|
||||
|
||||
def _get_e2e_cross_signing_key_txn(self, txn, user_id, key_type, from_user_id=None):
|
||||
@@ -397,8 +399,9 @@ class EndToEndKeyStore(EndToEndKeyWorkerStore, SQLBaseStore):
|
||||
txn.execute(sql, (from_user_id, user_id, device_id))
|
||||
row = txn.fetchone()
|
||||
if row:
|
||||
key.setdefault("signatures", {}) \
|
||||
.setdefault(from_user_id, {})[row[0]] = row[1]
|
||||
key.setdefault("signatures", {}).setdefault(from_user_id, {})[
|
||||
row[0]
|
||||
] = row[1]
|
||||
|
||||
return key
|
||||
|
||||
@@ -417,7 +420,9 @@ class EndToEndKeyStore(EndToEndKeyWorkerStore, SQLBaseStore):
|
||||
return self.runInteraction(
|
||||
"get_e2e_cross_signing_key",
|
||||
self._get_e2e_cross_signing_key_txn,
|
||||
user_id, key_type, from_user_id
|
||||
user_id,
|
||||
key_type,
|
||||
from_user_id,
|
||||
)
|
||||
|
||||
def store_e2e_cross_signing_signatures(self, user_id, signatures):
|
||||
@@ -434,11 +439,15 @@ class EndToEndKeyStore(EndToEndKeyWorkerStore, SQLBaseStore):
|
||||
"""
|
||||
return self._simple_insert_many(
|
||||
"e2e_cross_signing_signatures",
|
||||
[{"user_id": user_id,
|
||||
"key_id": key_id,
|
||||
"target_user_id": target_user_id,
|
||||
"target_device_id": target_device_id,
|
||||
"signature": signature}
|
||||
for (key_id, target_user_id, target_device_id, signature) in signatures],
|
||||
"add_e2e_signing_key"
|
||||
[
|
||||
{
|
||||
"user_id": user_id,
|
||||
"key_id": key_id,
|
||||
"target_user_id": target_user_id,
|
||||
"target_device_id": target_device_id,
|
||||
"signature": signature,
|
||||
}
|
||||
for (key_id, target_user_id, target_device_id, signature) in signatures
|
||||
],
|
||||
"add_e2e_signing_key",
|
||||
)
|
||||
|
||||
@@ -492,16 +492,10 @@ def get_verify_key_from_cross_signing_key(key_info):
|
||||
"""
|
||||
# make sure that exactly one key is provided
|
||||
if "keys" not in key_info:
|
||||
raise SynapseError(
|
||||
400,
|
||||
"Invalid key"
|
||||
)
|
||||
raise SynapseError(400, "Invalid key")
|
||||
keys = key_info["keys"]
|
||||
if len(keys) != 1:
|
||||
raise SynapseError(
|
||||
400,
|
||||
"Invalid key"
|
||||
)
|
||||
raise SynapseError(400, "Invalid key")
|
||||
# and return that one key
|
||||
for key_id, key_data in keys.items():
|
||||
return (key_id, decode_verify_key_bytes(key_id, decode_base64(key_data)))
|
||||
|
||||
@@ -158,9 +158,8 @@ class E2eKeysHandlerTestCase(unittest.TestCase):
|
||||
"user_id": local_user,
|
||||
"usage": ["master"],
|
||||
"keys": {
|
||||
"ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk":
|
||||
"nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk"
|
||||
}
|
||||
"ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk": "nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk"
|
||||
},
|
||||
}
|
||||
}
|
||||
yield self.handler.upload_signing_keys_for_user(local_user, keys1)
|
||||
@@ -171,22 +170,14 @@ class E2eKeysHandlerTestCase(unittest.TestCase):
|
||||
"user_id": local_user,
|
||||
"usage": ["master"],
|
||||
"keys": {
|
||||
"ed25519:Hq6gL+utB4ET+UvD5ci0kgAwsX6qP/zvf8v6OInU5iw":
|
||||
"Hq6gL+utB4ET+UvD5ci0kgAwsX6qP/zvf8v6OInU5iw"
|
||||
}
|
||||
"ed25519:Hq6gL+utB4ET+UvD5ci0kgAwsX6qP/zvf8v6OInU5iw": "Hq6gL+utB4ET+UvD5ci0kgAwsX6qP/zvf8v6OInU5iw"
|
||||
},
|
||||
}
|
||||
}
|
||||
yield self.handler.upload_signing_keys_for_user(local_user, keys2)
|
||||
|
||||
devices = yield self.handler.query_devices(
|
||||
{"device_keys": {local_user: []}}, 0
|
||||
)
|
||||
self.assertDictEqual(
|
||||
devices["master_keys"],
|
||||
{
|
||||
local_user: keys2["master_key"]
|
||||
},
|
||||
)
|
||||
devices = yield self.handler.query_devices({"device_keys": {local_user: []}}, 0)
|
||||
self.assertDictEqual(devices["master_keys"], {local_user: keys2["master_key"]})
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def test_self_signing_key_doesnt_show_up_as_device(self):
|
||||
@@ -198,9 +189,8 @@ class E2eKeysHandlerTestCase(unittest.TestCase):
|
||||
"user_id": local_user,
|
||||
"usage": ["master"],
|
||||
"keys": {
|
||||
"ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk":
|
||||
"nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk"
|
||||
}
|
||||
"ed25519:nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk": "nqOvzeuGWT/sRx3h7+MHoInYj3Uk2LD/unI9kDYcHwk"
|
||||
},
|
||||
}
|
||||
}
|
||||
yield self.handler.upload_signing_keys_for_user(local_user, keys1)
|
||||
|
||||
Reference in New Issue
Block a user