send 404 as http-status when filter-id is unknown to the server (#2380)

This fixed the weirdness of 400 vs 404 as http status code in the case
the filter id is not known by the server.
As e.g. matrix-js-sdk expects 404 to catch this situation this leads
to unwanted behaviour.
This commit is contained in:
krombel 2019-10-10 13:59:55 +02:00 committed by Richard van der Hoff
parent 0aee490013
commit 2efd050c9d
4 changed files with 33 additions and 23 deletions

1
changelog.d/2380.bugfix Normal file
View File

@ -0,0 +1 @@
Return an HTTP 404 instead of 400 when requesting a filter by ID that is unknown to the server. Thanks to @krombel for contributing this!

View File

@ -17,7 +17,7 @@ import logging
from twisted.internet import defer from twisted.internet import defer
from synapse.api.errors import AuthError, Codes, StoreError, SynapseError from synapse.api.errors import AuthError, NotFoundError, StoreError, SynapseError
from synapse.http.servlet import RestServlet, parse_json_object_from_request from synapse.http.servlet import RestServlet, parse_json_object_from_request
from synapse.types import UserID from synapse.types import UserID
@ -52,13 +52,15 @@ class GetFilterRestServlet(RestServlet):
raise SynapseError(400, "Invalid filter_id") raise SynapseError(400, "Invalid filter_id")
try: try:
filter = yield self.filtering.get_user_filter( filter_collection = yield self.filtering.get_user_filter(
user_localpart=target_user.localpart, filter_id=filter_id user_localpart=target_user.localpart, filter_id=filter_id
) )
except StoreError as e:
if e.code != 404:
raise
raise NotFoundError("No such filter")
return 200, filter.get_filter_json() return 200, filter_collection.get_filter_json()
except (KeyError, StoreError):
raise SynapseError(400, "No such filter", errcode=Codes.NOT_FOUND)
class CreateFilterRestServlet(RestServlet): class CreateFilterRestServlet(RestServlet):

View File

@ -21,7 +21,7 @@ from canonicaljson import json
from twisted.internet import defer from twisted.internet import defer
from synapse.api.constants import PresenceState from synapse.api.constants import PresenceState
from synapse.api.errors import SynapseError from synapse.api.errors import Codes, StoreError, SynapseError
from synapse.api.filtering import DEFAULT_FILTER_COLLECTION, FilterCollection from synapse.api.filtering import DEFAULT_FILTER_COLLECTION, FilterCollection
from synapse.events.utils import ( from synapse.events.utils import (
format_event_for_client_v2_without_room_id, format_event_for_client_v2_without_room_id,
@ -119,8 +119,9 @@ class SyncRestServlet(RestServlet):
request_key = (user, timeout, since, filter_id, full_state, device_id) request_key = (user, timeout, since, filter_id, full_state, device_id)
if filter_id: if filter_id is None:
if filter_id.startswith("{"): filter_collection = DEFAULT_FILTER_COLLECTION
elif filter_id.startswith("{"):
try: try:
filter_object = json.loads(filter_id) filter_object = json.loads(filter_id)
set_timeline_upper_limit( set_timeline_upper_limit(
@ -129,15 +130,21 @@ class SyncRestServlet(RestServlet):
except Exception: except Exception:
raise SynapseError(400, "Invalid filter JSON") raise SynapseError(400, "Invalid filter JSON")
self.filtering.check_valid_filter(filter_object) self.filtering.check_valid_filter(filter_object)
filter = FilterCollection(filter_object) filter_collection = FilterCollection(filter_object)
else: else:
filter = yield self.filtering.get_user_filter(user.localpart, filter_id) try:
else: filter_collection = yield self.filtering.get_user_filter(
filter = DEFAULT_FILTER_COLLECTION user.localpart, filter_id
)
except StoreError as err:
if err.code != 404:
raise
# fix up the description and errcode to be more useful
raise SynapseError(400, "No such filter", errcode=Codes.INVALID_PARAM)
sync_config = SyncConfig( sync_config = SyncConfig(
user=user, user=user,
filter_collection=filter, filter_collection=filter_collection,
is_guest=requester.is_guest, is_guest=requester.is_guest,
request_key=request_key, request_key=request_key,
device_id=device_id, device_id=device_id,
@ -171,7 +178,7 @@ class SyncRestServlet(RestServlet):
time_now = self.clock.time_msec() time_now = self.clock.time_msec()
response_content = yield self.encode_response( response_content = yield self.encode_response(
time_now, sync_result, requester.access_token_id, filter time_now, sync_result, requester.access_token_id, filter_collection
) )
return 200, response_content return 200, response_content

View File

@ -92,7 +92,7 @@ class FilterTestCase(unittest.HomeserverTestCase):
) )
self.render(request) self.render(request)
self.assertEqual(channel.result["code"], b"400") self.assertEqual(channel.result["code"], b"404")
self.assertEquals(channel.json_body["errcode"], Codes.NOT_FOUND) self.assertEquals(channel.json_body["errcode"], Codes.NOT_FOUND)
# Currently invalid params do not have an appropriate errcode # Currently invalid params do not have an appropriate errcode