diff --git a/CHANGES.md b/CHANGES.md
index a25951031a..c216d28818 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,4 +1,4 @@
-Synapse 1.28.0rc1 (2021-02-18)
+Synapse 1.28.0rc1 (2021-02-19)
==============================
Note that this release drops support for ARMv7 in the official Docker images, due to repeated problems building for ARMv7 (and the associated maintenance burden this entails).
@@ -10,7 +10,7 @@ Removal warning
The v1 list accounts API is deprecated and will be removed in a future release.
This API was undocumented and misleading. It can be replaced by the
-[v2 list accounts API](https://github.com/matrix-org/synapse/blob/master/docs/admin_api/user_admin_api.rst#list-accounts),
+[v2 list accounts API](https://github.com/matrix-org/synapse/blob/release-v1.28.0/docs/admin_api/user_admin_api.rst#list-accounts),
which has been available since Synapse 1.7.0 (2019-12-13).
Please check if you're using any scripts which use the admin API and replace
@@ -20,26 +20,26 @@ Please check if you're using any scripts which use the admin API and replace
Features
--------
-- New API /_synapse/admin/rooms/{roomId}/context/{eventId}. ([\#9150](https://github.com/matrix-org/synapse/issues/9150))
+- New admin API to get the context of an event: `/_synapse/admin/rooms/{roomId}/context/{eventId}`. ([\#9150](https://github.com/matrix-org/synapse/issues/9150))
- Further improvements to the user experience of registration via single sign-on. ([\#9300](https://github.com/matrix-org/synapse/issues/9300), [\#9301](https://github.com/matrix-org/synapse/issues/9301))
- Add hook to spam checker modules that allow checking file uploads and remote downloads. ([\#9311](https://github.com/matrix-org/synapse/issues/9311))
- Add support for receiving OpenID Connect authentication responses via form `POST`s rather than `GET`s. ([\#9376](https://github.com/matrix-org/synapse/issues/9376))
-- Add the shadow-banning status to the display user admin API. ([\#9400](https://github.com/matrix-org/synapse/issues/9400))
+- Add the shadow-banning status to the admin API for user info. ([\#9400](https://github.com/matrix-org/synapse/issues/9400))
Bugfixes
--------
-- Fix long-standing bug where sending email push would fail for rooms that the server had since left. ([\#9257](https://github.com/matrix-org/synapse/issues/9257))
+- Fix long-standing bug where sending email notifications would fail for rooms that the server had since left. ([\#9257](https://github.com/matrix-org/synapse/issues/9257))
- Fix bug in Synapse 1.27.0rc1 which meant the "session expired" error page during SSO registration was badly formatted. ([\#9296](https://github.com/matrix-org/synapse/issues/9296))
- Assert a maximum length for some parameters for spec compliance. ([\#9321](https://github.com/matrix-org/synapse/issues/9321), [\#9393](https://github.com/matrix-org/synapse/issues/9393))
- Fix additional errors when previewing URLs: "AttributeError 'NoneType' object has no attribute 'xpath'" and "ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.". ([\#9333](https://github.com/matrix-org/synapse/issues/9333))
- Fix a bug causing Synapse to impose the wrong type constraints on fields when processing responses from appservices to `/_matrix/app/v1/thirdparty/user/{protocol}`. ([\#9361](https://github.com/matrix-org/synapse/issues/9361))
-- Fix bug where Synapse would occaisonally stop reconnecting after the connection was lost. ([\#9391](https://github.com/matrix-org/synapse/issues/9391))
+- Fix bug where Synapse would occasionally stop reconnecting to Redis after the connection was lost. ([\#9391](https://github.com/matrix-org/synapse/issues/9391))
- Fix a long-standing bug when upgrading a room: "TypeError: '>' not supported between instances of 'NoneType' and 'int'". ([\#9395](https://github.com/matrix-org/synapse/issues/9395))
- Reduce the amount of memory used when generating the URL preview of a file that is larger than the `max_spider_size`. ([\#9421](https://github.com/matrix-org/synapse/issues/9421))
- Fix a long-standing bug in the deduplication of old presence, resulting in no deduplication. ([\#9425](https://github.com/matrix-org/synapse/issues/9425))
-- The `ui_auth.session_timeout` configuration setting can now be specified in terms of number of seconds/minutes/etc/. Contributed by Rishabh Arya. ([\#9426](https://github.com/matrix-org/synapse/issues/9426))
+- The `ui_auth.session_timeout` config option can now be specified in terms of number of seconds/minutes/etc/. Contributed by Rishabh Arya. ([\#9426](https://github.com/matrix-org/synapse/issues/9426))
- Fix a bug introduced in v1.27.0: "TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType." related to the user directory. ([\#9428](https://github.com/matrix-org/synapse/issues/9428))
@@ -52,7 +52,7 @@ Updates to the Docker image
Improved Documentation
----------------------
-- Reorganizing CHANGELOG.md. ([\#9281](https://github.com/matrix-org/synapse/issues/9281))
+- Reorganize CHANGELOG.md. ([\#9281](https://github.com/matrix-org/synapse/issues/9281))
- Add note to `auto_join_rooms` config option explaining existing rooms must be publicly joinable. ([\#9291](https://github.com/matrix-org/synapse/issues/9291))
- Correct name of Synapse's service file in TURN howto. ([\#9308](https://github.com/matrix-org/synapse/issues/9308))
- Fix the braces in the `oidc_providers` section of the sample config. ([\#9317](https://github.com/matrix-org/synapse/issues/9317))
diff --git a/changelog.d/9203.feature b/changelog.d/9203.feature
new file mode 100644
index 0000000000..36b66a47a8
--- /dev/null
+++ b/changelog.d/9203.feature
@@ -0,0 +1 @@
+Add some configuration settings to make users' profile data more private.
diff --git a/changelog.d/9383.feature b/changelog.d/9383.feature
new file mode 100644
index 0000000000..8957c9cc5e
--- /dev/null
+++ b/changelog.d/9383.feature
@@ -0,0 +1 @@
+Add a configuration option, `user_directory.prefer_local_users`, which when enabled will make it more likely for users on the same server as you to appear above other users.
\ No newline at end of file
diff --git a/changelog.d/9402.bugfix b/changelog.d/9402.bugfix
new file mode 100644
index 0000000000..7729225ba2
--- /dev/null
+++ b/changelog.d/9402.bugfix
@@ -0,0 +1 @@
+Fix a bug where a lot of unnecessary presence updates were sent when joining a room.
diff --git a/changelog.d/9440.bugfix b/changelog.d/9440.bugfix
new file mode 100644
index 0000000000..47b9842b37
--- /dev/null
+++ b/changelog.d/9440.bugfix
@@ -0,0 +1 @@
+Fix bug introduced in v1.27.0 where allowing a user to choose their own username when logging in via single sign-on did not work unless an `idp_icon` was defined.
diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml
index ff5992f92d..454fa74e8f 100644
--- a/docs/sample_config.yaml
+++ b/docs/sample_config.yaml
@@ -101,6 +101,14 @@ pid_file: DATADIR/homeserver.pid
#
#limit_profile_requests_to_users_who_share_rooms: true
+# Uncomment to prevent a user's profile data from being retrieved and
+# displayed in a room until they have joined it. By default, a user's
+# profile data is included in an invite event, regardless of the values
+# of the above two settings, and whether or not the users share a server.
+# Defaults to 'true'.
+#
+#include_profile_data_on_invite: false
+
# If set to 'true', removes the need for authentication to access the server's
# public rooms directory through the client API, meaning that anyone can
# query the room directory. Defaults to 'false'.
@@ -767,6 +775,12 @@ acme:
# - matrix.org
# - example.com
+# Uncomment to disable profile lookup over federation. By default, the
+# Federation API allows other homeservers to obtain profile data of any user
+# on this homeserver. Defaults to 'true'.
+#
+#allow_profile_lookup_over_federation: false
+
## Caching ##
diff --git a/synapse/config/federation.py b/synapse/config/federation.py
index 9f3c57e6a1..55e4db5442 100644
--- a/synapse/config/federation.py
+++ b/synapse/config/federation.py
@@ -41,6 +41,10 @@ class FederationConfig(Config):
)
self.federation_metrics_domains = set(federation_metrics_domains)
+ self.allow_profile_lookup_over_federation = config.get(
+ "allow_profile_lookup_over_federation", True
+ )
+
def generate_config_section(self, config_dir_path, server_name, **kwargs):
return """\
## Federation ##
@@ -66,6 +70,12 @@ class FederationConfig(Config):
#federation_metrics_domains:
# - matrix.org
# - example.com
+
+ # Uncomment to disable profile lookup over federation. By default, the
+ # Federation API allows other homeservers to obtain profile data of any user
+ # on this homeserver. Defaults to 'true'.
+ #
+ #allow_profile_lookup_over_federation: false
"""
diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index c2ffbc7c13..b49e6609ce 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -170,8 +170,8 @@ class RegistrationConfig(Config):
)
# Remove trailing slashes
- self.bind_new_user_emails_to_sydent = self.bind_new_user_emails_to_sydent.strip(
- "/"
+ self.bind_new_user_emails_to_sydent = (
+ self.bind_new_user_emails_to_sydent.strip("/")
)
def generate_config_section(self, generate_secrets=False, **kwargs):
diff --git a/synapse/config/server.py b/synapse/config/server.py
index 1b82c81db1..0e8394b149 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -263,6 +263,12 @@ class ServerConfig(Config):
False,
)
+ # Whether to retrieve and display profile data for a user when they
+ # are invited to a room
+ self.include_profile_data_on_invite = config.get(
+ "include_profile_data_on_invite", True
+ )
+
if "restrict_public_rooms_to_local_users" in config and (
"allow_public_rooms_without_auth" in config
or "allow_public_rooms_over_federation" in config
@@ -854,6 +860,14 @@ class ServerConfig(Config):
#
#limit_profile_requests_to_users_who_share_rooms: true
+ # Uncomment to prevent a user's profile data from being retrieved and
+ # displayed in a room until they have joined it. By default, a user's
+ # profile data is included in an invite event, regardless of the values
+ # of the above two settings, and whether or not the users share a server.
+ # Defaults to 'true'.
+ #
+ #include_profile_data_on_invite: false
+
# If set to 'true', removes the need for authentication to access the server's
# public rooms directory through the client API, meaning that anyone can
# query the room directory. Defaults to 'false'.
diff --git a/synapse/federation/federation_server.py b/synapse/federation/federation_server.py
index 6337accc70..e84fad9d77 100644
--- a/synapse/federation/federation_server.py
+++ b/synapse/federation/federation_server.py
@@ -603,7 +603,10 @@ class FederationServer(FederationBase):
return {"event": pdu.get_pdu_json(time_now), "room_version": room_version}
async def on_send_knock_request(
- self, origin: str, content: JsonDict, room_id: str,
+ self,
+ origin: str,
+ content: JsonDict,
+ room_id: str,
) -> Dict[str, List[JsonDict]]:
"""
We have received a knock event for a room. Verify and send the event into the room
@@ -636,8 +639,10 @@ class FederationServer(FederationBase):
# Retrieve stripped state events from the room and send them back to the remote
# server. This will allow the remote server's clients to display information
# related to the room while the knock request is pending.
- stripped_room_state = await self.store.get_stripped_room_state_from_event_context(
- event_context, DEFAULT_ROOM_STATE_TYPES
+ stripped_room_state = (
+ await self.store.get_stripped_room_state_from_event_context(
+ event_context, DEFAULT_ROOM_STATE_TYPES
+ )
)
return {"knock_state_events": stripped_room_state}
diff --git a/synapse/federation/sender/__init__.py b/synapse/federation/sender/__init__.py
index 97fc4d0a82..24ebc4b803 100644
--- a/synapse/federation/sender/__init__.py
+++ b/synapse/federation/sender/__init__.py
@@ -474,7 +474,7 @@ class FederationSender:
self._processing_pending_presence = False
def send_presence_to_destinations(
- self, states: List[UserPresenceState], destinations: List[str]
+ self, states: Iterable[UserPresenceState], destinations: Iterable[str]
) -> None:
"""Send the given presence states to the given destinations.
destinations (list[str])
diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py
index 68d9349a30..3f2b2bf7d5 100644
--- a/synapse/federation/transport/client.py
+++ b/synapse/federation/transport/client.py
@@ -309,7 +309,11 @@ class TransportLayerClient:
@log_function
async def send_knock_v2(
- self, destination: str, room_id: str, event_id: str, content: JsonDict,
+ self,
+ destination: str,
+ room_id: str,
+ event_id: str,
+ content: JsonDict,
) -> JsonDict:
"""
Sends a signed knock membership event to a remote server. This is the second
diff --git a/synapse/federation/transport/server.py b/synapse/federation/transport/server.py
index 8d89074c5a..963704d0c2 100644
--- a/synapse/federation/transport/server.py
+++ b/synapse/federation/transport/server.py
@@ -486,10 +486,9 @@ class FederationQueryServlet(BaseFederationServlet):
# This is when we receive a server-server Query
async def on_GET(self, origin, content, query, query_type):
- return await self.handler.on_query_request(
- query_type,
- {k.decode("utf8"): v[0].decode("utf-8") for k, v in query.items()},
- )
+ args = {k.decode("utf8"): v[0].decode("utf-8") for k, v in query.items()}
+ args["origin"] = origin
+ return await self.handler.on_query_request(query_type, args)
class FederationMakeJoinServlet(BaseFederationServlet):
diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py
index 51bdf97920..6cafb5c227 100644
--- a/synapse/handlers/federation.py
+++ b/synapse/handlers/federation.py
@@ -408,7 +408,8 @@ class FederationHandler(BaseHandler):
# First though we need to fetch all the events that are in
# state_map, so we can build up the state below.
evs = await self.store.get_events(
- list(state_map.values()), get_prev_content=False,
+ list(state_map.values()),
+ get_prev_content=False,
)
event_map.update(evs)
@@ -1451,7 +1452,11 @@ class FederationHandler(BaseHandler):
@log_function
async def do_knock(
- self, target_hosts: List[str], room_id: str, knockee: str, content: JsonDict,
+ self,
+ target_hosts: List[str],
+ room_id: str,
+ knockee: str,
+ content: JsonDict,
) -> Tuple[str, int]:
"""Sends the knock to the remote server.
diff --git a/synapse/handlers/identity.py b/synapse/handlers/identity.py
index ac81fa3678..382d1dbe6f 100644
--- a/synapse/handlers/identity.py
+++ b/synapse/handlers/identity.py
@@ -1017,7 +1017,9 @@ class IdentityHandler(BaseHandler):
raise SynapseError(500, "Timed out contacting identity server")
except HttpResponseException as e:
logger.warning(
- "Error trying to call /store-invite on %s: %s", id_server_url, e,
+ "Error trying to call /store-invite on %s: %s",
+ id_server_url,
+ e,
)
if data is None:
@@ -1054,7 +1056,10 @@ class IdentityHandler(BaseHandler):
return token, public_keys, fallback_public_key, display_name
async def bind_email_using_internal_sydent_api(
- self, id_server_url: str, email: str, user_id: str,
+ self,
+ id_server_url: str,
+ email: str,
+ user_id: str,
):
"""Bind an email to a fully qualified user ID using the internal API of an
instance of Sydent.
@@ -1086,7 +1091,10 @@ class IdentityHandler(BaseHandler):
# Remember where we bound the threepid
await self.store.add_user_bound_threepid(
- user_id=user_id, medium="email", address=email, id_server=id_server,
+ user_id=user_id,
+ medium="email",
+ address=email,
+ id_server=id_server,
)
diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py
index 1aded280c7..e06e8ff60c 100644
--- a/synapse/handlers/message.py
+++ b/synapse/handlers/message.py
@@ -389,6 +389,12 @@ class EventCreationHandler:
self.room_invite_state_types = self.hs.config.room_invite_state_types
+ self.membership_types_to_include_profile_data_in = (
+ {Membership.JOIN, Membership.INVITE, Membership.KNOCK}
+ if self.hs.config.include_profile_data_on_invite
+ else {Membership.JOIN, Membership.KNOCK}
+ )
+
self.send_event = ReplicationSendEventRestServlet.make_client(hs)
# This is only used to get at ratelimit function, and maybe_kick_guest_users
@@ -502,7 +508,7 @@ class EventCreationHandler:
membership = builder.content.get("membership", None)
target = UserID.from_string(builder.state_key)
- if membership in {Membership.JOIN, Membership.INVITE, Membership.KNOCK}:
+ if membership in self.membership_types_to_include_profile_data_in:
# If event doesn't include a display name, add one.
profile = self.profile_handler
content = builder.content
@@ -1181,7 +1187,8 @@ class EventCreationHandler:
event.unsigned[
"knock_room_state"
] = await self.store.get_stripped_room_state_from_event_context(
- context, DEFAULT_ROOM_STATE_TYPES,
+ context,
+ DEFAULT_ROOM_STATE_TYPES,
)
if event.type == EventTypes.Redaction:
diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py
index fb85b19770..b6a9ce4f38 100644
--- a/synapse/handlers/presence.py
+++ b/synapse/handlers/presence.py
@@ -849,6 +849,9 @@ class PresenceHandler(BasePresenceHandler):
"""Process current state deltas to find new joins that need to be
handled.
"""
+ # A map of destination to a set of user state that they should receive
+ presence_destinations = {} # type: Dict[str, Set[UserPresenceState]]
+
for delta in deltas:
typ = delta["type"]
state_key = delta["state_key"]
@@ -858,6 +861,7 @@ class PresenceHandler(BasePresenceHandler):
logger.debug("Handling: %r %r, %s", typ, state_key, event_id)
+ # Drop any event that isn't a membership join
if typ != EventTypes.Member:
continue
@@ -880,13 +884,38 @@ class PresenceHandler(BasePresenceHandler):
# Ignore changes to join events.
continue
- await self._on_user_joined_room(room_id, state_key)
+ # Retrieve any user presence state updates that need to be sent as a result,
+ # and the destinations that need to receive it
+ destinations, user_presence_states = await self._on_user_joined_room(
+ room_id, state_key
+ )
+
+ # Insert the destinations and respective updates into our destinations dict
+ for destination in destinations:
+ presence_destinations.setdefault(destination, set()).update(
+ user_presence_states
+ )
+
+ # Send out user presence updates for each destination
+ for destination, user_state_set in presence_destinations.items():
+ self.federation.send_presence_to_destinations(
+ destinations=[destination], states=user_state_set
+ )
- async def _on_user_joined_room(self, room_id: str, user_id: str) -> None:
+ async def _on_user_joined_room(
+ self, room_id: str, user_id: str
+ ) -> Tuple[List[str], List[UserPresenceState]]:
"""Called when we detect a user joining the room via the current state
- delta stream.
- """
+ delta stream. Returns the destinations that need to be updated and the
+ presence updates to send to them.
+
+ Args:
+ room_id: The ID of the room that the user has joined.
+ user_id: The ID of the user that has joined the room.
+ Returns:
+ A tuple of destinations and presence updates to send to them.
+ """
if self.is_mine_id(user_id):
# If this is a local user then we need to send their presence
# out to hosts in the room (who don't already have it)
@@ -894,15 +923,15 @@ class PresenceHandler(BasePresenceHandler):
# TODO: We should be able to filter the hosts down to those that
# haven't previously seen the user
- state = await self.current_state_for_user(user_id)
- hosts = await self.state.get_current_hosts_in_room(room_id)
+ remote_hosts = await self.state.get_current_hosts_in_room(room_id)
# Filter out ourselves.
- hosts = {host for host in hosts if host != self.server_name}
+ filtered_remote_hosts = [
+ host for host in remote_hosts if host != self.server_name
+ ]
- self.federation.send_presence_to_destinations(
- states=[state], destinations=hosts
- )
+ state = await self.current_state_for_user(user_id)
+ return filtered_remote_hosts, [state]
else:
# A remote user has joined the room, so we need to:
# 1. Check if this is a new server in the room
@@ -915,6 +944,8 @@ class PresenceHandler(BasePresenceHandler):
# TODO: Check that this is actually a new server joining the
# room.
+ remote_host = get_domain_from_id(user_id)
+
users = await self.state.get_current_users_in_room(room_id)
user_ids = list(filter(self.is_mine_id, users))
@@ -934,10 +965,7 @@ class PresenceHandler(BasePresenceHandler):
or state.status_msg is not None
]
- if states:
- self.federation.send_presence_to_destinations(
- states=states, destinations=[get_domain_from_id(user_id)]
- )
+ return [remote_host], states
def should_notify(old_state, new_state):
diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py
index b04ee5f430..f21352412e 100644
--- a/synapse/handlers/profile.py
+++ b/synapse/handlers/profile.py
@@ -333,7 +333,10 @@ class ProfileHandler(BaseHandler):
run_in_background(self._replicate_profiles)
async def set_active(
- self, users: List[UserID], active: bool, hide: bool,
+ self,
+ users: List[UserID],
+ active: bool,
+ hide: bool,
):
"""
Sets the 'active' flag on a set of user profiles. If set to false, the
@@ -515,6 +518,15 @@ class ProfileHandler(BaseHandler):
return avatar_pieces[-1]
async def on_profile_query(self, args: JsonDict) -> JsonDict:
+ """Handles federation profile query requests."""
+
+ if not self.hs.config.allow_profile_lookup_over_federation:
+ raise SynapseError(
+ 403,
+ "Profile lookup over federation is disabled on this homeserver",
+ Codes.FORBIDDEN,
+ )
+
user = UserID.from_string(args["user_id"])
if not self.hs.is_mine(user):
raise SynapseError(400, "User is not hosted on this homeserver")
diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py
index 312ebc139c..e8b7bb49ec 100644
--- a/synapse/handlers/room_member.py
+++ b/synapse/handlers/room_member.py
@@ -131,7 +131,11 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
@abc.abstractmethod
async def remote_knock(
- self, remote_room_hosts: List[str], room_id: str, user: UserID, content: dict,
+ self,
+ remote_room_hosts: List[str],
+ room_id: str,
+ user: UserID,
+ content: dict,
) -> Tuple[str, int]:
"""Try and knock on a room that this server is not in
@@ -1382,7 +1386,11 @@ class RoomMemberMasterHandler(RoomMemberHandler):
return result_event.event_id, result_event.internal_metadata.stream_ordering
async def remote_knock(
- self, remote_room_hosts: List[str], room_id: str, user: UserID, content: dict,
+ self,
+ remote_room_hosts: List[str],
+ room_id: str,
+ user: UserID,
+ content: dict,
) -> Tuple[str, int]:
"""Sends a knock to a room. Attempts to do so via one remote out of a given list.
diff --git a/synapse/handlers/room_member_worker.py b/synapse/handlers/room_member_worker.py
index 926d09f40c..428dae1914 100644
--- a/synapse/handlers/room_member_worker.py
+++ b/synapse/handlers/room_member_worker.py
@@ -112,7 +112,11 @@ class RoomMemberWorkerHandler(RoomMemberHandler):
return ret["event_id"], ret["stream_id"]
async def remote_knock(
- self, remote_room_hosts: List[str], room_id: str, user: UserID, content: dict,
+ self,
+ remote_room_hosts: List[str],
+ room_id: str,
+ user: UserID,
+ content: dict,
) -> Tuple[str, int]:
"""Sends a knock to a room.
diff --git a/synapse/handlers/sync.py b/synapse/handlers/sync.py
index fa6794734b..9059382246 100644
--- a/synapse/handlers/sync.py
+++ b/synapse/handlers/sync.py
@@ -1744,7 +1744,11 @@ class SyncHandler:
room_entries.append(entry)
return _RoomChanges(
- room_entries, invited, knocked, newly_joined_rooms, newly_left_rooms,
+ room_entries,
+ invited,
+ knocked,
+ newly_joined_rooms,
+ newly_left_rooms,
)
async def _get_all_rooms(
diff --git a/synapse/http/proxyagent.py b/synapse/http/proxyagent.py
index ee65a6668b..16ec850064 100644
--- a/synapse/http/proxyagent.py
+++ b/synapse/http/proxyagent.py
@@ -179,7 +179,8 @@ class ProxyAgent(_AgentBase):
should_skip_proxy = False
if self.no_proxy is not None:
should_skip_proxy = proxy_bypass_environment(
- parsed_uri.host.decode(), proxies={"no": self.no_proxy},
+ parsed_uri.host.decode(),
+ proxies={"no": self.no_proxy},
)
if (
diff --git a/synapse/replication/http/federation.py b/synapse/replication/http/federation.py
index 7a0dbb5b1a..8af53b4f28 100644
--- a/synapse/replication/http/federation.py
+++ b/synapse/replication/http/federation.py
@@ -213,8 +213,9 @@ class ReplicationGetQueryRestServlet(ReplicationEndpoint):
content = parse_json_object_from_request(request)
args = content["args"]
+ args["origin"] = content["origin"]
- logger.info("Got %r query", query_type)
+ logger.info("Got %r query from %s", query_type, args["origin"])
result = await self.registry.on_query(query_type, args)
diff --git a/synapse/replication/http/membership.py b/synapse/replication/http/membership.py
index ce52613956..d1394478b0 100644
--- a/synapse/replication/http/membership.py
+++ b/synapse/replication/http/membership.py
@@ -145,7 +145,10 @@ class ReplicationRemoteKnockRestServlet(ReplicationEndpoint):
}
async def _handle_request( # type: ignore
- self, request: Request, room_id: str, user_id: str,
+ self,
+ request: Request,
+ room_id: str,
+ user_id: str,
):
content = parse_json_object_from_request(request)
@@ -281,7 +284,9 @@ class ReplicationRemoteRescindKnockRestServlet(ReplicationEndpoint):
}
async def _handle_request( # type: ignore
- self, request: Request, knock_event_id: str,
+ self,
+ request: Request,
+ knock_event_id: str,
):
content = parse_json_object_from_request(request)
@@ -294,7 +299,10 @@ class ReplicationRemoteRescindKnockRestServlet(ReplicationEndpoint):
# hopefully we're now on the master, so this won't recurse!
event_id, stream_id = await self.member_handler.remote_rescind_knock(
- knock_event_id, txn_id, requester, event_content,
+ knock_event_id,
+ txn_id,
+ requester,
+ event_content,
)
return 200, {"event_id": event_id, "stream_id": stream_id}
diff --git a/synapse/res/templates/sso_auth_account_details.html b/synapse/res/templates/sso_auth_account_details.html
index f4fdc40b22..00e1dcdbb8 100644
--- a/synapse/res/templates/sso_auth_account_details.html
+++ b/synapse/res/templates/sso_auth_account_details.html
@@ -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><img src="{{ idp.idp_icon | mxc_to_http(24, 24) }}"/>Information from {{ idp.idp_name }}</h2>
+ <h2>{% if idp.idp_icon %}<img src="{{ idp.idp_icon | mxc_to_http(24, 24) }}"/>{% endif %}Information 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/rest/client/v2_alpha/knock.py b/synapse/rest/client/v2_alpha/knock.py
index 8439da447e..75b7f665c9 100644
--- a/synapse/rest/client/v2_alpha/knock.py
+++ b/synapse/rest/client/v2_alpha/knock.py
@@ -53,7 +53,10 @@ class KnockRoomAliasServlet(RestServlet):
self.auth = hs.get_auth()
async def on_POST(
- self, request: Request, room_identifier: str, txn_id: Optional[str] = None,
+ self,
+ request: Request,
+ room_identifier: str,
+ txn_id: Optional[str] = None,
) -> Tuple[int, JsonDict]:
requester = await self.auth.get_user_by_req(request)
diff --git a/synapse/rulecheck/domain_rule_checker.py b/synapse/rulecheck/domain_rule_checker.py
index 6f2a1931c5..11e7cb59da 100644
--- a/synapse/rulecheck/domain_rule_checker.py
+++ b/synapse/rulecheck/domain_rule_checker.py
@@ -77,8 +77,7 @@ class DomainRuleChecker(object):
)
def check_event_for_spam(self, event):
- """Implements synapse.events.SpamChecker.check_event_for_spam
- """
+ """Implements synapse.events.SpamChecker.check_event_for_spam"""
return False
def user_may_invite(
@@ -90,8 +89,7 @@ class DomainRuleChecker(object):
new_room,
published_room=False,
):
- """Implements synapse.events.SpamChecker.user_may_invite
- """
+ """Implements synapse.events.SpamChecker.user_may_invite"""
if self.can_only_invite_during_room_creation and not new_room:
return False
@@ -121,8 +119,7 @@ class DomainRuleChecker(object):
def user_may_create_room(
self, userid, invite_list, third_party_invite_list, cloning
):
- """Implements synapse.events.SpamChecker.user_may_create_room
- """
+ """Implements synapse.events.SpamChecker.user_may_create_room"""
if cloning:
return True
@@ -138,18 +135,15 @@ class DomainRuleChecker(object):
return True
def user_may_create_room_alias(self, userid, room_alias):
- """Implements synapse.events.SpamChecker.user_may_create_room_alias
- """
+ """Implements synapse.events.SpamChecker.user_may_create_room_alias"""
return True
def user_may_publish_room(self, userid, room_id):
- """Implements synapse.events.SpamChecker.user_may_publish_room
- """
+ """Implements synapse.events.SpamChecker.user_may_publish_room"""
return True
def user_may_join_room(self, userid, room_id, is_invited):
- """Implements synapse.events.SpamChecker.user_may_join_room
- """
+ """Implements synapse.events.SpamChecker.user_may_join_room"""
if self.can_only_join_rooms_with_invite and not is_invited:
return False
@@ -157,8 +151,7 @@ class DomainRuleChecker(object):
@staticmethod
def parse_config(config):
- """Implements synapse.events.SpamChecker.parse_config
- """
+ """Implements synapse.events.SpamChecker.parse_config"""
if "default" in config:
return config
else:
diff --git a/synapse/storage/databases/main/profile.py b/synapse/storage/databases/main/profile.py
index 2dcdf9beb0..1e65cb8a04 100644
--- a/synapse/storage/databases/main/profile.py
+++ b/synapse/storage/databases/main/profile.py
@@ -159,7 +159,11 @@ class ProfileWorkerStore(SQLBaseStore):
)
async def set_profiles_active(
- self, users: List[UserID], active: bool, hide: bool, batchnum: int,
+ self,
+ users: List[UserID],
+ active: bool,
+ hide: bool,
+ batchnum: int,
) -> None:
"""Given a set of users, set active and hidden flags on them.
diff --git a/synapse/storage/databases/main/registration.py b/synapse/storage/databases/main/registration.py
index 25d8dcb6ab..b96ff6a0b6 100644
--- a/synapse/storage/databases/main/registration.py
+++ b/synapse/storage/databases/main/registration.py
@@ -383,7 +383,8 @@ class RegistrationWorkerStore(CacheInvalidationWorkerStore):
)
async def get_info_for_users(
- self, user_ids: List[str],
+ self,
+ user_ids: List[str],
):
"""Return the user info for a given set of users
diff --git a/synapse/third_party_rules/access_rules.py b/synapse/third_party_rules/access_rules.py
index 4589e4539b..a047699cc4 100644
--- a/synapse/third_party_rules/access_rules.py
+++ b/synapse/third_party_rules/access_rules.py
@@ -81,7 +81,9 @@ class RoomAccessRules(object):
"""
def __init__(
- self, config: Dict, module_api: ModuleApi,
+ self,
+ config: Dict,
+ module_api: ModuleApi,
):
self.id_server = config["id_server"]
self.module_api = module_api
@@ -111,7 +113,10 @@ class RoomAccessRules(object):
return config
async def on_create_room(
- self, requester: Requester, config: Dict, is_requester_admin: bool,
+ self,
+ requester: Requester,
+ config: Dict,
+ is_requester_admin: bool,
) -> bool:
"""Implements synapse.events.ThirdPartyEventRules.on_create_room.
@@ -259,7 +264,10 @@ class RoomAccessRules(object):
}
async def check_threepid_can_be_invited(
- self, medium: str, address: str, state_events: StateMap[EventBase],
+ self,
+ medium: str,
+ address: str,
+ state_events: StateMap[EventBase],
) -> bool:
"""Implements synapse.events.ThirdPartyEventRules.check_threepid_can_be_invited.
@@ -309,7 +317,9 @@ class RoomAccessRules(object):
return True
async def check_event_allowed(
- self, event: EventBase, state_events: StateMap[EventBase],
+ self,
+ event: EventBase,
+ state_events: StateMap[EventBase],
) -> bool:
"""Implements synapse.events.ThirdPartyEventRules.check_event_allowed.
@@ -434,7 +444,10 @@ class RoomAccessRules(object):
)
async def _on_membership_or_invite(
- self, event: EventBase, rule: str, state_events: StateMap[EventBase],
+ self,
+ event: EventBase,
+ rule: str,
+ state_events: StateMap[EventBase],
) -> bool:
"""Applies the correct rule for incoming m.room.member and
m.room.third_party_invite events.
@@ -659,7 +672,9 @@ class RoomAccessRules(object):
return True
def _on_membership_or_invite_direct(
- self, event: EventBase, state_events: StateMap[EventBase],
+ self,
+ event: EventBase,
+ state_events: StateMap[EventBase],
) -> bool:
"""Implements the checks and behaviour specified for the "direct" rule.
diff --git a/tests/federation/transport/test_knocking.py b/tests/federation/transport/test_knocking.py
index 5b928480e7..fbce19f38b 100644
--- a/tests/federation/transport/test_knocking.py
+++ b/tests/federation/transport/test_knocking.py
@@ -34,7 +34,10 @@ KNOCK_UNSTABLE_IDENTIFIER = "xyz.amorgan.knock"
class KnockingStrippedStateEventHelperMixin(TestCase):
def send_example_state_events_to_room(
- self, hs: "HomeServer", room_id: str, sender: str,
+ self,
+ hs: "HomeServer",
+ room_id: str,
+ sender: str,
) -> OrderedDict:
"""Adds some state to a room. State events are those that should be sent to a knocking
user after they knock on the room, as well as some state that *shouldn't* be sent
@@ -133,7 +136,9 @@ class KnockingStrippedStateEventHelperMixin(TestCase):
return room_state
def check_knock_room_state_against_room_state(
- self, knock_room_state: List[Dict], expected_room_state: Dict,
+ self,
+ knock_room_state: List[Dict],
+ expected_room_state: Dict,
) -> None:
"""Test a list of stripped room state events received over federation against a
dict of expected state events.
diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py
index be2ee26f07..996c614198 100644
--- a/tests/handlers/test_presence.py
+++ b/tests/handlers/test_presence.py
@@ -521,7 +521,7 @@ class PresenceJoinTestCase(unittest.HomeserverTestCase):
)
self.assertEqual(expected_state.state, PresenceState.ONLINE)
self.federation_sender.send_presence_to_destinations.assert_called_once_with(
- destinations=["server2"], states=[expected_state]
+ destinations=["server2"], states={expected_state}
)
#
@@ -533,7 +533,7 @@ class PresenceJoinTestCase(unittest.HomeserverTestCase):
self.federation_sender.send_presence.assert_not_called()
self.federation_sender.send_presence_to_destinations.assert_called_once_with(
- destinations=["server3"], states=[expected_state]
+ destinations=["server3"], states={expected_state}
)
def test_remote_gets_presence_when_local_user_joins(self):
@@ -584,8 +584,14 @@ class PresenceJoinTestCase(unittest.HomeserverTestCase):
self.presence_handler.current_state_for_user("@test2:server")
)
self.assertEqual(expected_state.state, PresenceState.ONLINE)
- self.federation_sender.send_presence_to_destinations.assert_called_once_with(
- destinations={"server2", "server3"}, states=[expected_state]
+ self.assertEqual(
+ self.federation_sender.send_presence_to_destinations.call_count, 2
+ )
+ self.federation_sender.send_presence_to_destinations.assert_any_call(
+ destinations=["server3"], states={expected_state}
+ )
+ self.federation_sender.send_presence_to_destinations.assert_any_call(
+ destinations=["server2"], states={expected_state}
)
def _add_new_user(self, room_id, user_id):
diff --git a/tests/handlers/test_profile.py b/tests/handlers/test_profile.py
index 909984b3be..cbbe7280c7 100644
--- a/tests/handlers/test_profile.py
+++ b/tests/handlers/test_profile.py
@@ -161,7 +161,11 @@ class ProfileTestCase(unittest.HomeserverTestCase):
response = self.get_success(
self.query_handlers["profile"](
- {"user_id": "@caroline:test", "field": "displayname"}
+ {
+ "user_id": "@caroline:test",
+ "field": "displayname",
+ "origin": "servername.tld",
+ }
)
)
diff --git a/tests/handlers/test_user_directory.py b/tests/handlers/test_user_directory.py
index ddfe6950e1..dbe68bb058 100644
--- a/tests/handlers/test_user_directory.py
+++ b/tests/handlers/test_user_directory.py
@@ -619,7 +619,10 @@ class UserDirectoryTestCase(unittest.HomeserverTestCase):
[self.assertIn(user, remote_users) for user in received_user_id_ordering[3:]]
def _add_user_to_room(
- self, room_id: str, room_version: RoomVersion, user_id: str,
+ self,
+ room_id: str,
+ room_version: RoomVersion,
+ user_id: str,
):
# Add a user to the room.
builder = self.event_builder_factory.for_room_version(
diff --git a/tests/http/test_proxyagent.py b/tests/http/test_proxyagent.py
index 4e1a5a5138..34df39429b 100644
--- a/tests/http/test_proxyagent.py
+++ b/tests/http/test_proxyagent.py
@@ -184,7 +184,9 @@ class MatrixFederationAgentTests(TestCase):
)
def test_https_request_via_no_proxy(self):
agent = ProxyAgent(
- self.reactor, contextFactory=get_test_https_policy(), use_proxy=True,
+ self.reactor,
+ contextFactory=get_test_https_policy(),
+ use_proxy=True,
)
self._test_request_direct_connection(agent, b"https", b"test.com", b"abc")
@@ -196,7 +198,9 @@ class MatrixFederationAgentTests(TestCase):
@patch.dict(os.environ, {"https_proxy": "proxy.com", "no_proxy": "*"})
def test_https_request_via_no_proxy_star(self):
agent = ProxyAgent(
- self.reactor, contextFactory=get_test_https_policy(), use_proxy=True,
+ self.reactor,
+ contextFactory=get_test_https_policy(),
+ use_proxy=True,
)
self._test_request_direct_connection(agent, b"https", b"test.com", b"abc")
@@ -252,10 +256,13 @@ class MatrixFederationAgentTests(TestCase):
self._do_https_request_via_proxy(auth_credentials="bob:pinkponies")
def _do_https_request_via_proxy(
- self, auth_credentials: Optional[str] = None,
+ self,
+ auth_credentials: Optional[str] = None,
):
agent = ProxyAgent(
- self.reactor, contextFactory=get_test_https_policy(), use_proxy=True,
+ self.reactor,
+ contextFactory=get_test_https_policy(),
+ use_proxy=True,
)
self.reactor.lookups["proxy.com"] = "1.2.3.5"
diff --git a/tests/rest/client/test_room_access_rules.py b/tests/rest/client/test_room_access_rules.py
index 97f379b5a5..6344fcdf6a 100644
--- a/tests/rest/client/test_room_access_rules.py
+++ b/tests/rest/client/test_room_access_rules.py
@@ -86,7 +86,9 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
mock_federation_client = Mock(spec=["send_invite"])
mock_federation_client.send_invite.side_effect = send_invite
- mock_http_client = Mock(spec=["get_json", "post_json_get_json"],)
+ mock_http_client = Mock(
+ spec=["get_json", "post_json_get_json"],
+ )
# Mocking the response for /info on the IS API.
mock_http_client.get_json.side_effect = get_json
# Mocking the response for /store-invite on the IS API.
@@ -154,8 +156,7 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
self.create_room(rule=AccessRules.DIRECT, expected_code=400)
def test_create_room_direct_invalid_rule(self):
- """Tests that creating a direct room with an invalid rule will fail.
- """
+ """Tests that creating a direct room with an invalid rule will fail."""
self.create_room(direct=True, rule=AccessRules.RESTRICTED, expected_code=400)
def test_create_room_default_power_level_rules(self):
@@ -234,7 +235,9 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
"""
# Creates a room with the default power levels
room_id = self.create_room(
- direct=True, rule=AccessRules.DIRECT, expected_code=200,
+ direct=True,
+ rule=AccessRules.DIRECT,
+ expected_code=200,
)
# Attempt to drop invite and state_default power levels after the fact
@@ -854,22 +857,30 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
"""
def freeze_room_with_id_and_power_levels(
- room_id: str, custom_power_levels_content: Optional[JsonDict] = None,
+ room_id: str,
+ custom_power_levels_content: Optional[JsonDict] = None,
):
# Invite a user to the room, they join with PL 0
self.helper.invite(
- room=room_id, src=self.user_id, targ=self.invitee_id, tok=self.tok,
+ room=room_id,
+ src=self.user_id,
+ targ=self.invitee_id,
+ tok=self.tok,
)
# Invitee joins the room
self.helper.join(
- room=room_id, user=self.invitee_id, tok=self.invitee_tok,
+ room=room_id,
+ user=self.invitee_id,
+ tok=self.invitee_tok,
)
if not custom_power_levels_content:
# Retrieve the room's current power levels event content
power_levels = self.helper.get_state(
- room_id=room_id, event_type="m.room.power_levels", tok=self.tok,
+ room_id=room_id,
+ event_type="m.room.power_levels",
+ tok=self.tok,
)
else:
power_levels = custom_power_levels_content
@@ -884,12 +895,16 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
# Ensure that the invitee leaving the room does not change the power levels
self.helper.leave(
- room=room_id, user=self.invitee_id, tok=self.invitee_tok,
+ room=room_id,
+ user=self.invitee_id,
+ tok=self.invitee_tok,
)
# Retrieve the new power levels of the room
new_power_levels = self.helper.get_state(
- room_id=room_id, event_type="m.room.power_levels", tok=self.tok,
+ room_id=room_id,
+ event_type="m.room.power_levels",
+ tok=self.tok,
)
# Ensure they have not changed
@@ -897,22 +912,31 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
# Invite the user back again
self.helper.invite(
- room=room_id, src=self.user_id, targ=self.invitee_id, tok=self.tok,
+ room=room_id,
+ src=self.user_id,
+ targ=self.invitee_id,
+ tok=self.tok,
)
# Invitee joins the room
self.helper.join(
- room=room_id, user=self.invitee_id, tok=self.invitee_tok,
+ room=room_id,
+ user=self.invitee_id,
+ tok=self.invitee_tok,
)
# Now the admin leaves the room
self.helper.leave(
- room=room_id, user=self.user_id, tok=self.tok,
+ room=room_id,
+ user=self.user_id,
+ tok=self.tok,
)
# Check the power levels again
new_power_levels = self.helper.get_state(
- room_id=room_id, event_type="m.room.power_levels", tok=self.invitee_tok,
+ room_id=room_id,
+ event_type="m.room.power_levels",
+ tok=self.invitee_tok,
)
# Ensure that the new power levels prevent anyone but admins from sending
@@ -1002,7 +1026,10 @@ class RoomAccessTestCase(unittest.HomeserverTestCase):
content["power_levels_content_override"] = power_levels_content_override
channel = self.make_request(
- "POST", "/_matrix/client/r0/createRoom", content, access_token=self.tok,
+ "POST",
+ "/_matrix/client/r0/createRoom",
+ content,
+ access_token=self.tok,
)
self.assertEqual(channel.code, expected_code, channel.result)
diff --git a/tests/rest/client/v2_alpha/test_register.py b/tests/rest/client/v2_alpha/test_register.py
index 67f7dc43c3..2d4ce871eb 100644
--- a/tests/rest/client/v2_alpha/test_register.py
+++ b/tests/rest/client/v2_alpha/test_register.py
@@ -735,8 +735,10 @@ class AccountValidityRenewalByEmailTestCase(unittest.HomeserverTestCase):
# Check that the HTML we're getting is the one we expect when reusing a
# token. The account expiration date should not have changed.
- expected_html = self.hs.config.account_validity_account_previously_renewed_template.render(
- expiration_ts=expiration_ts
+ expected_html = (
+ self.hs.config.account_validity_account_previously_renewed_template.render(
+ expiration_ts=expiration_ts
+ )
)
self.assertEqual(
channel.result["body"], expected_html.encode("utf8"), channel.result
diff --git a/tests/rest/client/v2_alpha/test_sync.py b/tests/rest/client/v2_alpha/test_sync.py
index 899f4902d7..8755bfb38a 100644
--- a/tests/rest/client/v2_alpha/test_sync.py
+++ b/tests/rest/client/v2_alpha/test_sync.py
@@ -350,7 +350,9 @@ class SyncKnockTestCase(
# Perform an initial sync for the knocking user.
channel = self.make_request(
- "GET", self.url % self.next_batch, access_token=self.tok,
+ "GET",
+ self.url % self.next_batch,
+ access_token=self.tok,
)
self.assertEqual(channel.code, 200, channel.json_body)
@@ -382,7 +384,9 @@ class SyncKnockTestCase(
# Check that /sync includes stripped state from the room
channel = self.make_request(
- "GET", self.url % self.next_batch, access_token=self.knocker_tok,
+ "GET",
+ self.url % self.next_batch,
+ access_token=self.knocker_tok,
)
self.assertEqual(channel.code, 200, channel.json_body)
diff --git a/tests/rulecheck/test_domainrulecheck.py b/tests/rulecheck/test_domainrulecheck.py
index 27e59e3891..3c70a9c8c0 100644
--- a/tests/rulecheck/test_domainrulecheck.py
+++ b/tests/rulecheck/test_domainrulecheck.py
@@ -284,8 +284,7 @@ class DomainRuleCheckerRoomTestCase(unittest.HomeserverTestCase):
)
def test_cannot_3pid_invite(self):
- """Test that unbound 3pid invites get rejected.
- """
+ """Test that unbound 3pid invites get rejected."""
channel = self._create_room(self.admin_access_token)
assert channel.result["code"] == b"200", channel.result
@@ -322,7 +321,9 @@ class DomainRuleCheckerRoomTestCase(unittest.HomeserverTestCase):
path = "/_matrix/client/r0/createRoom?access_token=%s" % (token,)
channel = self.make_request(
- "POST", path, content=json.dumps(content).encode("utf8"),
+ "POST",
+ path,
+ content=json.dumps(content).encode("utf8"),
)
return channel
|