From 37b8a71f1086b394874fb13ee63dcbeb2b2334d2 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Mon, 26 Jan 2015 15:27:40 +0000 Subject: Initial trivial REST test of v2_alpha filter API --- tests/rest/client/v2_alpha/test_filter.py | 74 +++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tests/rest/client/v2_alpha/test_filter.py (limited to 'tests/rest') diff --git a/tests/rest/client/v2_alpha/test_filter.py b/tests/rest/client/v2_alpha/test_filter.py new file mode 100644 index 0000000000..1d1273ab9a --- /dev/null +++ b/tests/rest/client/v2_alpha/test_filter.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 OpenMarket 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. + +from tests import unittest +from twisted.internet import defer + +from mock import Mock + +from ....utils import MockHttpResource, MockKey + +from synapse.server import HomeServer +from synapse.rest.client.v2_alpha import filter +from synapse.types import UserID + + +myid = "@apple:test" +PATH_PREFIX = "/_matrix/client/v2_alpha" + + +class FilterTestCase(unittest.TestCase): + + def setUp(self): + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) + + mock_config = Mock() + mock_config.signing_key = [MockKey()] + + hs = HomeServer("test", + db_pool=None, + datastore=Mock(spec=[ + "insert_client_ip", + ]), + http_client=None, + resource_for_client=self.mock_resource, + resource_for_federation=self.mock_resource, + config=mock_config, + ) + + def _get_user_by_token(token=None): + return { + "user": UserID.from_string(myid), + "admin": False, + "device_id": None, + } + hs.get_auth().get_user_by_token = _get_user_by_token + + filter.register_servlets(hs, self.mock_resource) + + @defer.inlineCallbacks + def test_filter(self): + (code, response) = yield self.mock_resource.trigger("POST", + "/user/%s/filter" % (myid), + '{"type": ["m.*"]}' + ) + self.assertEquals(200, code) + self.assertEquals({"filter_id": "0"}, response) + + (code, response) = yield self.mock_resource.trigger("GET", + "/user/%s/filter/0" % (myid), None + ) + self.assertEquals(200, code) + self.assertEquals({"type": ["m.*"]}, response) -- cgit 1.4.1 From 39c1892b22012e20ce6f43e92b01f6fad780081d Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 27 Jan 2015 13:03:31 +0000 Subject: Minor changes to v2_alpha filter REST test to allow the setUp method to be shareable --- tests/rest/client/v2_alpha/test_filter.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'tests/rest') diff --git a/tests/rest/client/v2_alpha/test_filter.py b/tests/rest/client/v2_alpha/test_filter.py index 1d1273ab9a..91b19e88ff 100644 --- a/tests/rest/client/v2_alpha/test_filter.py +++ b/tests/rest/client/v2_alpha/test_filter.py @@ -25,11 +25,12 @@ from synapse.rest.client.v2_alpha import filter from synapse.types import UserID -myid = "@apple:test" PATH_PREFIX = "/_matrix/client/v2_alpha" class FilterTestCase(unittest.TestCase): + USER_ID = "@apple:test" + TO_REGISTER = [filter] def setUp(self): self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) @@ -50,25 +51,26 @@ class FilterTestCase(unittest.TestCase): def _get_user_by_token(token=None): return { - "user": UserID.from_string(myid), + "user": UserID.from_string(self.USER_ID), "admin": False, "device_id": None, } hs.get_auth().get_user_by_token = _get_user_by_token - filter.register_servlets(hs, self.mock_resource) + for r in self.TO_REGISTER: + r.register_servlets(hs, self.mock_resource) @defer.inlineCallbacks def test_filter(self): (code, response) = yield self.mock_resource.trigger("POST", - "/user/%s/filter" % (myid), + "/user/%s/filter" % (self.USER_ID), '{"type": ["m.*"]}' ) self.assertEquals(200, code) self.assertEquals({"filter_id": "0"}, response) (code, response) = yield self.mock_resource.trigger("GET", - "/user/%s/filter/0" % (myid), None + "/user/%s/filter/0" % (self.USER_ID), None ) self.assertEquals(200, code) self.assertEquals({"type": ["m.*"]}, response) -- cgit 1.4.1 From f9958f34043bf4fdf5923f471f193b40188e67bb Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 27 Jan 2015 13:17:25 +0000 Subject: Use new V2AlphaRestTestCase --- tests/rest/client/v2_alpha/test_filter.py | 40 ++----------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) (limited to 'tests/rest') diff --git a/tests/rest/client/v2_alpha/test_filter.py b/tests/rest/client/v2_alpha/test_filter.py index 91b19e88ff..8629a1aed6 100644 --- a/tests/rest/client/v2_alpha/test_filter.py +++ b/tests/rest/client/v2_alpha/test_filter.py @@ -13,53 +13,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -from tests import unittest from twisted.internet import defer -from mock import Mock +from . import V2AlphaRestTestCase -from ....utils import MockHttpResource, MockKey - -from synapse.server import HomeServer from synapse.rest.client.v2_alpha import filter -from synapse.types import UserID - - -PATH_PREFIX = "/_matrix/client/v2_alpha" -class FilterTestCase(unittest.TestCase): +class FilterTestCase(V2AlphaRestTestCase): USER_ID = "@apple:test" TO_REGISTER = [filter] - def setUp(self): - self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) - - mock_config = Mock() - mock_config.signing_key = [MockKey()] - - hs = HomeServer("test", - db_pool=None, - datastore=Mock(spec=[ - "insert_client_ip", - ]), - http_client=None, - resource_for_client=self.mock_resource, - resource_for_federation=self.mock_resource, - config=mock_config, - ) - - def _get_user_by_token(token=None): - return { - "user": UserID.from_string(self.USER_ID), - "admin": False, - "device_id": None, - } - hs.get_auth().get_user_by_token = _get_user_by_token - - for r in self.TO_REGISTER: - r.register_servlets(hs, self.mock_resource) - @defer.inlineCallbacks def test_filter(self): (code, response) = yield self.mock_resource.trigger("POST", -- cgit 1.4.1 From 54e513b4e6b5c644b9a2aeb02cef8258e87ae26a Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 27 Jan 2015 17:48:13 +0000 Subject: Move storage of user filters into real datastore layer; now have to mock it out in the REST-level tests --- synapse/api/filtering.py | 27 +++--------------- synapse/storage/__init__.py | 3 +- synapse/storage/filtering.py | 46 +++++++++++++++++++++++++++++++ tests/rest/client/v2_alpha/__init__.py | 9 ++++-- tests/rest/client/v2_alpha/test_filter.py | 21 ++++++++++++++ 5 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 synapse/storage/filtering.py (limited to 'tests/rest') diff --git a/synapse/api/filtering.py b/synapse/api/filtering.py index 014e2e1fc9..20b6951d47 100644 --- a/synapse/api/filtering.py +++ b/synapse/api/filtering.py @@ -16,37 +16,18 @@ from twisted.internet import defer -# TODO(paul) -_filters_for_user = {} - - class Filtering(object): def __init__(self, hs): super(Filtering, self).__init__() - self.hs = hs + self.store = hs.get_datastore() - @defer.inlineCallbacks def get_user_filter(self, user_localpart, filter_id): - filters = _filters_for_user.get(user_localpart, None) - - if not filters or filter_id >= len(filters): - raise KeyError() + return self.store.get_user_filter(user_localpart, filter_id) - # trivial yield to make it a generator so d.iC works - yield - defer.returnValue(filters[filter_id]) - - @defer.inlineCallbacks def add_user_filter(self, user_localpart, definition): - filters = _filters_for_user.setdefault(user_localpart, []) - - filter_id = len(filters) - filters.append(definition) - - # trivial yield, see above - yield - defer.returnValue(filter_id) + # TODO(paul): implement sanity checking of the definition + return self.store.add_user_filter(user_localpart, definition) # TODO(paul): surely we should probably add a delete_user_filter or # replace_user_filter at some point? There's no REST API specified for diff --git a/synapse/storage/__init__.py b/synapse/storage/__init__.py index 4beb951b9f..efa63031bd 100644 --- a/synapse/storage/__init__.py +++ b/synapse/storage/__init__.py @@ -30,9 +30,9 @@ from .transactions import TransactionStore from .keys import KeyStore from .event_federation import EventFederationStore from .media_repository import MediaRepositoryStore - from .state import StateStore from .signatures import SignatureStore +from .filtering import FilteringStore from syutil.base64util import decode_base64 from syutil.jsonutil import encode_canonical_json @@ -82,6 +82,7 @@ class DataStore(RoomMemberStore, RoomStore, DirectoryStore, KeyStore, StateStore, SignatureStore, EventFederationStore, MediaRepositoryStore, + FilteringStore, ): def __init__(self, hs): diff --git a/synapse/storage/filtering.py b/synapse/storage/filtering.py new file mode 100644 index 0000000000..18e0e7c298 --- /dev/null +++ b/synapse/storage/filtering.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2015 OpenMarket 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. + +from twisted.internet import defer + +from ._base import SQLBaseStore + + +# TODO(paul) +_filters_for_user = {} + + +class FilteringStore(SQLBaseStore): + @defer.inlineCallbacks + def get_user_filter(self, user_localpart, filter_id): + filters = _filters_for_user.get(user_localpart, None) + + if not filters or filter_id >= len(filters): + raise KeyError() + + # trivial yield to make it a generator so d.iC works + yield + defer.returnValue(filters[filter_id]) + + @defer.inlineCallbacks + def add_user_filter(self, user_localpart, definition): + filters = _filters_for_user.setdefault(user_localpart, []) + + filter_id = len(filters) + filters.append(definition) + + # trivial yield, see above + yield + defer.returnValue(filter_id) diff --git a/tests/rest/client/v2_alpha/__init__.py b/tests/rest/client/v2_alpha/__init__.py index f59745e13c..3fe62d5ac6 100644 --- a/tests/rest/client/v2_alpha/__init__.py +++ b/tests/rest/client/v2_alpha/__init__.py @@ -39,9 +39,7 @@ class V2AlphaRestTestCase(unittest.TestCase): hs = HomeServer("test", db_pool=None, - datastore=Mock(spec=[ - "insert_client_ip", - ]), + datastore=self.make_datastore_mock(), http_client=None, resource_for_client=self.mock_resource, resource_for_federation=self.mock_resource, @@ -58,3 +56,8 @@ class V2AlphaRestTestCase(unittest.TestCase): for r in self.TO_REGISTER: r.register_servlets(hs, self.mock_resource) + + def make_datastore_mock(self): + return Mock(spec=[ + "insert_client_ip", + ]) diff --git a/tests/rest/client/v2_alpha/test_filter.py b/tests/rest/client/v2_alpha/test_filter.py index 8629a1aed6..1add727e6b 100644 --- a/tests/rest/client/v2_alpha/test_filter.py +++ b/tests/rest/client/v2_alpha/test_filter.py @@ -15,6 +15,8 @@ from twisted.internet import defer +from mock import Mock + from . import V2AlphaRestTestCase from synapse.rest.client.v2_alpha import filter @@ -24,6 +26,25 @@ class FilterTestCase(V2AlphaRestTestCase): USER_ID = "@apple:test" TO_REGISTER = [filter] + def make_datastore_mock(self): + datastore = super(FilterTestCase, self).make_datastore_mock() + + self._user_filters = {} + + def add_user_filter(user_localpart, definition): + filters = self._user_filters.setdefault(user_localpart, []) + filter_id = len(filters) + filters.append(definition) + return defer.succeed(filter_id) + datastore.add_user_filter = add_user_filter + + def get_user_filter(user_localpart, filter_id): + filters = self._user_filters[user_localpart] + return defer.succeed(filters[filter_id]) + datastore.get_user_filter = get_user_filter + + return datastore + @defer.inlineCallbacks def test_filter(self): (code, response) = yield self.mock_resource.trigger("POST", -- cgit 1.4.1 From 0c14a699bb4e103a1845b0808821138cfea99552 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Tue, 27 Jan 2015 18:07:21 +0000 Subject: More unit-testing of REST errors --- tests/rest/client/v2_alpha/test_filter.py | 36 ++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'tests/rest') diff --git a/tests/rest/client/v2_alpha/test_filter.py b/tests/rest/client/v2_alpha/test_filter.py index 1add727e6b..80ddabf818 100644 --- a/tests/rest/client/v2_alpha/test_filter.py +++ b/tests/rest/client/v2_alpha/test_filter.py @@ -21,6 +21,8 @@ from . import V2AlphaRestTestCase from synapse.rest.client.v2_alpha import filter +from synapse.api.errors import StoreError + class FilterTestCase(V2AlphaRestTestCase): USER_ID = "@apple:test" @@ -39,14 +41,18 @@ class FilterTestCase(V2AlphaRestTestCase): datastore.add_user_filter = add_user_filter def get_user_filter(user_localpart, filter_id): + if user_localpart not in self._user_filters: + raise StoreError(404, "No user") filters = self._user_filters[user_localpart] + if filter_id >= len(filters): + raise StoreError(404, "No filter") return defer.succeed(filters[filter_id]) datastore.get_user_filter = get_user_filter return datastore @defer.inlineCallbacks - def test_filter(self): + def test_add_filter(self): (code, response) = yield self.mock_resource.trigger("POST", "/user/%s/filter" % (self.USER_ID), '{"type": ["m.*"]}' @@ -54,8 +60,36 @@ class FilterTestCase(V2AlphaRestTestCase): self.assertEquals(200, code) self.assertEquals({"filter_id": "0"}, response) + self.assertIn("apple", self._user_filters) + self.assertEquals(len(self._user_filters["apple"]), 1) + self.assertEquals({"type": ["m.*"]}, self._user_filters["apple"][0]) + + @defer.inlineCallbacks + def test_get_filter(self): + self._user_filters["apple"] = [ + {"type": ["m.*"]} + ] + (code, response) = yield self.mock_resource.trigger("GET", "/user/%s/filter/0" % (self.USER_ID), None ) self.assertEquals(200, code) self.assertEquals({"type": ["m.*"]}, response) + + @defer.inlineCallbacks + def test_get_filter_no_id(self): + self._user_filters["apple"] = [ + {"type": ["m.*"]} + ] + + (code, response) = yield self.mock_resource.trigger("GET", + "/user/%s/filter/2" % (self.USER_ID), None + ) + self.assertEquals(404, code) + + @defer.inlineCallbacks + def test_get_filter_no_user(self): + (code, response) = yield self.mock_resource.trigger("GET", + "/user/%s/filter/0" % (self.USER_ID), None + ) + self.assertEquals(404, code) -- cgit 1.4.1 From 33391db5f8d9d0d365607ca50ba59ce72c90cda0 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Thu, 29 Jan 2015 15:54:54 +0000 Subject: Merge in auth changes from develop --- synapse/rest/client/v2_alpha/filter.py | 4 ++-- tests/rest/client/v2_alpha/__init__.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'tests/rest') diff --git a/synapse/rest/client/v2_alpha/filter.py b/synapse/rest/client/v2_alpha/filter.py index 81a3e95155..cee06ccaca 100644 --- a/synapse/rest/client/v2_alpha/filter.py +++ b/synapse/rest/client/v2_alpha/filter.py @@ -40,7 +40,7 @@ class GetFilterRestServlet(RestServlet): @defer.inlineCallbacks def on_GET(self, request, user_id, filter_id): target_user = UserID.from_string(user_id) - auth_user = yield self.auth.get_user_by_req(request) + auth_user, client = yield self.auth.get_user_by_req(request) if target_user != auth_user: raise AuthError(403, "Cannot get filters for other users") @@ -76,7 +76,7 @@ class CreateFilterRestServlet(RestServlet): @defer.inlineCallbacks def on_POST(self, request, user_id): target_user = UserID.from_string(user_id) - auth_user = yield self.auth.get_user_by_req(request) + auth_user, client = yield self.auth.get_user_by_req(request) if target_user != auth_user: raise AuthError(403, "Cannot create filters for other users") diff --git a/tests/rest/client/v2_alpha/__init__.py b/tests/rest/client/v2_alpha/__init__.py index 3fe62d5ac6..fa70575c57 100644 --- a/tests/rest/client/v2_alpha/__init__.py +++ b/tests/rest/client/v2_alpha/__init__.py @@ -51,6 +51,7 @@ class V2AlphaRestTestCase(unittest.TestCase): "user": UserID.from_string(self.USER_ID), "admin": False, "device_id": None, + "token_id": 1, } hs.get_auth().get_user_by_token = _get_user_by_token -- cgit 1.4.1