Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Cross-signing [1/4] -- hidden devices #5759

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5759.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow devices to be marked as hidden, for use by features such as cross-signing.
38 changes: 29 additions & 9 deletions synapse/storage/devices.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright 2016 OpenMarket Ltd
# Copyright 2019 New Vector Ltd
# Copyright 2019 The Matrix.org Foundation C.I.C.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -20,7 +22,7 @@

from twisted.internet import defer

from synapse.api.errors import StoreError
from synapse.api.errors import Codes, StoreError
from synapse.metrics.background_process_metrics import run_as_background_process
from synapse.storage._base import Cache, SQLBaseStore, db_to_json
from synapse.storage.background_updates import BackgroundUpdateStore
Expand All @@ -36,7 +38,8 @@

class DeviceWorkerStore(SQLBaseStore):
def get_device(self, user_id, device_id):
"""Retrieve a device.
"""Retrieve a device. Only returns devices that are not marked as
hidden.

Args:
user_id (str): The ID of the user which owns the device
Expand All @@ -48,14 +51,15 @@ def get_device(self, user_id, device_id):
"""
return self._simple_select_one(
table="devices",
keyvalues={"user_id": user_id, "device_id": device_id},
keyvalues={"user_id": user_id, "device_id": device_id, "hidden": False},
retcols=("user_id", "device_id", "display_name"),
desc="get_device",
)

@defer.inlineCallbacks
def get_devices_by_user(self, user_id):
"""Retrieve all of a user's registered devices.
"""Retrieve all of a user's registered devices. Only returns devices
that are not marked as hidden.

Args:
user_id (str):
Expand All @@ -66,7 +70,7 @@ def get_devices_by_user(self, user_id):
"""
devices = yield self._simple_select_list(
table="devices",
keyvalues={"user_id": user_id},
keyvalues={"user_id": user_id, "hidden": False},
retcols=("user_id", "device_id", "display_name"),
desc="get_devices_by_user",
)
Expand Down Expand Up @@ -540,6 +544,8 @@ def store_device(self, user_id, device_id, initial_device_display_name):
Returns:
defer.Deferred: boolean whether the device was inserted or an
existing device existed with that ID.
Raises:
StoreError: if the device is already in use
"""
key = (user_id, device_id)
if self.device_id_exists_cache.get(key, None):
Expand All @@ -552,12 +558,25 @@ def store_device(self, user_id, device_id, initial_device_display_name):
"user_id": user_id,
"device_id": device_id,
"display_name": initial_device_display_name,
"hidden": False,
},
desc="store_device",
or_ignore=True,
)
if not inserted:
# if the device already exists, check if it's a real device, or
# 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",
)
if hidden:
raise StoreError(400, "The device ID is in use", Codes.FORBIDDEN)
self.device_id_exists_cache.prefill(key, True)
return inserted
except StoreError:
raise
except Exception as e:
logger.error(
"store_device with device_id=%s(%r) user_id=%s(%r)"
Expand All @@ -584,7 +603,7 @@ def delete_device(self, user_id, device_id):
"""
yield self._simple_delete_one(
table="devices",
keyvalues={"user_id": user_id, "device_id": device_id},
keyvalues={"user_id": user_id, "device_id": device_id, "hidden": False},
desc="delete_device",
)

Expand All @@ -604,14 +623,15 @@ def delete_devices(self, user_id, device_ids):
table="devices",
column="device_id",
iterable=device_ids,
keyvalues={"user_id": user_id},
keyvalues={"user_id": user_id, "hidden": False},
desc="delete_devices",
)
for device_id in device_ids:
self.device_id_exists_cache.invalidate((user_id, device_id))

def update_device(self, user_id, device_id, new_display_name=None):
"""Update a device.
"""Update a device. Only updates the device if it is not marked as
hidden.

Args:
user_id (str): The ID of the user which owns the device
Expand All @@ -630,7 +650,7 @@ def update_device(self, user_id, device_id, new_display_name=None):
return defer.succeed(None)
return self._simple_update_one(
table="devices",
keyvalues={"user_id": user_id, "device_id": device_id},
keyvalues={"user_id": user_id, "device_id": device_id, "hidden": False},
updatevalues=updates,
desc="update_device",
)
Expand Down
2 changes: 1 addition & 1 deletion synapse/storage/end_to_end_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def _get_e2e_device_keys_txn(
" k.key_json"
" FROM devices d"
" %s JOIN e2e_device_keys_json k USING (user_id, device_id)"
" WHERE %s"
" WHERE %s AND NOT d.hidden"
) % (
"LEFT" if include_all_devices else "INNER",
" OR ".join("(" + q + ")" for q in query_clauses),
Expand Down
18 changes: 18 additions & 0 deletions synapse/storage/schema/delta/56/hidden_devices.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

-- device list needs to know which ones are "real" devices, and which ones are
-- just used to avoid collisions
ALTER TABLE devices ADD COLUMN hidden BOOLEAN DEFAULT FALSE;