diff options
author | Brendan Abolivier <babolivier@matrix.org> | 2022-03-24 11:58:31 +0000 |
---|---|---|
committer | Brendan Abolivier <babolivier@matrix.org> | 2022-03-24 11:58:31 +0000 |
commit | 98917fb6df922d1c76b7ebbfe005378f03bc1f0e (patch) | |
tree | 0bcad58b2072c59290da31bb220d832b0e19c795 /synapse | |
parent | Add a configuration option for rewriting base URLs when interacting with ISs (diff) | |
parent | Optionally include account validity in MSC3720 account status responses (#12266) (diff) | |
download | synapse-98917fb6df922d1c76b7ebbfe005378f03bc1f0e.tar.xz |
Merge branch 'develop' of github.com:matrix-org/synapse into babolivier/rewrite_is_url
Diffstat (limited to 'synapse')
-rw-r--r-- | synapse/__init__.py | 2 | ||||
-rw-r--r-- | synapse/config/database.py | 6 | ||||
-rw-r--r-- | synapse/config/server.py | 4 | ||||
-rw-r--r-- | synapse/handlers/account.py | 11 | ||||
-rw-r--r-- | synapse/module_api/__init__.py | 4 | ||||
-rw-r--r-- | synapse/res/templates/sso_auth_account_details.html | 8 | ||||
-rw-r--r-- | synapse/res/templates/sso_auth_account_details.js | 2 | ||||
-rw-r--r-- | synapse/res/templates/sso_footer.html | 2 | ||||
-rw-r--r-- | synapse/rest/__init__.py | 4 | ||||
-rw-r--r-- | synapse/rest/client/mutual_rooms.py (renamed from synapse/rest/client/shared_rooms.py) | 21 | ||||
-rw-r--r-- | synapse/storage/database.py | 14 | ||||
-rw-r--r-- | synapse/storage/databases/main/user_directory.py | 6 | ||||
-rw-r--r-- | synapse/storage/engines/__init__.py | 2 | ||||
-rw-r--r-- | synapse/storage/engines/postgres.py | 45 |
14 files changed, 91 insertions, 40 deletions
diff --git a/synapse/__init__.py b/synapse/__init__.py index 870707f476..f0f224d0bb 100644 --- a/synapse/__init__.py +++ b/synapse/__init__.py @@ -68,7 +68,7 @@ try: except ImportError: pass -__version__ = "1.55.0rc1" +__version__ = "1.55.0" if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)): # We import here so that we don't have to install a bunch of deps when diff --git a/synapse/config/database.py b/synapse/config/database.py index 06ccf15cd9..d7f2219f53 100644 --- a/synapse/config/database.py +++ b/synapse/config/database.py @@ -37,6 +37,12 @@ DEFAULT_CONFIG = """\ # 'txn_limit' gives the maximum number of transactions to run per connection # before reconnecting. Defaults to 0, which means no limit. # +# 'allow_unsafe_locale' is an option specific to Postgres. Under the default behavior, Synapse will refuse to +# start if the postgres db is set to a non-C locale. You can override this behavior (which is *not* recommended) +# by setting 'allow_unsafe_locale' to true. Note that doing so may corrupt your database. You can find more information +# here: https://matrix-org.github.io/synapse/latest/postgres.html#fixing-incorrect-collate-or-ctype and here: +# https://wiki.postgresql.org/wiki/Locale_data_changes +# # 'args' gives options which are passed through to the database engine, # except for options starting 'cp_', which are used to configure the Twisted # connection pool. For a reference to valid arguments, see: diff --git a/synapse/config/server.py b/synapse/config/server.py index ef853c12be..bcdcf2f264 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -676,6 +676,10 @@ class ServerConfig(Config): ): raise ConfigError("'custom_template_directory' must be a string") + self.use_account_validity_in_account_status: bool = ( + config.get("use_account_validity_in_account_status") or False + ) + self.identity_server_rewrite_map: Dict[str, str] = ( config.get("rewrite_identity_server_base_urls") or {} ) diff --git a/synapse/handlers/account.py b/synapse/handlers/account.py index d5badf635b..c05a14304c 100644 --- a/synapse/handlers/account.py +++ b/synapse/handlers/account.py @@ -26,6 +26,10 @@ class AccountHandler: self._main_store = hs.get_datastores().main self._is_mine = hs.is_mine self._federation_client = hs.get_federation_client() + self._use_account_validity_in_account_status = ( + hs.config.server.use_account_validity_in_account_status + ) + self._account_validity_handler = hs.get_account_validity_handler() async def get_account_statuses( self, @@ -106,6 +110,13 @@ class AccountHandler: "deactivated": userinfo.is_deactivated, } + if self._use_account_validity_in_account_status: + status[ + "org.matrix.expired" + ] = await self._account_validity_handler.is_user_expired( + user_id.to_string() + ) + return status async def _get_remote_account_statuses( diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py index aa8256b36f..a628faaf65 100644 --- a/synapse/module_api/__init__.py +++ b/synapse/module_api/__init__.py @@ -611,15 +611,18 @@ class ModuleApi: localpart: str, displayname: Optional[str] = None, emails: Optional[List[str]] = None, + admin: bool = False, ) -> "defer.Deferred[str]": """Registers a new user with given localpart and optional displayname, emails. Added in Synapse v1.2.0. + Changed in Synapse v1.56.0: add 'admin' argument to register the user as admin. Args: localpart: The localpart of the new user. displayname: The displayname of the new user. emails: Emails to bind to the new user. + admin: True if the user should be registered as a server admin. Raises: SynapseError if there is an error performing the registration. Check the @@ -633,6 +636,7 @@ class ModuleApi: localpart=localpart, default_display_name=displayname, bind_emails=emails or [], + admin=admin, ) ) diff --git a/synapse/res/templates/sso_auth_account_details.html b/synapse/res/templates/sso_auth_account_details.html index b231aace01..1ba850369a 100644 --- a/synapse/res/templates/sso_auth_account_details.html +++ b/synapse/res/templates/sso_auth_account_details.html @@ -130,13 +130,13 @@ </head> <body> <header> - <h1>Choose your account name</h1> - <p>This is required to create your account on {{ server_name }}, and you can't change this later.</p> + <h1>Create your account</h1> + <p>This is required. Continue to create your account on {{ server_name }}. You can't change this later.</p> </header> <main> <form method="post" class="form__input" id="form"> <div class="username_input" id="username_input"> - <label for="field-username">Username</label> + <label for="field-username">Username (required)</label> <div class="prefix">@</div> <input type="text" name="username" id="field-username" value="{{ user_attributes.localpart }}" autofocus> <div class="postfix">:{{ server_name }}</div> @@ -145,7 +145,7 @@ <input type="submit" value="Continue" class="primary-button"> {% if user_attributes.avatar_url or user_attributes.display_name or user_attributes.emails %} <section class="idp-pick-details"> - <h2>{% if idp.idp_icon %}<img src="{{ idp.idp_icon | mxc_to_http(24, 24) }}"/>{% endif %}Information from {{ idp.idp_name }}</h2> + <h2>{% if idp.idp_icon %}<img src="{{ idp.idp_icon | mxc_to_http(24, 24) }}"/>{% endif %}Optional data from {{ idp.idp_name }}</h2> {% if user_attributes.avatar_url %} <label class="idp-detail idp-avatar" for="idp-avatar"> <div class="check-row"> diff --git a/synapse/res/templates/sso_auth_account_details.js b/synapse/res/templates/sso_auth_account_details.js index 3c45df9078..82438519a2 100644 --- a/synapse/res/templates/sso_auth_account_details.js +++ b/synapse/res/templates/sso_auth_account_details.js @@ -62,7 +62,7 @@ function validateUsername(username) { usernameField.parentElement.classList.remove("invalid"); usernameOutput.classList.remove("error"); if (!username) { - return reportError("Please provide a username"); + return reportError("This is required. Please provide a username"); } if (username.length > 255) { return reportError("Too long, please choose something shorter"); diff --git a/synapse/res/templates/sso_footer.html b/synapse/res/templates/sso_footer.html index 588a3d508d..b46e0d83fe 100644 --- a/synapse/res/templates/sso_footer.html +++ b/synapse/res/templates/sso_footer.html @@ -15,5 +15,5 @@ </g> </g> </svg> - <p>An open network for secure, decentralized communication.<br>© 2021 The Matrix.org Foundation C.I.C.</p> + <p>An open network for secure, decentralized communication.<br>© 2022 The Matrix.org Foundation C.I.C.</p> </footer> \ No newline at end of file diff --git a/synapse/rest/__init__.py b/synapse/rest/__init__.py index 762808a571..57c4773edc 100644 --- a/synapse/rest/__init__.py +++ b/synapse/rest/__init__.py @@ -32,6 +32,7 @@ from synapse.rest.client import ( knock, login as v1_login, logout, + mutual_rooms, notifications, openid, password_policy, @@ -49,7 +50,6 @@ from synapse.rest.client import ( room_keys, room_upgrade_rest_servlet, sendtodevice, - shared_rooms, sync, tags, thirdparty, @@ -132,4 +132,4 @@ class ClientRestResource(JsonResource): admin.register_servlets_for_client_rest_resource(hs, client_resource) # unstable - shared_rooms.register_servlets(hs, client_resource) + mutual_rooms.register_servlets(hs, client_resource) diff --git a/synapse/rest/client/shared_rooms.py b/synapse/rest/client/mutual_rooms.py index e669fa7890..27bfaf0b29 100644 --- a/synapse/rest/client/shared_rooms.py +++ b/synapse/rest/client/mutual_rooms.py @@ -28,13 +28,13 @@ if TYPE_CHECKING: logger = logging.getLogger(__name__) -class UserSharedRoomsServlet(RestServlet): +class UserMutualRoomsServlet(RestServlet): """ - GET /uk.half-shot.msc2666/user/shared_rooms/{user_id} HTTP/1.1 + GET /uk.half-shot.msc2666/user/mutual_rooms/{user_id} HTTP/1.1 """ PATTERNS = client_patterns( - "/uk.half-shot.msc2666/user/shared_rooms/(?P<user_id>[^/]*)", + "/uk.half-shot.msc2666/user/mutual_rooms/(?P<user_id>[^/]*)", releases=(), # This is an unstable feature ) @@ -42,17 +42,19 @@ class UserSharedRoomsServlet(RestServlet): super().__init__() self.auth = hs.get_auth() self.store = hs.get_datastores().main - self.user_directory_active = hs.config.server.update_user_directory + self.user_directory_search_enabled = ( + hs.config.userdirectory.user_directory_search_enabled + ) async def on_GET( self, request: SynapseRequest, user_id: str ) -> Tuple[int, JsonDict]: - if not self.user_directory_active: + if not self.user_directory_search_enabled: raise SynapseError( code=400, - msg="The user directory is disabled on this server. Cannot determine shared rooms.", - errcode=Codes.FORBIDDEN, + msg="User directory searching is disabled. Cannot determine shared rooms.", + errcode=Codes.UNKNOWN, ) UserID.from_string(user_id) @@ -64,7 +66,8 @@ class UserSharedRoomsServlet(RestServlet): msg="You cannot request a list of shared rooms with yourself", errcode=Codes.FORBIDDEN, ) - rooms = await self.store.get_shared_rooms_for_users( + + rooms = await self.store.get_mutual_rooms_for_users( requester.user.to_string(), user_id ) @@ -72,4 +75,4 @@ class UserSharedRoomsServlet(RestServlet): def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None: - UserSharedRoomsServlet(hs).register(http_server) + UserMutualRoomsServlet(hs).register(http_server) diff --git a/synapse/storage/database.py b/synapse/storage/database.py index 9749f0c06e..367709a1a7 100644 --- a/synapse/storage/database.py +++ b/synapse/storage/database.py @@ -288,7 +288,7 @@ class LoggingTransaction: """ if isinstance(self.database_engine, PostgresEngine): - from psycopg2.extras import execute_batch # type: ignore + from psycopg2.extras import execute_batch self._do_execute(lambda *x: execute_batch(self.txn, *x), sql, args) else: @@ -302,10 +302,18 @@ class LoggingTransaction: rows (e.g. INSERTs). """ assert isinstance(self.database_engine, PostgresEngine) - from psycopg2.extras import execute_values # type: ignore + from psycopg2.extras import execute_values return self._do_execute( - lambda *x: execute_values(self.txn, *x, fetch=fetch), sql, *args + # Type ignore: mypy is unhappy because if `x` is a 5-tuple, then there will + # be two values for `fetch`: one given positionally, and another given + # as a keyword argument. We might be able to fix this by + # - propagating the signature of psycopg2.extras.execute_values to this + # function, or + # - changing `*args: Any` to `values: T` for some appropriate T. + lambda *x: execute_values(self.txn, *x, fetch=fetch), # type: ignore[misc] + sql, + *args, ) def execute(self, sql: str, *args: Any) -> None: diff --git a/synapse/storage/databases/main/user_directory.py b/synapse/storage/databases/main/user_directory.py index 55cc9178f0..0595df01d3 100644 --- a/synapse/storage/databases/main/user_directory.py +++ b/synapse/storage/databases/main/user_directory.py @@ -730,7 +730,7 @@ class UserDirectoryStore(UserDirectoryBackgroundUpdateStore): users.update(rows) return list(users) - async def get_shared_rooms_for_users( + async def get_mutual_rooms_for_users( self, user_id: str, other_user_id: str ) -> Set[str]: """ @@ -744,7 +744,7 @@ class UserDirectoryStore(UserDirectoryBackgroundUpdateStore): A set of room ID's that the users share. """ - def _get_shared_rooms_for_users_txn( + def _get_mutual_rooms_for_users_txn( txn: LoggingTransaction, ) -> List[Dict[str, str]]: txn.execute( @@ -768,7 +768,7 @@ class UserDirectoryStore(UserDirectoryBackgroundUpdateStore): return rows rows = await self.db_pool.runInteraction( - "get_shared_rooms_for_users", _get_shared_rooms_for_users_txn + "get_mutual_rooms_for_users", _get_mutual_rooms_for_users_txn ) return {row["room_id"] for row in rows} diff --git a/synapse/storage/engines/__init__.py b/synapse/storage/engines/__init__.py index 9abc02046e..afb7d5054d 100644 --- a/synapse/storage/engines/__init__.py +++ b/synapse/storage/engines/__init__.py @@ -27,7 +27,7 @@ def create_engine(database_config) -> BaseDatabaseEngine: if name == "psycopg2": # Note that psycopg2cffi-compat provides the psycopg2 module on pypy. - import psycopg2 # type: ignore + import psycopg2 return PostgresEngine(psycopg2, database_config) diff --git a/synapse/storage/engines/postgres.py b/synapse/storage/engines/postgres.py index 808342fafb..e8d29e2870 100644 --- a/synapse/storage/engines/postgres.py +++ b/synapse/storage/engines/postgres.py @@ -47,17 +47,26 @@ class PostgresEngine(BaseDatabaseEngine): self.default_isolation_level = ( self.module.extensions.ISOLATION_LEVEL_REPEATABLE_READ ) + self.config = database_config @property def single_threaded(self) -> bool: return False + def get_db_locale(self, txn): + txn.execute( + "SELECT datcollate, datctype FROM pg_database WHERE datname = current_database()" + ) + collation, ctype = txn.fetchone() + return collation, ctype + def check_database(self, db_conn, allow_outdated_version: bool = False): # Get the version of PostgreSQL that we're using. As per the psycopg2 # docs: The number is formed by converting the major, minor, and # revision numbers into two-decimal-digit numbers and appending them # together. For example, version 8.1.5 will be returned as 80105 self._version = db_conn.server_version + allow_unsafe_locale = self.config.get("allow_unsafe_locale", False) # Are we on a supported PostgreSQL version? if not allow_outdated_version and self._version < 100000: @@ -72,33 +81,39 @@ class PostgresEngine(BaseDatabaseEngine): "See docs/postgres.md for more information." % (rows[0][0],) ) - txn.execute( - "SELECT datcollate, datctype FROM pg_database WHERE datname = current_database()" - ) - collation, ctype = txn.fetchone() + collation, ctype = self.get_db_locale(txn) if collation != "C": logger.warning( - "Database has incorrect collation of %r. Should be 'C'\n" - "See docs/postgres.md for more information.", + "Database has incorrect collation of %r. Should be 'C'", collation, ) + if not allow_unsafe_locale: + raise IncorrectDatabaseSetup( + "Database has incorrect collation of %r. Should be 'C'\n" + "See docs/postgres.md for more information. You can override this check by" + "setting 'allow_unsafe_locale' to true in the database config.", + collation, + ) if ctype != "C": - logger.warning( - "Database has incorrect ctype of %r. Should be 'C'\n" - "See docs/postgres.md for more information.", - ctype, - ) + if not allow_unsafe_locale: + logger.warning( + "Database has incorrect ctype of %r. Should be 'C'", + ctype, + ) + raise IncorrectDatabaseSetup( + "Database has incorrect ctype of %r. Should be 'C'\n" + "See docs/postgres.md for more information. You can override this check by" + "setting 'allow_unsafe_locale' to true in the database config.", + ctype, + ) def check_new_database(self, txn): """Gets called when setting up a brand new database. This allows us to apply stricter checks on new databases versus existing database. """ - txn.execute( - "SELECT datcollate, datctype FROM pg_database WHERE datname = current_database()" - ) - collation, ctype = txn.fetchone() + collation, ctype = self.get_db_locale(txn) errors = [] |