From 03b11034b000ee55cc7b7a8976c1d722b32cf80b Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 13 Aug 2018 17:09:11 +1000 Subject: [PATCH 01/25] some way of running docker to run postgresql --- Dockerfile-pgtests | 8 ++++++++ docker_run_pg_tests.sh | 10 ++++++++++ test_postgresql.sh | 3 +++ 3 files changed, 21 insertions(+) create mode 100644 Dockerfile-pgtests create mode 100755 docker_run_pg_tests.sh create mode 100755 test_postgresql.sh diff --git a/Dockerfile-pgtests b/Dockerfile-pgtests new file mode 100644 index 000000000000..4cd8d480457f --- /dev/null +++ b/Dockerfile-pgtests @@ -0,0 +1,8 @@ +FROM matrixdotorg/sytest:latest + +RUN apt-get -qq install -y python python-dev python-pip + +RUN pip install tox + +ADD docker_run_pg_tests.sh /pg_tests.sh +ENTRYPOINT /pg_tests.sh diff --git a/docker_run_pg_tests.sh b/docker_run_pg_tests.sh new file mode 100755 index 000000000000..3577e66cb8dd --- /dev/null +++ b/docker_run_pg_tests.sh @@ -0,0 +1,10 @@ +export PGDATA=/var/lib/postgresql/data +export PGUSER=postgres + +# Initialise the database files and start the database +su -c '/usr/lib/postgresql/9.6/bin/initdb -E "UTF-8" --lc-collate="en_US.UTF-8" --lc-ctype="en_US.UTF-8" --username=postgres' postgres +su -c '/usr/lib/postgresql/9.6/bin/pg_ctl -w -D /var/lib/postgresql/data start' postgres + +cd /src +export TRIAL_FLAGS="-j 4" +tox -e py27-postgres diff --git a/test_postgresql.sh b/test_postgresql.sh new file mode 100755 index 000000000000..a2e88aabb0dc --- /dev/null +++ b/test_postgresql.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +docker build . -f Dockerfile-pgtests -t synapsepgtests +docker run --rm -it -v $(pwd)\:/src synapsepgtests From 25a3b5ed53754084e3d7ed4eae7c84539908232c Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 13 Aug 2018 22:17:59 +1000 Subject: [PATCH 02/25] changes made in the hotfixes branch --- synapse/app/synchrotron.py | 3 +++ synapse/federation/transaction_queue.py | 1 + synapse/handlers/initial_sync.py | 1 + synapse/handlers/message.py | 2 +- synapse/handlers/presence.py | 4 ++++ synapse/handlers/sync.py | 2 +- synapse/rest/client/v1/presence.py | 2 +- 7 files changed, 12 insertions(+), 3 deletions(-) diff --git a/synapse/app/synchrotron.py b/synapse/app/synchrotron.py index e201f18efdc5..6178080b728c 100644 --- a/synapse/app/synchrotron.py +++ b/synapse/app/synchrotron.py @@ -114,6 +114,7 @@ def __init__(self, hs): logger.info("Presence process_id is %r", self.process_id) def send_user_sync(self, user_id, is_syncing, last_sync_ms): + return self.hs.get_tcp_replication().send_user_sync(user_id, is_syncing, last_sync_ms) def mark_as_coming_online(self, user_id): @@ -211,6 +212,8 @@ def process_replication_rows(self, token, rows): yield self.notify_from_replication(states, stream_id) def get_currently_syncing_users(self): + # presence is disabled on matrix.org, so we return the empty set + return set() return [ user_id for user_id, count in iteritems(self.user_to_num_current_syncs) if count > 0 diff --git a/synapse/federation/transaction_queue.py b/synapse/federation/transaction_queue.py index f603c8a368aa..eced72985753 100644 --- a/synapse/federation/transaction_queue.py +++ b/synapse/federation/transaction_queue.py @@ -308,6 +308,7 @@ def send_presence(self, states): Args: states (list(UserPresenceState)) """ + return # First we queue up the new presence by user ID, so multiple presence # updates in quick successtion are correctly handled diff --git a/synapse/handlers/initial_sync.py b/synapse/handlers/initial_sync.py index 1fb17fd9a5b1..672cb9f11345 100644 --- a/synapse/handlers/initial_sync.py +++ b/synapse/handlers/initial_sync.py @@ -372,6 +372,7 @@ def _room_initial_sync_joined(self, user_id, room_id, pagin_config, @defer.inlineCallbacks def get_presence(): + defer.returnValue([]) states = yield presence_handler.get_states( [m.user_id for m in room_members], as_event=True, diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index 01a362360e92..faf5833a9dfb 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -139,7 +139,7 @@ def get_joined_members(self, requester, room_id): # If this is an AS, double check that they are allowed to see the members. # This can either be because the AS user is in the room or because there # is a user in the room that the AS is "interested in" - if requester.app_service and user_id not in users_with_profile: + if False and requester.app_service and user_id not in users_with_profile: for uid in users_with_profile: if requester.app_service.is_interested_in_user(uid): break diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py index 3671d24f60d0..2fb2729c53e2 100644 --- a/synapse/handlers/presence.py +++ b/synapse/handlers/presence.py @@ -395,6 +395,7 @@ def bump_presence_active_time(self, user): """We've seen the user do something that indicates they're interacting with the app. """ + return user_id = user.to_string() bump_active_time_counter.inc() @@ -424,6 +425,7 @@ def user_syncing(self, user_id, affect_presence=True): Useful for streams that are not associated with an actual client that is being used by a user. """ + affect_presence = False if affect_presence: curr_sync = self.user_to_num_current_syncs.get(user_id, 0) self.user_to_num_current_syncs[user_id] = curr_sync + 1 @@ -469,6 +471,8 @@ def get_currently_syncing_users(self): Returns: set(str): A set of user_id strings. """ + # presence is disabled on matrix.org, so we return the empty set + return set() syncing_user_ids = { user_id for user_id, count in self.user_to_num_current_syncs.items() if count diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py index 6393a9674b72..b24659f11ded 100644 --- a/synapse/handlers/sync.py +++ b/synapse/handlers/sync.py @@ -724,7 +724,7 @@ def generate_sync_result(self, sync_config, since_token=None, full_state=False): since_token is None and sync_config.filter_collection.blocks_all_presence() ) - if not block_all_presence_data: + if False and not block_all_presence_data: yield self._generate_sync_entry_for_presence( sync_result_builder, newly_joined_rooms, newly_joined_users ) diff --git a/synapse/rest/client/v1/presence.py b/synapse/rest/client/v1/presence.py index a14f0c807e2e..cb61bfcb21b8 100644 --- a/synapse/rest/client/v1/presence.py +++ b/synapse/rest/client/v1/presence.py @@ -84,7 +84,7 @@ def on_PUT(self, request, user_id): except Exception: raise SynapseError(400, "Unable to parse state") - yield self.presence_handler.set_state(user, state) + # yield self.presence_handler.set_state(user, state) defer.returnValue((200, {})) From 3844e39e1a442cb65e92b03b386af8218e34fd4c Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 13 Aug 2018 22:31:10 +1000 Subject: [PATCH 03/25] make it use a config option --- synapse/app/synchrotron.py | 16 +++++++------ synapse/config/server.py | 3 +++ synapse/federation/transaction_queue.py | 4 +++- synapse/handlers/initial_sync.py | 5 ++++- synapse/handlers/message.py | 2 +- synapse/handlers/presence.py | 30 ++++++++++++++++--------- synapse/handlers/sync.py | 2 +- synapse/rest/client/v1/presence.py | 3 ++- 8 files changed, 42 insertions(+), 23 deletions(-) diff --git a/synapse/app/synchrotron.py b/synapse/app/synchrotron.py index 6178080b728c..9511de5aa80e 100644 --- a/synapse/app/synchrotron.py +++ b/synapse/app/synchrotron.py @@ -114,8 +114,8 @@ def __init__(self, hs): logger.info("Presence process_id is %r", self.process_id) def send_user_sync(self, user_id, is_syncing, last_sync_ms): - return - self.hs.get_tcp_replication().send_user_sync(user_id, is_syncing, last_sync_ms) + if self.hs.config.use_presence: + self.hs.get_tcp_replication().send_user_sync(user_id, is_syncing, last_sync_ms) def mark_as_coming_online(self, user_id): """A user has started syncing. Send a UserSync to the master, unless they @@ -213,11 +213,13 @@ def process_replication_rows(self, token, rows): def get_currently_syncing_users(self): # presence is disabled on matrix.org, so we return the empty set - return set() - return [ - user_id for user_id, count in iteritems(self.user_to_num_current_syncs) - if count > 0 - ] + if self.hs.config.use_presence: + return [ + user_id for user_id, count in iteritems(self.user_to_num_current_syncs) + if count > 0 + ] + else: + return set() class SynchrotronTyping(object): diff --git a/synapse/config/server.py b/synapse/config/server.py index 3b078d72cabd..dc364711721b 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -49,6 +49,9 @@ def read_config(self, config): # "disable" federation self.send_federation = config.get("send_federation", True) + # Whether to enable user presence. + self.use_presence = config.get("use_presence", True) + # Whether to update the user directory or not. This should be set to # false only if we are updating the user directory in a worker self.update_user_directory = config.get("update_user_directory", True) diff --git a/synapse/federation/transaction_queue.py b/synapse/federation/transaction_queue.py index eced72985753..0606fc2b8002 100644 --- a/synapse/federation/transaction_queue.py +++ b/synapse/federation/transaction_queue.py @@ -308,7 +308,9 @@ def send_presence(self, states): Args: states (list(UserPresenceState)) """ - return + if not self.hs.config.use_presence: + # No-op if presence is disabled. + return # First we queue up the new presence by user ID, so multiple presence # updates in quick successtion are correctly handled diff --git a/synapse/handlers/initial_sync.py b/synapse/handlers/initial_sync.py index 672cb9f11345..e0093952074f 100644 --- a/synapse/handlers/initial_sync.py +++ b/synapse/handlers/initial_sync.py @@ -372,7 +372,10 @@ def _room_initial_sync_joined(self, user_id, room_id, pagin_config, @defer.inlineCallbacks def get_presence(): - defer.returnValue([]) + # If presence is disabled, return an empty list + if not self.hs.config.use_presence: + defer.returnValue([]) + states = yield presence_handler.get_states( [m.user_id for m in room_members], as_event=True, diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index faf5833a9dfb..01a362360e92 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -139,7 +139,7 @@ def get_joined_members(self, requester, room_id): # If this is an AS, double check that they are allowed to see the members. # This can either be because the AS user is in the room or because there # is a user in the room that the AS is "interested in" - if False and requester.app_service and user_id not in users_with_profile: + if requester.app_service and user_id not in users_with_profile: for uid in users_with_profile: if requester.app_service.is_interested_in_user(uid): break diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py index 2fb2729c53e2..ba3856674d0e 100644 --- a/synapse/handlers/presence.py +++ b/synapse/handlers/presence.py @@ -395,7 +395,10 @@ def bump_presence_active_time(self, user): """We've seen the user do something that indicates they're interacting with the app. """ - return + # If presence is disabled, no-op + if not self.hs.config.use_presence: + return + user_id = user.to_string() bump_active_time_counter.inc() @@ -425,7 +428,11 @@ def user_syncing(self, user_id, affect_presence=True): Useful for streams that are not associated with an actual client that is being used by a user. """ - affect_presence = False + # Override if it should affect the user's presence, if presence is + # disabled. + if not self.hs.config.use_presence: + affect_presence = False + if affect_presence: curr_sync = self.user_to_num_current_syncs.get(user_id, 0) self.user_to_num_current_syncs[user_id] = curr_sync + 1 @@ -471,15 +478,16 @@ def get_currently_syncing_users(self): Returns: set(str): A set of user_id strings. """ - # presence is disabled on matrix.org, so we return the empty set - return set() - syncing_user_ids = { - user_id for user_id, count in self.user_to_num_current_syncs.items() - if count - } - for user_ids in self.external_process_to_current_syncs.values(): - syncing_user_ids.update(user_ids) - return syncing_user_ids + if self.hs.config.use_presence: + syncing_user_ids = { + user_id for user_id, count in self.user_to_num_current_syncs.items() + if count + } + for user_ids in self.external_process_to_current_syncs.values(): + syncing_user_ids.update(user_ids) + return syncing_user_ids + else: + return set() @defer.inlineCallbacks def update_external_syncs_row(self, process_id, user_id, is_syncing, sync_time_msec): diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py index b24659f11ded..767b63991bce 100644 --- a/synapse/handlers/sync.py +++ b/synapse/handlers/sync.py @@ -724,7 +724,7 @@ def generate_sync_result(self, sync_config, since_token=None, full_state=False): since_token is None and sync_config.filter_collection.blocks_all_presence() ) - if False and not block_all_presence_data: + if self.hs.config.use_presence and not block_all_presence_data: yield self._generate_sync_entry_for_presence( sync_result_builder, newly_joined_rooms, newly_joined_users ) diff --git a/synapse/rest/client/v1/presence.py b/synapse/rest/client/v1/presence.py index cb61bfcb21b8..b5a6d6aebfc7 100644 --- a/synapse/rest/client/v1/presence.py +++ b/synapse/rest/client/v1/presence.py @@ -84,7 +84,8 @@ def on_PUT(self, request, user_id): except Exception: raise SynapseError(400, "Unable to parse state") - # yield self.presence_handler.set_state(user, state) + if self.hs.config.use_presence: + yield self.presence_handler.set_state(user, state) defer.returnValue((200, {})) From f21d6415858cce5369f6fe1fa06f4358e00b308e Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 13 Aug 2018 22:32:53 +1000 Subject: [PATCH 04/25] add it as a default --- synapse/config/server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/synapse/config/server.py b/synapse/config/server.py index dc364711721b..4a9d06dab2ed 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -248,6 +248,9 @@ def default_config(self, server_name, **kwargs): # hard limit. soft_file_limit: 0 + # Set to false to disable presence tracking on this homeserver. + use_presence: true + # The GC threshold parameters to pass to `gc.set_threshold`, if defined # gc_thresholds: [700, 10, 10] From ed38a2ece243437546195a15201e2d6d4b36aaf4 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 13 Aug 2018 23:48:46 +1000 Subject: [PATCH 05/25] initial tests --- tests/rest/client/v1/test_presence.py | 46 +++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/rest/client/v1/test_presence.py diff --git a/tests/rest/client/v1/test_presence.py b/tests/rest/client/v1/test_presence.py new file mode 100644 index 000000000000..160674fcfb88 --- /dev/null +++ b/tests/rest/client/v1/test_presence.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 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. + +import hashlib +import hmac +import json + +from mock import Mock + +from synapse.http.server import JsonResource +from synapse.rest.client.v1.admin import register_servlets +from synapse.util import Clock + +from tests import unittest +from tests.server import ( + ThreadedMemoryReactorClock, + make_request, + render, + setup_test_homeserver, +) + + +class UserRegisterTestCase(unittest.TestCase): + def setUp(self): + + self.clock = ThreadedMemoryReactorClock() + self.hs_clock = Clock(self.clock) + + self.hs = setup_test_homeserver( + self.addCleanup, http_client=None, clock=self.hs_clock, reactor=self.clock + ) + + self.resource = JsonResource(self.hs) + register_servlets(self.hs, self.resource) From 3b7759fe00f001b46e6d2457543224efee87d339 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 02:15:02 +1000 Subject: [PATCH 06/25] some initial tests --- tests/rest/client/v1/test_presence.py | 75 +++++++++++++++++++-------- tests/unittest.py | 8 ++- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/tests/rest/client/v1/test_presence.py b/tests/rest/client/v1/test_presence.py index 160674fcfb88..6b1d05335059 100644 --- a/tests/rest/client/v1/test_presence.py +++ b/tests/rest/client/v1/test_presence.py @@ -13,34 +13,67 @@ # See the License for the specific language governing permissions and # limitations under the License. -import hashlib -import hmac -import json +from mock import Mock, NonCallableMock -from mock import Mock +from twisted.internet import defer -from synapse.http.server import JsonResource -from synapse.rest.client.v1.admin import register_servlets -from synapse.util import Clock +from synapse.rest.client.v1 import presence +from synapse.types import UserID from tests import unittest -from tests.server import ( - ThreadedMemoryReactorClock, - make_request, - render, - setup_test_homeserver, -) +class RoomTypingTestCase(unittest.HomeserverTestCase): + """ Tests presence REST API. """ -class UserRegisterTestCase(unittest.TestCase): - def setUp(self): + user_id = "@sid:red" - self.clock = ThreadedMemoryReactorClock() - self.hs_clock = Clock(self.clock) + user = UserID.from_string(user_id) + servlets = [presence.register_servlets] - self.hs = setup_test_homeserver( - self.addCleanup, http_client=None, clock=self.hs_clock, reactor=self.clock + def make_homeserver(self, reactor, clock): + + hs = self.setup_test_homeserver( + "red", + http_client=None, + federation_client=Mock(), + ) + + hs.presence_handler = Mock() + + return hs + + def test_put_presence(self): + """ + PUT to the status endpoint with use_presence enabled will call + set_state on the presence handler. + """ + self.hs.config.use_presence = True + + body = {"presence": "here", "status_msg": "beep boop"} + request, channel = self.make_request( + "PUT", + "/presence/%s/status" % (self.user_id,), + body + ) + self.render(request) + + self.assertEqual(channel.code, 200) + self.assertEqual(self.hs.presence_handler.set_state.call_count, 1) + + def test_put_presence_disabled(self): + """ + PUT to the status endpoint with use_presence disbled will NOT call + set_state on the presence handler. + """ + self.hs.config.use_presence = False + + body = {"presence": "here", "status_msg": "beep boop"} + request, channel = self.make_request( + "PUT", + "/presence/%s/status" % (self.user_id,), + body ) + self.render(request) - self.resource = JsonResource(self.hs) - register_servlets(self.hs, self.resource) + self.assertEqual(channel.code, 200) + self.assertEqual(self.hs.presence_handler.set_state.call_count, 0) diff --git a/tests/unittest.py b/tests/unittest.py index e6afe3b96d61..26edccaf05c3 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -22,6 +22,8 @@ import twisted.logger from twisted.trial import unittest +from canonicaljson import json + from synapse.http.server import JsonResource from synapse.server import HomeServer from synapse.types import UserID, create_requester @@ -241,11 +243,15 @@ def make_request(self, method, path, content=b""): method (bytes/unicode): The HTTP request method ("verb"). path (bytes/unicode): The HTTP path, suitably URL encoded (e.g. escaped UTF-8 & spaces and such). - content (bytes): The body of the request. + content (bytes or dict): The body of the request. JSON-encoded, if + a dict. Returns: A synapse.http.site.SynapseRequest. """ + if isinstance(content, dict): + content = json.dumps(content).encode('utf8') + return make_request(method, path, content) def render(self, request): From 16d20ffe572c71e90790bb44a92d7a764bc2f5d7 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 19:37:58 +1000 Subject: [PATCH 07/25] minor fix --- synapse/federation/transaction_queue.py | 1 + 1 file changed, 1 insertion(+) diff --git a/synapse/federation/transaction_queue.py b/synapse/federation/transaction_queue.py index 0606fc2b8002..94d7423d016a 100644 --- a/synapse/federation/transaction_queue.py +++ b/synapse/federation/transaction_queue.py @@ -58,6 +58,7 @@ class TransactionQueue(object): """ def __init__(self, hs): + self.hs = hs self.server_name = hs.hostname self.store = hs.get_datastore() From f320a5e1a78e28b7b010f939cdd6257c28ed87eb Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 19:44:11 +1000 Subject: [PATCH 08/25] other fix --- synapse/handlers/sync.py | 1 + 1 file changed, 1 insertion(+) diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py index 767b63991bce..93bafe6693b6 100644 --- a/synapse/handlers/sync.py +++ b/synapse/handlers/sync.py @@ -184,6 +184,7 @@ def __nonzero__(self): class SyncHandler(object): def __init__(self, hs): + self.hs = hs self.store = hs.get_datastore() self.notifier = hs.get_notifier() self.presence_handler = hs.get_presence_handler() From e49e3e0c4ab74c815831a05cb33f06a0ea549b54 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 20:16:24 +1000 Subject: [PATCH 09/25] fixes --- MANIFEST.in | 3 +++ tests/rest/client/v1/test_presence.py | 17 +++++------------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index e0826ba544c8..90c6898392ee 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -28,6 +28,9 @@ exclude jenkins*.sh exclude jenkins* exclude Dockerfile exclude .dockerignore +exclude Dockerfile-pgtests +exclude docker_run_pg_tests.sh +exclude test_postgresql.sh recursive-exclude jenkins *.sh include pyproject.toml diff --git a/tests/rest/client/v1/test_presence.py b/tests/rest/client/v1/test_presence.py index 6b1d05335059..e2624da17b9a 100644 --- a/tests/rest/client/v1/test_presence.py +++ b/tests/rest/client/v1/test_presence.py @@ -13,15 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -from mock import Mock, NonCallableMock - -from twisted.internet import defer +from mock import Mock from synapse.rest.client.v1 import presence from synapse.types import UserID from tests import unittest + class RoomTypingTestCase(unittest.HomeserverTestCase): """ Tests presence REST API. """ @@ -33,9 +32,7 @@ class RoomTypingTestCase(unittest.HomeserverTestCase): def make_homeserver(self, reactor, clock): hs = self.setup_test_homeserver( - "red", - http_client=None, - federation_client=Mock(), + "red", http_client=None, federation_client=Mock() ) hs.presence_handler = Mock() @@ -51,9 +48,7 @@ def test_put_presence(self): body = {"presence": "here", "status_msg": "beep boop"} request, channel = self.make_request( - "PUT", - "/presence/%s/status" % (self.user_id,), - body + "PUT", "/presence/%s/status" % (self.user_id,), body ) self.render(request) @@ -69,9 +64,7 @@ def test_put_presence_disabled(self): body = {"presence": "here", "status_msg": "beep boop"} request, channel = self.make_request( - "PUT", - "/presence/%s/status" % (self.user_id,), - body + "PUT", "/presence/%s/status" % (self.user_id,), body ) self.render(request) From 850c47fd9eb07879bfbb6223a5e633da15b0c606 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 20:17:24 +1000 Subject: [PATCH 10/25] fix --- synapse/app/synchrotron.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/synapse/app/synchrotron.py b/synapse/app/synchrotron.py index 9511de5aa80e..f43c4d547a74 100644 --- a/synapse/app/synchrotron.py +++ b/synapse/app/synchrotron.py @@ -115,7 +115,9 @@ def __init__(self, hs): def send_user_sync(self, user_id, is_syncing, last_sync_ms): if self.hs.config.use_presence: - self.hs.get_tcp_replication().send_user_sync(user_id, is_syncing, last_sync_ms) + self.hs.get_tcp_replication().send_user_sync( + user_id, is_syncing, last_sync_ms + ) def mark_as_coming_online(self, user_id): """A user has started syncing. Send a UserSync to the master, unless they From 204884ff9577dc218b031b1e904709c22c780e31 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 20:25:45 +1000 Subject: [PATCH 11/25] changelog --- changelog.d/3694.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/3694.feature diff --git a/changelog.d/3694.feature b/changelog.d/3694.feature new file mode 100644 index 000000000000..916a342ff48f --- /dev/null +++ b/changelog.d/3694.feature @@ -0,0 +1 @@ +Synapse's presence functionality can now be disabled with the "use_presence" configuration option. From 3a905cd9917eb77c430338b23dcd7d95848d9c60 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 20:26:19 +1000 Subject: [PATCH 12/25] fixes --- tests/unittest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unittest.py b/tests/unittest.py index 26edccaf05c3..d852e2465a06 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -18,12 +18,12 @@ from mock import Mock +from canonicaljson import json + import twisted import twisted.logger from twisted.trial import unittest -from canonicaljson import json - from synapse.http.server import JsonResource from synapse.server import HomeServer from synapse.types import UserID, create_requester From 48e1a7a7bb7be593cba8878728b596696614fb5b Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 21:27:39 +1000 Subject: [PATCH 13/25] fix name --- tests/rest/client/v1/test_presence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rest/client/v1/test_presence.py b/tests/rest/client/v1/test_presence.py index e2624da17b9a..66c2b687079c 100644 --- a/tests/rest/client/v1/test_presence.py +++ b/tests/rest/client/v1/test_presence.py @@ -21,7 +21,7 @@ from tests import unittest -class RoomTypingTestCase(unittest.HomeserverTestCase): +class PresenceTestCase(unittest.HomeserverTestCase): """ Tests presence REST API. """ user_id = "@sid:red" From 83f5c525263474f56fa05b7a8a99f00a4468f33e Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 15 Aug 2018 23:14:49 +1000 Subject: [PATCH 14/25] some fixes --- tests/rest/client/v2_alpha/test_sync.py | 67 ++++++++++++------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/tests/rest/client/v2_alpha/test_sync.py b/tests/rest/client/v2_alpha/test_sync.py index 2e1d06c50982..6cf985a4f287 100644 --- a/tests/rest/client/v2_alpha/test_sync.py +++ b/tests/rest/client/v2_alpha/test_sync.py @@ -13,6 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import mock + import synapse.types from synapse.http.server import JsonResource from synapse.rest.client.v2_alpha import sync @@ -30,55 +32,50 @@ PATH_PREFIX = "/_matrix/client/v2_alpha" -class FilterTestCase(unittest.TestCase): +class FilterTestCase(unittest.HomeserverTestCase): - USER_ID = "@apple:test" - TO_REGISTER = [sync] + user_id = "@apple:test" + servlets = [sync.register_servlets] - def setUp(self): - self.clock = MemoryReactorClock() - self.hs_clock = Clock(self.clock) + def make_homeserver(self, reactor, clock): - self.hs = setup_test_homeserver( - self.addCleanup, http_client=None, clock=self.hs_clock, reactor=self.clock + hs = self.setup_test_homeserver( + "red", http_client=None, federation_client=Mock() ) + return hs - self.auth = self.hs.get_auth() - - def get_user_by_access_token(token=None, allow_guest=False): - return { - "user": UserID.from_string(self.USER_ID), - "token_id": 1, - "is_guest": False, - } - - def get_user_by_req(request, allow_guest=False, rights="access"): - return synapse.types.create_requester( - UserID.from_string(self.USER_ID), 1, False, None - ) - - self.auth.get_user_by_access_token = get_user_by_access_token - self.auth.get_user_by_req = get_user_by_req + def test_sync_argless(self): + request, channel = self.make_request("GET", "/_matrix/client/r0/sync") + self.render(self.request) - self.store = self.hs.get_datastore() - self.filtering = self.hs.get_filtering() - self.resource = JsonResource(self.hs) + self.assertEqual(channel.code, 200) + self.assertTrue( + set( + [ + "next_batch", + "rooms", + "presence", + "account_data", + "to_device", + "device_lists", + ] + ).issubset(set(channel.json_body.keys())) + ) - for r in self.TO_REGISTER: - r.register_servlets(self.hs, self.resource) + def test_sync_presence_disabled(self): + """ + """ + self.hs.config.use_presence = False - def test_sync_argless(self): - request, channel = make_request("GET", "/_matrix/client/r0/sync") - request.render(self.resource) - wait_until_result(self.clock, channel) + request, channel = self.make_request("GET", "/_matrix/client/r0/sync") + self.render(self.request) - self.assertEqual(channel.result["code"], b"200") + self.assertEqual(channel.code, 200) self.assertTrue( set( [ "next_batch", "rooms", - "presence", "account_data", "to_device", "device_lists", From f95d03f6c6cba817197bad359b7c4deced43ae30 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 16 Aug 2018 03:29:40 +1000 Subject: [PATCH 15/25] fix --- tests/rest/client/v2_alpha/test_sync.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rest/client/v2_alpha/test_sync.py b/tests/rest/client/v2_alpha/test_sync.py index 6cf985a4f287..4863ddcd3449 100644 --- a/tests/rest/client/v2_alpha/test_sync.py +++ b/tests/rest/client/v2_alpha/test_sync.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import mock +from mock import Mock import synapse.types from synapse.http.server import JsonResource @@ -64,6 +64,7 @@ def test_sync_argless(self): def test_sync_presence_disabled(self): """ + When presence is disabled, the key does not appear in /sync. """ self.hs.config.use_presence = False From b985d80ecd25a999d8793d137476f5f1410bc65e Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 16 Aug 2018 03:30:26 +1000 Subject: [PATCH 16/25] fix test --- tests/rest/client/v2_alpha/test_sync.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/rest/client/v2_alpha/test_sync.py b/tests/rest/client/v2_alpha/test_sync.py index 4863ddcd3449..d31a7f37ef78 100644 --- a/tests/rest/client/v2_alpha/test_sync.py +++ b/tests/rest/client/v2_alpha/test_sync.py @@ -46,7 +46,7 @@ def make_homeserver(self, reactor, clock): def test_sync_argless(self): request, channel = self.make_request("GET", "/_matrix/client/r0/sync") - self.render(self.request) + self.render(request) self.assertEqual(channel.code, 200) self.assertTrue( @@ -69,7 +69,7 @@ def test_sync_presence_disabled(self): self.hs.config.use_presence = False request, channel = self.make_request("GET", "/_matrix/client/r0/sync") - self.render(self.request) + self.render(request) self.assertEqual(channel.code, 200) self.assertTrue( From 6323339a41b6abdf9303c8860837b874762d1005 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 16 Aug 2018 03:37:02 +1000 Subject: [PATCH 17/25] fix --- tests/rest/client/v2_alpha/test_sync.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/rest/client/v2_alpha/test_sync.py b/tests/rest/client/v2_alpha/test_sync.py index d31a7f37ef78..560b1fba967a 100644 --- a/tests/rest/client/v2_alpha/test_sync.py +++ b/tests/rest/client/v2_alpha/test_sync.py @@ -15,21 +15,9 @@ from mock import Mock -import synapse.types -from synapse.http.server import JsonResource from synapse.rest.client.v2_alpha import sync -from synapse.types import UserID -from synapse.util import Clock from tests import unittest -from tests.server import ( - ThreadedMemoryReactorClock as MemoryReactorClock, - make_request, - setup_test_homeserver, - wait_until_result, -) - -PATH_PREFIX = "/_matrix/client/v2_alpha" class FilterTestCase(unittest.HomeserverTestCase): @@ -45,7 +33,7 @@ def make_homeserver(self, reactor, clock): return hs def test_sync_argless(self): - request, channel = self.make_request("GET", "/_matrix/client/r0/sync") + request, channel = self.make_request("GET", "/sync") self.render(request) self.assertEqual(channel.code, 200) @@ -68,7 +56,7 @@ def test_sync_presence_disabled(self): """ self.hs.config.use_presence = False - request, channel = self.make_request("GET", "/_matrix/client/r0/sync") + request, channel = self.make_request("GET", "/sync") self.render(request) self.assertEqual(channel.code, 200) From 59081485e69a9af3202b083b00733bcd878e11fc Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 16 Aug 2018 03:38:29 +1000 Subject: [PATCH 18/25] remove stuff not meant to be in this branch --- Dockerfile-pgtests | 8 -------- MANIFEST.in | 3 --- docker_run_pg_tests.sh | 10 ---------- test_postgresql.sh | 3 --- 4 files changed, 24 deletions(-) delete mode 100644 Dockerfile-pgtests delete mode 100755 docker_run_pg_tests.sh delete mode 100755 test_postgresql.sh diff --git a/Dockerfile-pgtests b/Dockerfile-pgtests deleted file mode 100644 index 4cd8d480457f..000000000000 --- a/Dockerfile-pgtests +++ /dev/null @@ -1,8 +0,0 @@ -FROM matrixdotorg/sytest:latest - -RUN apt-get -qq install -y python python-dev python-pip - -RUN pip install tox - -ADD docker_run_pg_tests.sh /pg_tests.sh -ENTRYPOINT /pg_tests.sh diff --git a/MANIFEST.in b/MANIFEST.in index 90c6898392ee..e0826ba544c8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -28,9 +28,6 @@ exclude jenkins*.sh exclude jenkins* exclude Dockerfile exclude .dockerignore -exclude Dockerfile-pgtests -exclude docker_run_pg_tests.sh -exclude test_postgresql.sh recursive-exclude jenkins *.sh include pyproject.toml diff --git a/docker_run_pg_tests.sh b/docker_run_pg_tests.sh deleted file mode 100755 index 3577e66cb8dd..000000000000 --- a/docker_run_pg_tests.sh +++ /dev/null @@ -1,10 +0,0 @@ -export PGDATA=/var/lib/postgresql/data -export PGUSER=postgres - -# Initialise the database files and start the database -su -c '/usr/lib/postgresql/9.6/bin/initdb -E "UTF-8" --lc-collate="en_US.UTF-8" --lc-ctype="en_US.UTF-8" --username=postgres' postgres -su -c '/usr/lib/postgresql/9.6/bin/pg_ctl -w -D /var/lib/postgresql/data start' postgres - -cd /src -export TRIAL_FLAGS="-j 4" -tox -e py27-postgres diff --git a/test_postgresql.sh b/test_postgresql.sh deleted file mode 100755 index a2e88aabb0dc..000000000000 --- a/test_postgresql.sh +++ /dev/null @@ -1,3 +0,0 @@ -#! /usr/bin/env bash -docker build . -f Dockerfile-pgtests -t synapsepgtests -docker run --rm -it -v $(pwd)\:/src synapsepgtests From ede5fdb76d5580039be7b3dd79b8a71284ab5ea5 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 16 Aug 2018 03:39:53 +1000 Subject: [PATCH 19/25] clean comment --- synapse/app/synchrotron.py | 1 - 1 file changed, 1 deletion(-) diff --git a/synapse/app/synchrotron.py b/synapse/app/synchrotron.py index f43c4d547a74..cade09d60e37 100644 --- a/synapse/app/synchrotron.py +++ b/synapse/app/synchrotron.py @@ -214,7 +214,6 @@ def process_replication_rows(self, token, rows): yield self.notify_from_replication(states, stream_id) def get_currently_syncing_users(self): - # presence is disabled on matrix.org, so we return the empty set if self.hs.config.use_presence: return [ user_id for user_id, count in iteritems(self.user_to_num_current_syncs) From 6c621243447f2cce9708d6e4b1ea564f400f881a Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Fri, 17 Aug 2018 20:30:30 +1000 Subject: [PATCH 20/25] port this over too --- synapse/app/frontend_proxy.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/synapse/app/frontend_proxy.py b/synapse/app/frontend_proxy.py index 671fbbcb2a9d..1f055c98562d 100644 --- a/synapse/app/frontend_proxy.py +++ b/synapse/app/frontend_proxy.py @@ -38,6 +38,7 @@ from synapse.replication.slave.storage.devices import SlavedDeviceStore from synapse.replication.slave.storage.registration import SlavedRegistrationStore from synapse.replication.tcp.client import ReplicationClientHandler +from synapse.rest.client.v1.base import ClientV1RestServlet, client_path_patterns from synapse.rest.client.v2_alpha._base import client_v2_patterns from synapse.server import HomeServer from synapse.storage.engines import create_engine @@ -49,6 +50,35 @@ logger = logging.getLogger("synapse.app.frontend_proxy") +class PresenceStatusStubServlet(ClientV1RestServlet): + PATTERNS = client_path_patterns("/presence/(?P[^/]*)/status") + + def __init__(self, hs): + super(PresenceStatusStubServlet, self).__init__(hs) + self.http_client = hs.get_simple_http_client() + self.auth = hs.get_auth() + self.main_uri = hs.config.worker_main_http_uri + + @defer.inlineCallbacks + def on_GET(self, request, user_id): + # Pass through the auth headers, if any, in case the access token + # is there. + auth_headers = request.requestHeaders.getRawHeaders("Authorization", []) + headers = { + "Authorization": auth_headers, + } + result = yield self.http_client.get_json( + self.main_uri + request.uri, + headers=headers, + ) + defer.returnValue((200, result)) + + @defer.inlineCallbacks + def on_PUT(self, request, user_id): + yield self.auth.get_user_by_req(request) + defer.returnValue((200, {})) + + class KeyUploadServlet(RestServlet): PATTERNS = client_v2_patterns("/keys/upload(/(?P[^/]+))?$") @@ -135,6 +165,8 @@ def _listen_http(self, listener_config): elif name == "client": resource = JsonResource(self, canonical_json=False) KeyUploadServlet(self).register(resource) + if not self.config.use_presence: + PresenceStatusStubServlet(self).register(resource) resources.update({ "/_matrix/client/r0": resource, "/_matrix/client/unstable": resource, From bf83b44632e8c04aaa2940eec97bdb5a88dc47b0 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Fri, 17 Aug 2018 22:09:44 +1000 Subject: [PATCH 21/25] tests & fixes --- synapse/app/_base.py | 6 +- synapse/app/frontend_proxy.py | 7 ++- tests/app/__init__.py | 0 tests/app/test_frontend_proxy.py | 94 ++++++++++++++++++++++++++++++++ tests/utils.py | 7 ++- 5 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 tests/app/__init__.py create mode 100644 tests/app/test_frontend_proxy.py diff --git a/synapse/app/_base.py b/synapse/app/_base.py index 391bd14c5c9c..7c866e246af8 100644 --- a/synapse/app/_base.py +++ b/synapse/app/_base.py @@ -140,7 +140,7 @@ def listen_metrics(bind_addresses, port): logger.info("Metrics now reporting on %s:%d", host, port) -def listen_tcp(bind_addresses, port, factory, backlog=50): +def listen_tcp(bind_addresses, port, factory, reactor=reactor, backlog=50): """ Create a TCP socket for a port and several addresses """ @@ -156,7 +156,9 @@ def listen_tcp(bind_addresses, port, factory, backlog=50): check_bind_error(e, address, bind_addresses) -def listen_ssl(bind_addresses, port, factory, context_factory, backlog=50): +def listen_ssl( + bind_addresses, port, factory, context_factory, reactor=reactor, backlog=50 +): """ Create an SSL socket for a port and several addresses """ diff --git a/synapse/app/frontend_proxy.py b/synapse/app/frontend_proxy.py index 1f055c98562d..8d484c1cd4a0 100644 --- a/synapse/app/frontend_proxy.py +++ b/synapse/app/frontend_proxy.py @@ -165,8 +165,12 @@ def _listen_http(self, listener_config): elif name == "client": resource = JsonResource(self, canonical_json=False) KeyUploadServlet(self).register(resource) + + # If presence is disabled, use the stub servlet that does + # not allow sending presence if not self.config.use_presence: PresenceStatusStubServlet(self).register(resource) + resources.update({ "/_matrix/client/r0": resource, "/_matrix/client/unstable": resource, @@ -185,7 +189,8 @@ def _listen_http(self, listener_config): listener_config, root_resource, self.version_string, - ) + ), + reactor=self.get_reactor() ) logger.info("Synapse client reader now listening on port %d", port) diff --git a/tests/app/__init__.py b/tests/app/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/app/test_frontend_proxy.py b/tests/app/test_frontend_proxy.py new file mode 100644 index 000000000000..7ee0f9cce9c2 --- /dev/null +++ b/tests/app/test_frontend_proxy.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# Copyright 2018 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. + +from unittest import TestCase + +from synapse.app.frontend_proxy import FrontendProxyServer + +from tests.unittest import HomeserverTestCase + +class FrontendProxyTests(HomeserverTestCase): + + def make_homeserver(self, reactor, clock): + + hs = self.setup_test_homeserver( + http_client=None, homeserverToUse=FrontendProxyServer + ) + + return hs + + def test_listen_http_with_presence_enabled(self): + """ + When presence is on, the stub servlet will not register. + """ + # Presence is on + self.hs.config.use_presence = True + + config = { + "port": 8080, + "bind_addresses": ["0.0.0.0"], + "resources": [ + { + "names": ["client"] + } + ] + } + + # Listen with the config + self.hs._listen_http(config) + + # Grab the resource from the site that was told to listen + self.assertEqual(len(self.reactor.tcpServers), 1) + site = self.reactor.tcpServers[0][1] + self.resource = site.resource.children["_matrix"].children["client"].children["r0"] + + request, channel = self.make_request("PUT", "presence/a/status") + self.render(request) + + # 400 + unrecognised, because nothing is registered + self.assertEqual(channel.code, 400) + self.assertEqual(channel.json_body["errcode"], "M_UNRECOGNIZED") + + def test_listen_http_with_presence_disabled(self): + """ + When presence is on, the stub servlet will register. + """ + # Presence is off + self.hs.config.use_presence = False + + config = { + "port": 8080, + "bind_addresses": ["0.0.0.0"], + "resources": [ + { + "names": ["client"] + } + ] + } + + # Listen with the config + self.hs._listen_http(config) + + # Grab the resource from the site that was told to listen + self.assertEqual(len(self.reactor.tcpServers), 1) + site = self.reactor.tcpServers[0][1] + self.resource = site.resource.children["_matrix"].children["client"].children["r0"] + + request, channel = self.make_request("PUT", "presence/a/status") + self.render(request) + + # 401, because the stub servlet still checks authentication + self.assertEqual(channel.code, 401) + self.assertEqual(channel.json_body["errcode"], "M_MISSING_TOKEN") diff --git a/tests/utils.py b/tests/utils.py index 90378326f898..b4be27a45b8b 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -93,7 +93,8 @@ def _cleanup(): @defer.inlineCallbacks def setup_test_homeserver( - cleanup_func, name="test", datastore=None, config=None, reactor=None, **kargs + cleanup_func, name="test", datastore=None, config=None, reactor=None, + homeserverToUse=HomeServer, **kargs ): """ Setup a homeserver suitable for running tests against. Keyword arguments @@ -190,7 +191,7 @@ def setup_test_homeserver( config.database_config["args"]["cp_openfun"] = db_engine.on_new_connection if datastore is None: - hs = HomeServer( + hs = homeserverToUse( name, config=config, db_config=config.database_config, @@ -233,7 +234,7 @@ def cleanup(): hs.setup() else: - hs = HomeServer( + hs = homeserverToUse( name, db_pool=None, datastore=datastore, From 414e430ce588531e073695397311493c9a8b989a Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Fri, 17 Aug 2018 22:15:10 +1000 Subject: [PATCH 22/25] fix --- tests/app/test_frontend_proxy.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/app/test_frontend_proxy.py b/tests/app/test_frontend_proxy.py index 7ee0f9cce9c2..1ec2a3540124 100644 --- a/tests/app/test_frontend_proxy.py +++ b/tests/app/test_frontend_proxy.py @@ -19,8 +19,8 @@ from tests.unittest import HomeserverTestCase -class FrontendProxyTests(HomeserverTestCase): +class FrontendProxyTests(HomeserverTestCase): def make_homeserver(self, reactor, clock): hs = self.setup_test_homeserver( @@ -39,11 +39,7 @@ def test_listen_http_with_presence_enabled(self): config = { "port": 8080, "bind_addresses": ["0.0.0.0"], - "resources": [ - { - "names": ["client"] - } - ] + "resources": [{"names": ["client"]}], } # Listen with the config @@ -52,7 +48,9 @@ def test_listen_http_with_presence_enabled(self): # Grab the resource from the site that was told to listen self.assertEqual(len(self.reactor.tcpServers), 1) site = self.reactor.tcpServers[0][1] - self.resource = site.resource.children["_matrix"].children["client"].children["r0"] + self.resource = ( + site.resource.children["_matrix"].children["client"].children["r0"] + ) request, channel = self.make_request("PUT", "presence/a/status") self.render(request) @@ -71,11 +69,7 @@ def test_listen_http_with_presence_disabled(self): config = { "port": 8080, "bind_addresses": ["0.0.0.0"], - "resources": [ - { - "names": ["client"] - } - ] + "resources": [{"names": ["client"]}], } # Listen with the config @@ -84,7 +78,9 @@ def test_listen_http_with_presence_disabled(self): # Grab the resource from the site that was told to listen self.assertEqual(len(self.reactor.tcpServers), 1) site = self.reactor.tcpServers[0][1] - self.resource = site.resource.children["_matrix"].children["client"].children["r0"] + self.resource = ( + site.resource.children["_matrix"].children["client"].children["r0"] + ) request, channel = self.make_request("PUT", "presence/a/status") self.render(request) From 72735e5bf5e51f47a7a4fba2435e5fafd124015a Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Fri, 17 Aug 2018 22:21:05 +1000 Subject: [PATCH 23/25] fix pep8 --- tests/app/test_frontend_proxy.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/app/test_frontend_proxy.py b/tests/app/test_frontend_proxy.py index 1ec2a3540124..76b5090fffd1 100644 --- a/tests/app/test_frontend_proxy.py +++ b/tests/app/test_frontend_proxy.py @@ -13,8 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from unittest import TestCase - from synapse.app.frontend_proxy import FrontendProxyServer from tests.unittest import HomeserverTestCase From b9febad1f3cebde8b42968e221c09ec4dba464f3 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Sat, 18 Aug 2018 00:49:45 +1000 Subject: [PATCH 24/25] docs, fix --- docs/workers.rst | 8 ++++++++ synapse/handlers/sync.py | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/workers.rst b/docs/workers.rst index ac9efb621f06..aec319dd8458 100644 --- a/docs/workers.rst +++ b/docs/workers.rst @@ -241,6 +241,14 @@ regular expressions:: ^/_matrix/client/(api/v1|r0|unstable)/keys/upload +If ``use_presence`` is False in the homeserver config, it can also handle REST +endpoints matching the following regular expressions:: + + ^/_matrix/client/(api/v1|r0|unstable)/presence/[^/]+/status + +This "stub" presence handler will pass through ``GET`` request but make the +``PUT`` effectively a no-op. + It will proxy any requests it cannot handle to the main synapse instance. It must therefore be configured with the location of the main instance, via the ``worker_main_http_uri`` setting in the frontend_proxy worker configuration diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py index a185ef40eec2..648debc8aa96 100644 --- a/synapse/handlers/sync.py +++ b/synapse/handlers/sync.py @@ -185,7 +185,7 @@ def __nonzero__(self): class SyncHandler(object): def __init__(self, hs): - self.hs = hs + self.hs_config = hs.config self.store = hs.get_datastore() self.notifier = hs.get_notifier() self.presence_handler = hs.get_presence_handler() @@ -861,7 +861,7 @@ def generate_sync_result(self, sync_config, since_token=None, full_state=False): since_token is None and sync_config.filter_collection.blocks_all_presence() ) - if self.hs.config.use_presence and not block_all_presence_data: + if self.hs_config.use_presence and not block_all_presence_data: yield self._generate_sync_entry_for_presence( sync_result_builder, newly_joined_rooms, newly_joined_users ) From 45cac1aae9186d839dee1819d98c3812efc95047 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Sat, 18 Aug 2018 00:56:48 +1000 Subject: [PATCH 25/25] fix --- tests/rest/client/v2_alpha/test_sync.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/rest/client/v2_alpha/test_sync.py b/tests/rest/client/v2_alpha/test_sync.py index 16bf23b10421..560b1fba967a 100644 --- a/tests/rest/client/v2_alpha/test_sync.py +++ b/tests/rest/client/v2_alpha/test_sync.py @@ -19,6 +19,7 @@ from tests import unittest + class FilterTestCase(unittest.HomeserverTestCase): user_id = "@apple:test"