From 8751f0ef32836a4c349bd0b50ac4a77934a5dbf0 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Mon, 27 Nov 2023 15:16:20 +0000 Subject: Fix poetry version typo in contributors' guide (#16695) --- docs/development/contributing_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/development/contributing_guide.md b/docs/development/contributing_guide.md index 2efb4099e5..57cac7ed16 100644 --- a/docs/development/contributing_guide.md +++ b/docs/development/contributing_guide.md @@ -66,7 +66,7 @@ Of their installation methods, we recommend ```shell pip install --user pipx -pipx install poetry==1.5.2 # Problems with Poetry 1.6, see https://github.com/matrix-org/synapse/issues/16147 +pipx install poetry==1.5.1 # Problems with Poetry 1.6, see https://github.com/matrix-org/synapse/issues/16147 ``` but see poetry's [installation instructions](https://python-poetry.org/docs/#installation) -- cgit 1.5.1 From 77882b6a7d1ad1ab76b0ff878b3daed894bdb26e Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Tue, 28 Nov 2023 11:01:24 -0500 Subject: Document which versions of Synapse have compatible schema versions. (#16661) --- .github/workflows/docs-pr.yaml | 11 +++ .github/workflows/docs.yaml | 10 +++ book.toml | 5 +- changelog.d/16661.doc | 1 + docs/upgrade.md | 9 ++ scripts-dev/schema_versions.py | 181 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 changelog.d/16661.doc create mode 100755 scripts-dev/schema_versions.py (limited to 'docs') diff --git a/.github/workflows/docs-pr.yaml b/.github/workflows/docs-pr.yaml index 3704bd66e2..9cf3d340a4 100644 --- a/.github/workflows/docs-pr.yaml +++ b/.github/workflows/docs-pr.yaml @@ -6,6 +6,7 @@ on: - docs/** - book.toml - .github/workflows/docs-pr.yaml + - scripts-dev/schema_versions.py jobs: pages: @@ -13,12 +14,22 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + # Fetch all history so that the schema_versions script works. + fetch-depth: 0 - name: Setup mdbook uses: peaceiris/actions-mdbook@adeb05db28a0c0004681db83893d56c0388ea9ea # v1.2.0 with: mdbook-version: '0.4.17' + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - run: "pip install 'packaging>=20.0' 'GitPython>=3.1.20'" + - name: Build the documentation # mdbook will only create an index.html if we're including docs/README.md in SUMMARY.md. # However, we're using docs/README.md for other purposes and need to pick a new page diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index c7cb2d78e5..31b9dbe3fe 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -51,12 +51,22 @@ jobs: - pre steps: - uses: actions/checkout@v4 + with: + # Fetch all history so that the schema_versions script works. + fetch-depth: 0 - name: Setup mdbook uses: peaceiris/actions-mdbook@adeb05db28a0c0004681db83893d56c0388ea9ea # v1.2.0 with: mdbook-version: '0.4.17' + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - run: "pip install 'packaging>=20.0' 'GitPython>=3.1.20'" + - name: Build the documentation # mdbook will only create an index.html if we're including docs/README.md in SUMMARY.md. # However, we're using docs/README.md for other purposes and need to pick a new page diff --git a/book.toml b/book.toml index fa83d86ffc..ed3f6151e0 100644 --- a/book.toml +++ b/book.toml @@ -36,4 +36,7 @@ additional-css = [ "docs/website_files/indent-section-headers.css", ] additional-js = ["docs/website_files/table-of-contents.js"] -theme = "docs/website_files/theme" \ No newline at end of file +theme = "docs/website_files/theme" + +[preprocessor.schema_versions] +command = "./scripts-dev/schema_versions.py" diff --git a/changelog.d/16661.doc b/changelog.d/16661.doc new file mode 100644 index 0000000000..74f8fc84b8 --- /dev/null +++ b/changelog.d/16661.doc @@ -0,0 +1 @@ +Add schema rollback information to documentation. diff --git a/docs/upgrade.md b/docs/upgrade.md index ba2f7703bc..329c9c7787 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -88,6 +88,15 @@ process, for example: dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb ``` +Generally Synapse database schemas are compatible across multiple versions, once +a version of Synapse is deployed you may not be able to rollback automatically. +The following table gives the version ranges and the earliest version they can +be rolled back to. E.g. Synapse versions v1.58.0 through v1.61.1 can be rolled +back safely to v1.57.0, but starting with v1.62.0 it is only safe to rollback to +v1.61.0. + + + # Upgrading to v1.93.0 ## Minimum supported Rust version diff --git a/scripts-dev/schema_versions.py b/scripts-dev/schema_versions.py new file mode 100755 index 0000000000..5fd73251cd --- /dev/null +++ b/scripts-dev/schema_versions.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python +# Copyright 2023 The Matrix.org Foundation C.I.C. +# +# 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. + +"""A script to calculate which versions of Synapse have backwards-compatible +database schemas. It creates a Markdown table of Synapse versions and the earliest +compatible version. + +It is compatible with the mdbook protocol for preprocessors (see +https://rust-lang.github.io/mdBook/for_developers/preprocessors.html#implementing-a-preprocessor-with-a-different-language): + +Exit 0 to denote support for all renderers: + + ./scripts-dev/schema_versions.py supports + +Parse a JSON list from stdin and add the table to the proper documetnation page: + + ./scripts-dev/schema_versions.py + +Additionally, the script supports dumping the table to stdout for debugging: + + ./scripts-dev/schema_versions.py dump +""" + +import io +import json +import sys +from collections import defaultdict +from typing import Any, Dict, Iterator, Optional, Tuple + +import git +from packaging import version + +# The schema version has moved around over the years. +SCHEMA_VERSION_FILES = ( + "synapse/storage/schema/__init__.py", + "synapse/storage/prepare_database.py", + "synapse/storage/__init__.py", + "synapse/app/homeserver.py", +) + + +# Skip versions of Synapse < v1.0, they're old and essentially not +# compatible with today's federation. +OLDEST_SHOWN_VERSION = version.parse("v1.0") + + +def get_schema_versions(tag: git.Tag) -> Tuple[Optional[int], Optional[int]]: + """Get the schema and schema compat versions for a tag.""" + schema_version = None + schema_compat_version = None + + for file in SCHEMA_VERSION_FILES: + try: + schema_file = tag.commit.tree / file + except KeyError: + continue + + # We (usually) can't execute the code since it might have unknown imports. + if file != "synapse/storage/schema/__init__.py": + with io.BytesIO(schema_file.data_stream.read()) as f: + for line in f.readlines(): + if line.startswith(b"SCHEMA_VERSION"): + schema_version = int(line.split()[2]) + + # Bail early. + break + else: + # SCHEMA_COMPAT_VERSION is sometimes across multiple lines, the easist + # thing to do is exec the code. Luckily it has only ever existed in + # a file which imports nothing else from Synapse. + locals: Dict[str, Any] = {} + exec(schema_file.data_stream.read().decode("utf-8"), {}, locals) + schema_version = locals["SCHEMA_VERSION"] + schema_compat_version = locals.get("SCHEMA_COMPAT_VERSION") + + return schema_version, schema_compat_version + + +def get_tags(repo: git.Repo) -> Iterator[git.Tag]: + """Return an iterator of tags sorted by version.""" + tags = [] + for tag in repo.tags: + # All "real" Synapse tags are of the form vX.Y.Z. + if not tag.name.startswith("v"): + continue + + # There's a weird tag from the initial react UI. + if tag.name == "v0.1": + continue + + try: + tag_version = version.parse(tag.name) + except version.InvalidVersion: + # Skip invalid versions. + continue + + # Skip pre- and post-release versions. + if tag_version.is_prerelease or tag_version.is_postrelease or tag_version.local: + continue + + # Skip old versions. + if tag_version < OLDEST_SHOWN_VERSION: + continue + + tags.append((tag_version, tag)) + + # Sort based on the version number (not lexically). + return (tag for _, tag in sorted(tags, key=lambda t: t[0])) + + +def calculate_version_chart() -> str: + repo = git.Repo(path=".") + + # Map of schema version -> Synapse versions which are at that schema version. + schema_versions = defaultdict(list) + # Map of schema version -> Synapse versions which are compatible with that + # schema version. + schema_compat_versions = defaultdict(list) + + # Find ranges of versions which are compatible with a schema version. + # + # There are two modes of operation: + # + # 1. Pre-schema_compat_version (i.e. schema_compat_version of None), then + # Synapse is compatible up/downgrading to a version with + # schema_version >= its current version. + # + # 2. Post-schema_compat_version (i.e. schema_compat_version is *not* None), + # then Synapse is compatible up/downgrading to a version with + # schema version >= schema_compat_version. + # + # This is more generous and avoids versions that cannot be rolled back. + # + # See https://github.com/matrix-org/synapse/pull/9933 which was included in v1.37.0. + for tag in get_tags(repo): + schema_version, schema_compat_version = get_schema_versions(tag) + + # If a schema compat version is given, prefer that over the schema version. + schema_versions[schema_version].append(tag.name) + schema_compat_versions[schema_compat_version or schema_version].append(tag.name) + + # Generate a table which maps the latest Synapse version compatible with each + # schema version. + result = f"| {'Versions': ^19} | Compatible version |\n" + result += f"|{'-' * (19 + 2)}|{'-' * (18 + 2)}|\n" + for schema_version, synapse_versions in schema_compat_versions.items(): + result += f"| {synapse_versions[0] + ' – ' + synapse_versions[-1]: ^19} | {schema_versions[schema_version][0]: ^18} |\n" + + return result + + +if __name__ == "__main__": + if len(sys.argv) == 3 and sys.argv[1] == "supports": + # We don't care about the renderer which is being used, which is the second argument. + sys.exit(0) + elif len(sys.argv) == 2 and sys.argv[1] == "dump": + print(calculate_version_chart()) + else: + # Expect JSON data on stdin. + context, book = json.load(sys.stdin) + + for section in book["sections"]: + if "Chapter" in section and section["Chapter"]["path"] == "upgrade.md": + section["Chapter"]["content"] = section["Chapter"]["content"].replace( + "", calculate_version_chart() + ) + + # Print the result back out to stdout. + print(json.dumps(book)) -- cgit 1.5.1 From 63d96bfc61fcbf53e9607c63f215d2dde387de29 Mon Sep 17 00:00:00 2001 From: Andrew Yasinishyn Date: Fri, 1 Dec 2023 16:31:50 +0200 Subject: ModuleAPI SSO auth callbacks (#15207) Signed-off-by: Andrii Yasynyshyn yasinishyn.a.n@gmail.com --- changelog.d/15207.feature | 1 + docs/modules/account_validity_callbacks.md | 13 +++++++++++++ rust/src/push/mod.rs | 3 +-- synapse/handlers/account_validity.py | 16 ++++++++++++++++ synapse/handlers/auth.py | 8 ++++++++ synapse/module_api/__init__.py | 3 +++ .../module_api/callbacks/account_validity_callbacks.py | 6 ++++++ synapse/rest/client/login.py | 8 ++++++++ 8 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 changelog.d/15207.feature (limited to 'docs') diff --git a/changelog.d/15207.feature b/changelog.d/15207.feature new file mode 100644 index 0000000000..17790d62eb --- /dev/null +++ b/changelog.d/15207.feature @@ -0,0 +1 @@ +Adds on_user_login ModuleAPI callback allowing to execute custom code after (on) Auth. \ No newline at end of file diff --git a/docs/modules/account_validity_callbacks.md b/docs/modules/account_validity_callbacks.md index 3cd0e72198..f5eefcd7d6 100644 --- a/docs/modules/account_validity_callbacks.md +++ b/docs/modules/account_validity_callbacks.md @@ -42,3 +42,16 @@ operations to keep track of them. (e.g. add them to a database table). The user represented by their Matrix user ID. If multiple modules implement this callback, Synapse runs them all in order. + +### `on_user_login` + +_First introduced in Synapse v1.98.0_ + +```python +async def on_user_login(user_id: str, auth_provider_type: str, auth_provider_id: str) -> None +``` + +Called after successfully login or registration of a user for cases when module needs to perform extra operations after auth. +represented by their Matrix user ID. + +If multiple modules implement this callback, Synapse runs them all in order. diff --git a/rust/src/push/mod.rs b/rust/src/push/mod.rs index 5e1e8e1abb..68d4227baa 100644 --- a/rust/src/push/mod.rs +++ b/rust/src/push/mod.rs @@ -296,8 +296,7 @@ impl<'source> FromPyObject<'source> for JsonValue { match l.iter().map(SimpleJsonValue::extract).collect() { Ok(a) => Ok(JsonValue::Array(a)), Err(e) => Err(PyTypeError::new_err(format!( - "Can't convert to JsonValue::Array: {}", - e + "Can't convert to JsonValue::Array: {e}" ))), } } else if let Ok(v) = SimpleJsonValue::extract(ob) { diff --git a/synapse/handlers/account_validity.py b/synapse/handlers/account_validity.py index 6c2a49a3b9..c66bb6364f 100644 --- a/synapse/handlers/account_validity.py +++ b/synapse/handlers/account_validity.py @@ -98,6 +98,22 @@ class AccountValidityHandler: for callback in self._module_api_callbacks.on_user_registration_callbacks: await callback(user_id) + async def on_user_login( + self, + user_id: str, + auth_provider_type: Optional[str], + auth_provider_id: Optional[str], + ) -> None: + """Tell third-party modules about a user logins. + + Args: + user_id: The mxID of the user. + auth_provider_type: The type of login. + auth_provider_id: The ID of the auth provider. + """ + for callback in self._module_api_callbacks.on_user_login_callbacks: + await callback(user_id, auth_provider_type, auth_provider_id) + @wrap_as_background_process("send_renewals") async def _send_renewal_emails(self) -> None: """Gets the list of users whose account is expiring in the amount of time diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index 2b0c505130..89cbaff864 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -212,6 +212,7 @@ class AuthHandler: self._password_enabled_for_reauth = hs.config.auth.password_enabled_for_reauth self._password_localdb_enabled = hs.config.auth.password_localdb_enabled self._third_party_rules = hs.get_module_api_callbacks().third_party_event_rules + self._account_validity_handler = hs.get_account_validity_handler() # Ratelimiter for failed auth during UIA. Uses same ratelimit config # as per `rc_login.failed_attempts`. @@ -1783,6 +1784,13 @@ class AuthHandler: client_redirect_url, "loginToken", login_token ) + # Run post-login module callback handlers + await self._account_validity_handler.on_user_login( + user_id=registered_user_id, + auth_provider_type=LoginType.SSO, + auth_provider_id=auth_provider_id, + ) + # if the client is whitelisted, we can redirect straight to it if client_redirect_url.startswith(self._whitelisted_sso_clients): request.redirect(redirect_url) diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py index 812144a128..6ee53511f2 100644 --- a/synapse/module_api/__init__.py +++ b/synapse/module_api/__init__.py @@ -80,6 +80,7 @@ from synapse.module_api.callbacks.account_validity_callbacks import ( ON_LEGACY_ADMIN_REQUEST, ON_LEGACY_RENEW_CALLBACK, ON_LEGACY_SEND_MAIL_CALLBACK, + ON_USER_LOGIN_CALLBACK, ON_USER_REGISTRATION_CALLBACK, ) from synapse.module_api.callbacks.spamchecker_callbacks import ( @@ -334,6 +335,7 @@ class ModuleApi: *, is_user_expired: Optional[IS_USER_EXPIRED_CALLBACK] = None, on_user_registration: Optional[ON_USER_REGISTRATION_CALLBACK] = None, + on_user_login: Optional[ON_USER_LOGIN_CALLBACK] = None, on_legacy_send_mail: Optional[ON_LEGACY_SEND_MAIL_CALLBACK] = None, on_legacy_renew: Optional[ON_LEGACY_RENEW_CALLBACK] = None, on_legacy_admin_request: Optional[ON_LEGACY_ADMIN_REQUEST] = None, @@ -345,6 +347,7 @@ class ModuleApi: return self._callbacks.account_validity.register_callbacks( is_user_expired=is_user_expired, on_user_registration=on_user_registration, + on_user_login=on_user_login, on_legacy_send_mail=on_legacy_send_mail, on_legacy_renew=on_legacy_renew, on_legacy_admin_request=on_legacy_admin_request, diff --git a/synapse/module_api/callbacks/account_validity_callbacks.py b/synapse/module_api/callbacks/account_validity_callbacks.py index 531d0c9ddc..cbfdfbd3d1 100644 --- a/synapse/module_api/callbacks/account_validity_callbacks.py +++ b/synapse/module_api/callbacks/account_validity_callbacks.py @@ -22,6 +22,7 @@ logger = logging.getLogger(__name__) # Types for callbacks to be registered via the module api IS_USER_EXPIRED_CALLBACK = Callable[[str], Awaitable[Optional[bool]]] ON_USER_REGISTRATION_CALLBACK = Callable[[str], Awaitable] +ON_USER_LOGIN_CALLBACK = Callable[[str, Optional[str], Optional[str]], Awaitable] # Temporary hooks to allow for a transition from `/_matrix/client` endpoints # to `/_synapse/client/account_validity`. See `register_callbacks` below. ON_LEGACY_SEND_MAIL_CALLBACK = Callable[[str], Awaitable] @@ -33,6 +34,7 @@ class AccountValidityModuleApiCallbacks: def __init__(self) -> None: self.is_user_expired_callbacks: List[IS_USER_EXPIRED_CALLBACK] = [] self.on_user_registration_callbacks: List[ON_USER_REGISTRATION_CALLBACK] = [] + self.on_user_login_callbacks: List[ON_USER_LOGIN_CALLBACK] = [] self.on_legacy_send_mail_callback: Optional[ON_LEGACY_SEND_MAIL_CALLBACK] = None self.on_legacy_renew_callback: Optional[ON_LEGACY_RENEW_CALLBACK] = None @@ -44,6 +46,7 @@ class AccountValidityModuleApiCallbacks: self, is_user_expired: Optional[IS_USER_EXPIRED_CALLBACK] = None, on_user_registration: Optional[ON_USER_REGISTRATION_CALLBACK] = None, + on_user_login: Optional[ON_USER_LOGIN_CALLBACK] = None, on_legacy_send_mail: Optional[ON_LEGACY_SEND_MAIL_CALLBACK] = None, on_legacy_renew: Optional[ON_LEGACY_RENEW_CALLBACK] = None, on_legacy_admin_request: Optional[ON_LEGACY_ADMIN_REQUEST] = None, @@ -55,6 +58,9 @@ class AccountValidityModuleApiCallbacks: if on_user_registration is not None: self.on_user_registration_callbacks.append(on_user_registration) + if on_user_login is not None: + self.on_user_login_callbacks.append(on_user_login) + # The builtin account validity feature exposes 3 endpoints (send_mail, renew, and # an admin one). As part of moving the feature into a module, we need to change # the path from /_matrix/client/unstable/account_validity/... to diff --git a/synapse/rest/client/login.py b/synapse/rest/client/login.py index 7be327e26f..546f042f87 100644 --- a/synapse/rest/client/login.py +++ b/synapse/rest/client/login.py @@ -115,6 +115,7 @@ class LoginRestServlet(RestServlet): self.registration_handler = hs.get_registration_handler() self._sso_handler = hs.get_sso_handler() self._spam_checker = hs.get_module_api_callbacks().spam_checker + self._account_validity_handler = hs.get_account_validity_handler() self._well_known_builder = WellKnownBuilder(hs) self._address_ratelimiter = Ratelimiter( @@ -470,6 +471,13 @@ class LoginRestServlet(RestServlet): device_id=device_id, ) + # execute the callback + await self._account_validity_handler.on_user_login( + user_id, + auth_provider_type=login_submission.get("type"), + auth_provider_id=auth_provider_id, + ) + if valid_until_ms is not None: expires_in_ms = valid_until_ms - self.clock.time_msec() result["expires_in_ms"] = expires_in_ms -- cgit 1.5.1 From 9e7f80037d08619cdd193831540d34e9ed5aacd7 Mon Sep 17 00:00:00 2001 From: Mathieu Velten Date: Mon, 4 Dec 2023 13:31:42 +0100 Subject: Server notices: add an autojoin setting for the notices room (#16699) Co-authored-by: Patrick Cloke --- changelog.d/16699.feature | 1 + docs/server_notices.md | 3 +++ docs/usage/configuration/config_documentation.md | 3 +++ synapse/config/server_notices.py | 2 ++ synapse/server_notices/server_notices_manager.py | 15 ++++++++++++- tests/rest/admin/test_server_notice.py | 27 ++++++++++++++++++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 changelog.d/16699.feature (limited to 'docs') diff --git a/changelog.d/16699.feature b/changelog.d/16699.feature new file mode 100644 index 0000000000..7ede50f326 --- /dev/null +++ b/changelog.d/16699.feature @@ -0,0 +1 @@ +Add an autojoin setting for the notices room so users get joined directly instead of receiving an invite. diff --git a/docs/server_notices.md b/docs/server_notices.md index 339d10a0ab..aae25d23b8 100644 --- a/docs/server_notices.md +++ b/docs/server_notices.md @@ -46,6 +46,7 @@ server_notices: system_mxid_display_name: "Server Notices" system_mxid_avatar_url: "mxc://server.com/oumMVlgDnLYFaPVkExemNVVZ" room_name: "Server Notices" + auto_join: true ``` The only compulsory setting is `system_mxid_localpart`, which defines the user @@ -55,6 +56,8 @@ room which will be created. `system_mxid_display_name` and `system_mxid_avatar_url` can be used to set the displayname and avatar of the Server Notices user. +`auto_join` will autojoin users to the notices room instead of sending an invite. + ## Sending notices To send server notices to users you can use the diff --git a/docs/usage/configuration/config_documentation.md b/docs/usage/configuration/config_documentation.md index 7c4e742cd5..812a7d429b 100644 --- a/docs/usage/configuration/config_documentation.md +++ b/docs/usage/configuration/config_documentation.md @@ -3815,6 +3815,8 @@ Sub-options for this setting include: * `system_mxid_display_name`: set the display name of the "notices" user * `system_mxid_avatar_url`: set the avatar for the "notices" user * `room_name`: set the room name of the server notices room +* `auto_join`: boolean. If true, the user will be automatically joined to the room instead of being invited. + Defaults to false. _Added in Synapse 1.98.0._ Example configuration: ```yaml @@ -3823,6 +3825,7 @@ server_notices: system_mxid_display_name: "Server Notices" system_mxid_avatar_url: "mxc://server.com/oumMVlgDnLYFaPVkExemNVVZ" room_name: "Server Notices" + auto_join: true ``` --- ### `enable_room_list_search` diff --git a/synapse/config/server_notices.py b/synapse/config/server_notices.py index ce041abe9b..a8badba0f8 100644 --- a/synapse/config/server_notices.py +++ b/synapse/config/server_notices.py @@ -48,6 +48,7 @@ class ServerNoticesConfig(Config): self.server_notices_mxid_display_name: Optional[str] = None self.server_notices_mxid_avatar_url: Optional[str] = None self.server_notices_room_name: Optional[str] = None + self.server_notices_auto_join: bool = False def read_config(self, config: JsonDict, **kwargs: Any) -> None: c = config.get("server_notices") @@ -62,3 +63,4 @@ class ServerNoticesConfig(Config): self.server_notices_mxid_avatar_url = c.get("system_mxid_avatar_url", None) # todo: i18n self.server_notices_room_name = c.get("room_name", "Server Notices") + self.server_notices_auto_join = c.get("auto_join", False) diff --git a/synapse/server_notices/server_notices_manager.py b/synapse/server_notices/server_notices_manager.py index 44b999677a..2353b5d47f 100644 --- a/synapse/server_notices/server_notices_manager.py +++ b/synapse/server_notices/server_notices_manager.py @@ -224,14 +224,27 @@ class ServerNoticesManager: if room.room_id == room_id: return + user_id_obj = UserID.from_string(user_id) await self._room_member_handler.update_membership( requester=requester, - target=UserID.from_string(user_id), + target=user_id_obj, room_id=room_id, action="invite", ratelimit=False, ) + if self._config.servernotices.server_notices_auto_join: + user_requester = create_requester( + user_id, authenticated_entity=self._server_name + ) + await self._room_member_handler.update_membership( + requester=user_requester, + target=user_id_obj, + room_id=room_id, + action="join", + ratelimit=False, + ) + async def _update_notice_user_profile_if_changed( self, requester: Requester, diff --git a/tests/rest/admin/test_server_notice.py b/tests/rest/admin/test_server_notice.py index dfd14f5751..2398bc503a 100644 --- a/tests/rest/admin/test_server_notice.py +++ b/tests/rest/admin/test_server_notice.py @@ -477,6 +477,33 @@ class ServerNoticeTestCase(unittest.HomeserverTestCase): # second room has new ID self.assertNotEqual(first_room_id, second_room_id) + @override_config( + {"server_notices": {"system_mxid_localpart": "notices", "auto_join": True}} + ) + def test_auto_join(self) -> None: + """ + Tests that the user get automatically joined to the notice room + when `auto_join` setting is used. + """ + # user has no room memberships + self._check_invite_and_join_status(self.other_user, 0, 0) + + # send server notice + server_notice_request_content = { + "user_id": self.other_user, + "content": {"msgtype": "m.text", "body": "test msg one"}, + } + + self.make_request( + "POST", + self.url, + access_token=self.admin_user_tok, + content=server_notice_request_content, + ) + + # user has joined the room + self._check_invite_and_join_status(self.other_user, 0, 1) + @override_config({"server_notices": {"system_mxid_localpart": "notices"}}) def test_update_notice_user_name_when_changed(self) -> None: """ -- cgit 1.5.1 From 0aa4d3b6f7193d9721bd484dae0242ccd0cc10b8 Mon Sep 17 00:00:00 2001 From: villepeh <100730729+villepeh@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:38:46 +0200 Subject: Switch UNIX socket paths to /run, and add a UNIX socket example for HAProxy (#16700) --- changelog.d/16700.doc | 1 + docs/reverse_proxy.md | 6 +++++- docs/usage/configuration/config_documentation.md | 14 +++++++------- 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 changelog.d/16700.doc (limited to 'docs') diff --git a/changelog.d/16700.doc b/changelog.d/16700.doc new file mode 100644 index 0000000000..0d55ad338a --- /dev/null +++ b/changelog.d/16700.doc @@ -0,0 +1 @@ +Switch the example UNIX socket paths to /run. Add HAProxy example configuration for UNIX sockets. diff --git a/docs/reverse_proxy.md b/docs/reverse_proxy.md index fe9519b4b6..20854035d1 100644 --- a/docs/reverse_proxy.md +++ b/docs/reverse_proxy.md @@ -181,7 +181,11 @@ frontend matrix-federation backend matrix server matrix 127.0.0.1:8008 ``` - +Example configuration, if using a UNIX socket. The configuration lines regarding the frontends do not need to be modified. +``` +backend matrix + server matrix unix@/run/synapse/main_public.sock +``` [Delegation](delegate.md) example: ``` diff --git a/docs/usage/configuration/config_documentation.md b/docs/usage/configuration/config_documentation.md index 812a7d429b..e6fcffb570 100644 --- a/docs/usage/configuration/config_documentation.md +++ b/docs/usage/configuration/config_documentation.md @@ -566,7 +566,7 @@ listeners: # Note that x_forwarded will default to true, when using a UNIX socket. Please see # https://matrix-org.github.io/synapse/latest/reverse_proxy.html. # - - path: /var/run/synapse/main_public.sock + - path: /run/synapse/main_public.sock type: http resources: - names: [client, federation] @@ -4218,9 +4218,9 @@ Example configuration(#2, for UNIX sockets): ```yaml instance_map: main: - path: /var/run/synapse/main_replication.sock + path: /run/synapse/main_replication.sock worker1: - path: /var/run/synapse/worker1_replication.sock + path: /run/synapse/worker1_replication.sock ``` --- ### `stream_writers` @@ -4406,13 +4406,13 @@ Example configuration(#2, using UNIX sockets with a `replication` listener): ```yaml worker_listeners: - type: http - path: /var/run/synapse/worker_public.sock + path: /run/synapse/worker_replication.sock resources: - - names: [client, federation] + - names: [replication] - type: http - path: /var/run/synapse/worker_replication.sock + path: /run/synapse/worker_public.sock resources: - - names: [replication] + - names: [client, federation] ``` --- ### `worker_manhole` -- cgit 1.5.1