summary refs log tree commit diff
diff options
context:
space:
mode:
authorH. Shay <hillerys@element.io>2022-12-19 17:58:18 -0800
committerH. Shay <hillerys@element.io>2022-12-19 17:58:18 -0800
commit16fabc8b325ea76e3a7012bf2817b25c738b11c5 (patch)
tree9ecdd0af93aa2802e1d4d9903ad668569a287377
parentFix html templates to load images only on HTTPS (#14625) (diff)
downloadsynapse-16fabc8b325ea76e3a7012bf2817b25c738b11c5.tar.xz
create membership event locally and add to batch
-rw-r--r--synapse/handlers/room.py91
1 files changed, 70 insertions, 21 deletions
diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py
index 6dcfd86fdf..255ca6ab51 100644
--- a/synapse/handlers/room.py
+++ b/synapse/handlers/room.py
@@ -1125,42 +1125,91 @@ class RoomCreationHandler:
             EventTypes.Create, creation_content, False
         )
 
-        logger.debug("Sending %s in new room", EventTypes.Member)
-        ev = await self.event_creation_handler.handle_new_client_event(
+        await self.event_creation_handler.handle_new_client_event(
             requester=creator,
             events_and_context=[(creation_event, creation_context)],
             ratelimit=False,
             ignore_shadow_ban=True,
         )
-        last_sent_event_id = ev.event_id
+        logger.debug("Sending %s in new room", EventTypes.Member)
 
-        member_event_id, _ = await self.room_member_handler.update_membership(
-            creator,
-            creator.user,
-            room_id,
-            "join",
-            ratelimit=False,
-            content=creator_join_profile,
-            new_room=True,
-            prev_event_ids=[last_sent_event_id],
-            depth=depth,
+        # Do some checks and create a membership event
+        if creator_join_profile is None:
+            creator_join_profile = {}
+        else:
+            # We do a copy here as we potentially change some keys
+            # later on.
+            creator_join_profile = dict(creator_join_profile)
+
+        # allow the server notices mxid to set room-level profile
+        is_requester_server_notices_user = (
+            self._server_notices_mxid is not None
+            and creator.user.to_string() == self._server_notices_mxid
         )
-        prev_event = [member_event_id]
+        room_handler = self.hs.get_room_member_handler()
 
-        # update the depth and state map here as the membership event has been created
-        # through a different code path
-        depth += 1
-        state_map[(EventTypes.Member, creator.user.to_string())] = member_event_id
+        if (
+            not room_handler.allow_per_room_profiles
+            and not is_requester_server_notices_user
+        ) or creator.shadow_banned:
+            # Strip profile data, knowing that new profile data will be added to the
+            # event's content in event_creation_handler.create_event() using the target's
+            # global profile.
+            creator_join_profile.pop("displayname", None)
+            creator_join_profile.pop("avatar_url", None)
+
+        if len(creator_join_profile.get("displayname") or "") > 256:
+            raise SynapseError(
+                400,
+                f"Displayname is too long (max {256})",
+                errcode=Codes.BAD_JSON,
+            )
 
-        # we need the state group of the membership event as it is the current state group
+        if len(creator_join_profile.get("avatar_url") or "") > 1000:
+            raise SynapseError(
+                400,
+                f"Avatar URL is too long (max {1000})",
+                errcode=Codes.BAD_JSON,
+            )
+
+        if (
+            "avatar_url" in creator_join_profile
+            and creator_join_profile.get("avatar_url") is not None
+        ):
+            profile_handler = self.hs.get_profile_handler()
+            if not await profile_handler.check_avatar_size_and_mime_type(
+                creator_join_profile["avatar_url"],
+            ):
+                raise SynapseError(403, "This avatar is not allowed", Codes.FORBIDDEN)
+
+        # The event content should *not* include the authorising user as
+        # it won't be properly signed. Strip it out since it might come
+        # back from a client updating a display name / avatar.
+        #
+        # This only applies to restricted rooms, but there should be no reason
+        # for a client to include it. Unconditionally remove it.
+        creator_join_profile.pop(EventContentFields.AUTHORISING_USER, None)
+        creator_join_profile["membership"] = "join"
+
+        # we need the state group of the creation event as it is the current state group
         event_to_state = (
             await self._storage_controllers.state.get_state_group_for_events(
-                [member_event_id]
+                [creation_event.event_id]
             )
         )
-        current_state_group = event_to_state[member_event_id]
+        current_state_group = event_to_state[creation_event.event_id]
 
         events_to_send = []
+        member_event, member_context = await create_event(
+            EventTypes.Member,
+            creator_join_profile,
+            True,
+            state_key=creator.user.to_string(),
+            room_id=room_id,
+        )
+        current_state_group = member_context._state_group
+        events_to_send.append((member_event, member_context))
+
         # We treat the power levels override specially as this needs to be one
         # of the first events that get sent into a room.
         pl_content = initial_state.pop((EventTypes.PowerLevels, ""), None)