Make `get_device` return None if the device doesn't exist rather than raising an exception. (#11565)

Co-authored-by: Sean Quah <8349537+squahtx@users.noreply.github.com>
This commit is contained in:
reivilibre 2021-12-13 15:39:43 +00:00 committed by GitHub
parent aa8708ebed
commit e5cdb9e233
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 20 additions and 13 deletions

1
changelog.d/11565.misc Normal file
View File

@ -0,0 +1 @@
Make `get_device` return `None` if the device doesn't exist rather than raising an exception.

View File

@ -997,9 +997,7 @@ class AuthHandler:
# really don't want is active access_tokens without a record of the # really don't want is active access_tokens without a record of the
# device, so we double-check it here. # device, so we double-check it here.
if device_id is not None: if device_id is not None:
try: if await self.store.get_device(user_id, device_id) is None:
await self.store.get_device(user_id, device_id)
except StoreError:
await self.store.delete_access_token(access_token) await self.store.delete_access_token(access_token)
raise StoreError(400, "Login raced against device deletion") raise StoreError(400, "Login raced against device deletion")

View File

@ -106,10 +106,10 @@ class DeviceWorkerHandler:
Raises: Raises:
errors.NotFoundError: if the device was not found errors.NotFoundError: if the device was not found
""" """
try:
device = await self.store.get_device(user_id, device_id) device = await self.store.get_device(user_id, device_id)
except errors.StoreError: if device is None:
raise errors.NotFoundError raise errors.NotFoundError()
ips = await self.store.get_last_client_ip_by_device(user_id, device_id) ips = await self.store.get_last_client_ip_by_device(user_id, device_id)
_update_device_from_client_ips(device, ips) _update_device_from_client_ips(device, ips)
@ -602,6 +602,8 @@ class DeviceHandler(DeviceWorkerHandler):
access_token, device_id access_token, device_id
) )
old_device = await self.store.get_device(user_id, old_device_id) old_device = await self.store.get_device(user_id, old_device_id)
if old_device is None:
raise errors.NotFoundError()
await self.store.update_device(user_id, device_id, old_device["display_name"]) await self.store.update_device(user_id, device_id, old_device["display_name"])
# can't call self.delete_device because that will clobber the # can't call self.delete_device because that will clobber the
# access token so call the storage layer directly # access token so call the storage layer directly

View File

@ -63,6 +63,8 @@ class DeviceRestServlet(RestServlet):
device = await self.device_handler.get_device( device = await self.device_handler.get_device(
target_user.to_string(), device_id target_user.to_string(), device_id
) )
if device is None:
raise NotFoundError("No device found")
return HTTPStatus.OK, device return HTTPStatus.OK, device
async def on_DELETE( async def on_DELETE(

View File

@ -17,6 +17,7 @@ import logging
from typing import TYPE_CHECKING, Tuple from typing import TYPE_CHECKING, Tuple
from synapse.api import errors from synapse.api import errors
from synapse.api.errors import NotFoundError
from synapse.http.server import HttpServer from synapse.http.server import HttpServer
from synapse.http.servlet import ( from synapse.http.servlet import (
RestServlet, RestServlet,
@ -24,10 +25,9 @@ from synapse.http.servlet import (
parse_json_object_from_request, parse_json_object_from_request,
) )
from synapse.http.site import SynapseRequest from synapse.http.site import SynapseRequest
from synapse.rest.client._base import client_patterns, interactive_auth_handler
from synapse.types import JsonDict from synapse.types import JsonDict
from ._base import client_patterns, interactive_auth_handler
if TYPE_CHECKING: if TYPE_CHECKING:
from synapse.server import HomeServer from synapse.server import HomeServer
@ -116,6 +116,8 @@ class DeviceRestServlet(RestServlet):
device = await self.device_handler.get_device( device = await self.device_handler.get_device(
requester.user.to_string(), device_id requester.user.to_string(), device_id
) )
if device is None:
raise NotFoundError("No device found")
return 200, device return 200, device
@interactive_auth_handler @interactive_auth_handler

View File

@ -101,7 +101,9 @@ class DeviceWorkerStore(SQLBaseStore):
"count_devices_by_users", count_devices_by_users_txn, user_ids "count_devices_by_users", count_devices_by_users_txn, user_ids
) )
async def get_device(self, user_id: str, device_id: str) -> Dict[str, Any]: async def get_device(
self, user_id: str, device_id: str
) -> Optional[Dict[str, Any]]:
"""Retrieve a device. Only returns devices that are not marked as """Retrieve a device. Only returns devices that are not marked as
hidden. hidden.
@ -109,15 +111,15 @@ class DeviceWorkerStore(SQLBaseStore):
user_id: The ID of the user which owns the device user_id: The ID of the user which owns the device
device_id: The ID of the device to retrieve device_id: The ID of the device to retrieve
Returns: Returns:
A dict containing the device information A dict containing the device information, or `None` if the device does not
Raises: exist.
StoreError: if the device is not found
""" """
return await self.db_pool.simple_select_one( return await self.db_pool.simple_select_one(
table="devices", table="devices",
keyvalues={"user_id": user_id, "device_id": device_id, "hidden": False}, keyvalues={"user_id": user_id, "device_id": device_id, "hidden": False},
retcols=("user_id", "device_id", "display_name"), retcols=("user_id", "device_id", "display_name"),
desc="get_device", desc="get_device",
allow_none=True,
) )
async def get_devices_by_user(self, user_id: str) -> Dict[str, Dict[str, str]]: async def get_devices_by_user(self, user_id: str) -> Dict[str, Dict[str, str]]: