diff options
-rw-r--r-- | CHANGES.md | 25 | ||||
-rw-r--r-- | INSTALL.md | 9 | ||||
-rw-r--r-- | changelog.d/5633.bugfix | 1 | ||||
-rw-r--r-- | changelog.d/5856.feature | 1 | ||||
-rw-r--r-- | changelog.d/5857.bugfix | 1 | ||||
-rw-r--r-- | changelog.d/5863.bugfix | 1 | ||||
-rw-r--r-- | debian/changelog | 16 | ||||
-rw-r--r-- | debian/control | 1 | ||||
-rw-r--r-- | synapse/__init__.py | 2 | ||||
-rw-r--r-- | synapse/api/auth.py | 4 | ||||
-rw-r--r-- | synapse/app/_base.py | 47 | ||||
-rw-r--r-- | synapse/app/homeserver.py | 2 | ||||
-rw-r--r-- | synapse/config/emailconfig.py | 16 | ||||
-rw-r--r-- | synapse/federation/transport/server.py | 23 | ||||
-rw-r--r-- | synapse/handlers/room.py | 14 | ||||
-rw-r--r-- | synapse/http/matrixfederationclient.py | 23 | ||||
-rw-r--r-- | synapse/python_dependencies.py | 1 | ||||
-rw-r--r-- | synapse/rest/client/v2_alpha/account.py | 4 | ||||
-rw-r--r-- | synapse/storage/e2e_room_keys.py | 2 | ||||
-rw-r--r-- | synapse/storage/schema/delta/56/fix_room_keys_index.sql | 18 |
20 files changed, 159 insertions, 52 deletions
diff --git a/CHANGES.md b/CHANGES.md index eca9c82f55..f25c7d0c1a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,28 @@ +Synapse 1.3.1 (2019-08-17) +========================== + +Features +-------- + +- Drop hard dependency on `sdnotify` python package. ([\#5871](https://github.com/matrix-org/synapse/issues/5871)) + + +Bugfixes +-------- + +- Fix startup issue (hang on ACME provisioning) due to ordering of Twisted reactor startup. Thanks to @chrismoos for supplying the fix. ([\#5867](https://github.com/matrix-org/synapse/issues/5867)) + + +Synapse 1.3.0 (2019-08-15) +========================== + +Bugfixes +-------- + +- Fix 500 Internal Server Error on `publicRooms` when the public room list was + cached. ([\#5851](https://github.com/matrix-org/synapse/issues/5851)) + + Synapse 1.3.0rc1 (2019-08-13) ========================== diff --git a/INSTALL.md b/INSTALL.md index 25343593d5..5728882460 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -419,12 +419,11 @@ If Synapse is not configured with an SMTP server, password reset via email will ## Registering a user -You will need at least one user on your server in order to use a Matrix -client. Users can be registered either via a Matrix client, or via a -commandline script. +The easiest way to create a new user is to do so from a client like [Riot](https://riot.im). -To get started, it is easiest to use the command line to register new -users. This can be done as follows: +Alternatively you can do so from the command line if you have installed via pip. + +This can be done as follows: ``` $ source ~/synapse/env/bin/activate diff --git a/changelog.d/5633.bugfix b/changelog.d/5633.bugfix new file mode 100644 index 0000000000..b2ff803b9d --- /dev/null +++ b/changelog.d/5633.bugfix @@ -0,0 +1 @@ +Don't create broken room when power_level_content_override.users does not contain creator_id. \ No newline at end of file diff --git a/changelog.d/5856.feature b/changelog.d/5856.feature new file mode 100644 index 0000000000..f4310b9244 --- /dev/null +++ b/changelog.d/5856.feature @@ -0,0 +1 @@ +Add a tag recording a request's authenticated entity and corresponding servlet in opentracing. diff --git a/changelog.d/5857.bugfix b/changelog.d/5857.bugfix new file mode 100644 index 0000000000..008799ccbb --- /dev/null +++ b/changelog.d/5857.bugfix @@ -0,0 +1 @@ +Fix database index so that different backup versions can have the same sessions. diff --git a/changelog.d/5863.bugfix b/changelog.d/5863.bugfix new file mode 100644 index 0000000000..bceae5be67 --- /dev/null +++ b/changelog.d/5863.bugfix @@ -0,0 +1 @@ +Fix Synapse looking for config options `password_reset_failure_template` and `password_reset_success_template`, when they are actually `password_reset_template_failure_html`, `password_reset_template_success_html`. diff --git a/debian/changelog b/debian/changelog index 6634c1085a..76efc442d7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,18 @@ -matrix-synapse-py3 (1.2.1) stable; urgency=medium +matrix-synapse-py3 (1.3.1) stable; urgency=medium - * New synapse release 1.2.1. + * New synapse release 1.3.1. - -- Synapse Packaging team <packages@matrix.org> Fri, 26 Jul 2019 11:32:47 +0100 + -- Synapse Packaging team <packages@matrix.org> Sat, 17 Aug 2019 09:15:49 +0100 + +matrix-synapse-py3 (1.3.0) stable; urgency=medium + + [ Andrew Morgan ] + * Remove libsqlite3-dev from required build dependencies. + + [ Synapse Packaging team ] + * New synapse release 1.3.0. + + -- Synapse Packaging team <packages@matrix.org> Thu, 15 Aug 2019 12:04:23 +0100 matrix-synapse-py3 (1.2.0) stable; urgency=medium diff --git a/debian/control b/debian/control index 9e679c9d42..bae14b41e4 100644 --- a/debian/control +++ b/debian/control @@ -15,7 +15,6 @@ Build-Depends: python3-setuptools, python3-pip, python3-venv, - libsqlite3-dev, tar, Standards-Version: 3.9.8 Homepage: https://github.com/matrix-org/synapse diff --git a/synapse/__init__.py b/synapse/__init__.py index d2316c7df9..6766ef445c 100644 --- a/synapse/__init__.py +++ b/synapse/__init__.py @@ -35,4 +35,4 @@ try: except ImportError: pass -__version__ = "1.3.0rc1" +__version__ = "1.3.1" diff --git a/synapse/api/auth.py b/synapse/api/auth.py index 179644852a..7b3a5a8221 100644 --- a/synapse/api/auth.py +++ b/synapse/api/auth.py @@ -22,6 +22,7 @@ from netaddr import IPAddress from twisted.internet import defer +import synapse.logging.opentracing as opentracing import synapse.types from synapse import event_auth from synapse.api.constants import EventTypes, JoinRules, Membership @@ -178,6 +179,7 @@ class Auth(object): def get_public_keys(self, invite_event): return event_auth.get_public_keys(invite_event) + @opentracing.trace @defer.inlineCallbacks def get_user_by_req( self, request, allow_guest=False, rights="access", allow_expired=False @@ -209,6 +211,7 @@ class Auth(object): user_id, app_service = yield self._get_appservice_user_id(request) if user_id: request.authenticated_entity = user_id + opentracing.set_tag("authenticated_entity", user_id) if ip_addr and self.hs.config.track_appservice_user_ips: yield self.store.insert_client_ip( @@ -259,6 +262,7 @@ class Auth(object): ) request.authenticated_entity = user.to_string() + opentracing.set_tag("authenticated_entity", user.to_string()) return synapse.types.create_requester( user, token_id, is_guest, device_id, app_service=app_service diff --git a/synapse/app/_base.py b/synapse/app/_base.py index c010e70955..69dcf3523f 100644 --- a/synapse/app/_base.py +++ b/synapse/app/_base.py @@ -17,10 +17,10 @@ import gc import logging import os import signal +import socket import sys import traceback -import sdnotify from daemonize import Daemonize from twisted.internet import defer, error, reactor @@ -246,13 +246,12 @@ def start(hs, listeners=None): def handle_sighup(*args, **kwargs): # Tell systemd our state, if we're using it. This will silently fail if # we're not using systemd. - sd_channel = sdnotify.SystemdNotifier() - sd_channel.notify("RELOADING=1") + sdnotify(b"RELOADING=1") for i in _sighup_callbacks: i(hs) - sd_channel.notify("READY=1") + sdnotify(b"READY=1") signal.signal(signal.SIGHUP, handle_sighup) @@ -308,16 +307,12 @@ def setup_sdnotify(hs): # Tell systemd our state, if we're using it. This will silently fail if # we're not using systemd. - sd_channel = sdnotify.SystemdNotifier() - hs.get_reactor().addSystemEventTrigger( - "after", - "startup", - lambda: sd_channel.notify("READY=1\nMAINPID=%s" % (os.getpid())), + "after", "startup", sdnotify, b"READY=1\nMAINPID=%i" % (os.getpid(),) ) hs.get_reactor().addSystemEventTrigger( - "before", "shutdown", lambda: sd_channel.notify("STOPPING=1") + "before", "shutdown", sdnotify, b"STOPPING=1" ) @@ -414,3 +409,35 @@ class _DeferredResolutionReceiver(object): def resolutionComplete(self): self._deferred.callback(()) self._receiver.resolutionComplete() + + +sdnotify_sockaddr = os.getenv("NOTIFY_SOCKET") + + +def sdnotify(state): + """ + Send a notification to systemd, if the NOTIFY_SOCKET env var is set. + + This function is based on the sdnotify python package, but since it's only a few + lines of code, it's easier to duplicate it here than to add a dependency on a + package which many OSes don't include as a matter of principle. + + Args: + state (bytes): notification to send + """ + if not isinstance(state, bytes): + raise TypeError("sdnotify should be called with a bytes") + if not sdnotify_sockaddr: + return + addr = sdnotify_sockaddr + if addr[0] == "@": + addr = "\0" + addr[1:] + + try: + with socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) as sock: + sock.connect(addr) + sock.sendall(state) + except Exception as e: + # this is a bit surprising, since we don't expect to have a NOTIFY_SOCKET + # unless systemd is expecting us to notify it. + logger.warning("Unable to send notification to systemd: %s", e) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 7d6b51b5bc..8233905844 100644 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -447,7 +447,7 @@ def setup(config_options): reactor.stop() sys.exit(1) - reactor.addSystemEventTrigger("before", "startup", start) + reactor.callWhenRunning(start) return hs diff --git a/synapse/config/emailconfig.py b/synapse/config/emailconfig.py index 8381b8eb29..36d01a10af 100644 --- a/synapse/config/emailconfig.py +++ b/synapse/config/emailconfig.py @@ -132,21 +132,21 @@ class EmailConfig(Config): self.email_password_reset_template_text = email_config.get( "password_reset_template_text", "password_reset.txt" ) - self.email_password_reset_failure_template = email_config.get( - "password_reset_failure_template", "password_reset_failure.html" + self.email_password_reset_template_failure_html = email_config.get( + "password_reset_template_failure_html", "password_reset_failure.html" ) # This template does not support any replaceable variables, so we will # read it from the disk once during setup - email_password_reset_success_template = email_config.get( - "password_reset_success_template", "password_reset_success.html" + email_password_reset_template_success_html = email_config.get( + "password_reset_template_success_html", "password_reset_success.html" ) # Check templates exist for f in [ self.email_password_reset_template_html, self.email_password_reset_template_text, - self.email_password_reset_failure_template, - email_password_reset_success_template, + self.email_password_reset_template_failure_html, + email_password_reset_template_success_html, ]: p = os.path.join(self.email_template_dir, f) if not os.path.isfile(p): @@ -154,9 +154,9 @@ class EmailConfig(Config): # Retrieve content of web templates filepath = os.path.join( - self.email_template_dir, email_password_reset_success_template + self.email_template_dir, email_password_reset_template_success_html ) - self.email_password_reset_success_html_content = self.read_file( + self.email_password_reset_template_success_html_content = self.read_file( filepath, "email.password_reset_template_success_html" ) diff --git a/synapse/federation/transport/server.py b/synapse/federation/transport/server.py index ea4e1b6d0f..a17148fc3c 100644 --- a/synapse/federation/transport/server.py +++ b/synapse/federation/transport/server.py @@ -19,8 +19,9 @@ import functools import logging import re +from twisted.internet.defer import maybeDeferred + import synapse -import synapse.logging.opentracing as opentracing from synapse.api.errors import Codes, FederationDeniedError, SynapseError from synapse.api.room_versions import RoomVersions from synapse.api.urls import ( @@ -37,6 +38,7 @@ from synapse.http.servlet import ( parse_string_from_args, ) from synapse.logging.context import run_in_background +from synapse.logging.opentracing import start_active_span_from_context, tags from synapse.types import ThirdPartyInstanceID, get_domain_from_id from synapse.util.ratelimitutils import FederationRateLimiter from synapse.util.versionstring import get_version_string @@ -287,16 +289,17 @@ class BaseFederationServlet(object): raise # Start an opentracing span - with opentracing.start_active_span_from_context( + with start_active_span_from_context( request.requestHeaders, "incoming-federation-request", tags={ "request_id": request.get_request_id(), - opentracing.tags.SPAN_KIND: opentracing.tags.SPAN_KIND_RPC_SERVER, - opentracing.tags.HTTP_METHOD: request.get_method(), - opentracing.tags.HTTP_URL: request.get_redacted_uri(), - opentracing.tags.PEER_HOST_IPV6: request.getClientIP(), + tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER, + tags.HTTP_METHOD: request.get_method(), + tags.HTTP_URL: request.get_redacted_uri(), + tags.PEER_HOST_IPV6: request.getClientIP(), "authenticated_entity": origin, + "servlet_name": request.request_metrics.name, }, ): if origin: @@ -745,8 +748,12 @@ class PublicRoomList(BaseFederationServlet): else: network_tuple = ThirdPartyInstanceID(None, None) - data = await self.handler.get_local_public_room_list( - limit, since_token, network_tuple=network_tuple, from_federation=True + data = await maybeDeferred( + self.handler.get_local_public_room_list, + limit, + since_token, + network_tuple=network_tuple, + from_federation=True, ) return 200, data diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py index 5caa90c3b7..6e47fe7867 100644 --- a/synapse/handlers/room.py +++ b/synapse/handlers/room.py @@ -560,6 +560,18 @@ class RoomCreationHandler(BaseHandler): yield self.event_creation_handler.assert_accepted_privacy_policy(requester) + power_level_content_override = config.get("power_level_content_override") + if ( + power_level_content_override + and "users" in power_level_content_override + and user_id not in power_level_content_override["users"] + ): + raise SynapseError( + 400, + "Not a valid power_level_content_override: 'users' did not contain %s" + % (user_id,), + ) + invite_3pid_list = config.get("invite_3pid", []) visibility = config.get("visibility", None) @@ -604,7 +616,7 @@ class RoomCreationHandler(BaseHandler): initial_state=initial_state, creation_content=creation_content, room_alias=room_alias, - power_level_content_override=config.get("power_level_content_override"), + power_level_content_override=power_level_content_override, creator_join_profile=creator_join_profile, ) diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py index d07d356464..4326e98a28 100644 --- a/synapse/http/matrixfederationclient.py +++ b/synapse/http/matrixfederationclient.py @@ -36,7 +36,6 @@ from twisted.internet.task import _EPSILON, Cooperator from twisted.web._newclient import ResponseDone from twisted.web.http_headers import Headers -import synapse.logging.opentracing as opentracing import synapse.metrics import synapse.util.retryutils from synapse.api.errors import ( @@ -50,6 +49,12 @@ from synapse.http import QuieterFileBodyProducer from synapse.http.client import BlacklistingAgentWrapper, IPBlacklistingResolver from synapse.http.federation.matrix_federation_agent import MatrixFederationAgent from synapse.logging.context import make_deferred_yieldable +from synapse.logging.opentracing import ( + inject_active_span_byte_dict, + set_tag, + start_active_span, + tags, +) from synapse.util.async_helpers import timeout_deferred from synapse.util.metrics import Measure @@ -341,20 +346,20 @@ class MatrixFederationHttpClient(object): query_bytes = b"" # Retreive current span - scope = opentracing.start_active_span( + scope = start_active_span( "outgoing-federation-request", tags={ - opentracing.tags.SPAN_KIND: opentracing.tags.SPAN_KIND_RPC_CLIENT, - opentracing.tags.PEER_ADDRESS: request.destination, - opentracing.tags.HTTP_METHOD: request.method, - opentracing.tags.HTTP_URL: request.path, + tags.SPAN_KIND: tags.SPAN_KIND_RPC_CLIENT, + tags.PEER_ADDRESS: request.destination, + tags.HTTP_METHOD: request.method, + tags.HTTP_URL: request.path, }, finish_on_close=True, ) # Inject the span into the headers headers_dict = {} - opentracing.inject_active_span_byte_dict(headers_dict, request.destination) + inject_active_span_byte_dict(headers_dict, request.destination) headers_dict[b"User-Agent"] = [self.version_string_bytes] @@ -436,9 +441,7 @@ class MatrixFederationHttpClient(object): response.phrase.decode("ascii", errors="replace"), ) - opentracing.set_tag( - opentracing.tags.HTTP_STATUS_CODE, response.code - ) + set_tag(tags.HTTP_STATUS_CODE, response.code) if 200 <= response.code < 300: pass diff --git a/synapse/python_dependencies.py b/synapse/python_dependencies.py index 195a7a70c8..c6465c0386 100644 --- a/synapse/python_dependencies.py +++ b/synapse/python_dependencies.py @@ -72,7 +72,6 @@ REQUIREMENTS = [ "netaddr>=0.7.18", "Jinja2>=2.9", "bleach>=1.4.3", - "sdnotify>=0.3", ] CONDITIONAL_REQUIREMENTS = { diff --git a/synapse/rest/client/v2_alpha/account.py b/synapse/rest/client/v2_alpha/account.py index 7ac456812a..934ed5d16d 100644 --- a/synapse/rest/client/v2_alpha/account.py +++ b/synapse/rest/client/v2_alpha/account.py @@ -282,13 +282,13 @@ class PasswordResetSubmitTokenServlet(RestServlet): return None # Otherwise show the success template - html = self.config.email_password_reset_success_html_content + html = self.config.email_password_reset_template_success_html_content request.setResponseCode(200) except ThreepidValidationError as e: # Show a failure page with a reason html = self.load_jinja2_template( self.config.email_template_dir, - self.config.email_password_reset_failure_template, + self.config.email_password_reset_template_failure_html, template_vars={"failure_reason": e.msg}, ) request.setResponseCode(e.code) diff --git a/synapse/storage/e2e_room_keys.py b/synapse/storage/e2e_room_keys.py index 99128f2df7..b1901404af 100644 --- a/synapse/storage/e2e_room_keys.py +++ b/synapse/storage/e2e_room_keys.py @@ -82,11 +82,11 @@ class EndToEndRoomKeyStore(SQLBaseStore): table="e2e_room_keys", keyvalues={ "user_id": user_id, + "version": version, "room_id": room_id, "session_id": session_id, }, values={ - "version": version, "first_message_index": room_key["first_message_index"], "forwarded_count": room_key["forwarded_count"], "is_verified": room_key["is_verified"], diff --git a/synapse/storage/schema/delta/56/fix_room_keys_index.sql b/synapse/storage/schema/delta/56/fix_room_keys_index.sql new file mode 100644 index 0000000000..014cb3b538 --- /dev/null +++ b/synapse/storage/schema/delta/56/fix_room_keys_index.sql @@ -0,0 +1,18 @@ +/* Copyright 2019 Matrix.org Foundation CIC + * + * 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. + */ + +-- version is supposed to be part of the room keys index +CREATE UNIQUE INDEX e2e_room_keys_with_version_idx ON e2e_room_keys(user_id, version, room_id, session_id); +DROP INDEX IF EXISTS e2e_room_keys_idx; |