diff --git a/synapse/api/auth.py b/synapse/api/auth.py index 1071a0576e..98bb1aaee5 100644 --- a/synapse/api/auth.py +++ b/synapse/api/auth.py @@ -89,6 +89,9 @@ class Auth: auth_events = await self.store.get_events(auth_events_ids) auth_events = {(e.type, e.state_key): e for e in auth_events.values()} + # TODO: + # Would need to thread original_event everywhere we call event_auth.check + # Ask in #synapse-dev about this first... room_version_obj = KNOWN_ROOM_VERSIONS[room_version] event_auth.check( room_version_obj, event, auth_events=auth_events, do_sig_check=do_sig_check diff --git a/synapse/event_auth.py b/synapse/event_auth.py index 66c9b97108..ea5a8e6ed0 100644 --- a/synapse/event_auth.py +++ b/synapse/event_auth.py @@ -161,6 +161,7 @@ def check( if logger.isEnabledFor(logging.DEBUG): logger.debug("Auth events: %s", [a.event_id for a in auth_events.values()]) + # 5. If type if m.room.membership if event.type == EventTypes.Member: _is_membership_change_allowed(event, auth_events) logger.debug("Allowing! %s", event) @@ -267,7 +268,6 @@ def _is_membership_change_allowed( # FIXME (erikj): What should we do here as the default? ban_level = _get_named_level(auth_events, "ban", 50) - knock_level = _get_named_level(auth_events, "knock", 0) logger.debug( "_is_membership_change_allowed: %s", @@ -345,13 +345,14 @@ def _is_membership_change_allowed( if user_level < ban_level or user_level <= target_level: raise AuthError(403, "You don't have permission to ban") elif Membership.KNOCK == membership: - # check that we have the leave event - if target and target.membership != Membership.LEAVE: - raise AuthError(403, "You don't have permission to knock") - elif join_rule != JoinRules.INVITE: - raise AuthError(403, "You don't have permission to knock") - elif user_level < knock_level: + if join_rule != JoinRules.KNOCK: raise AuthError(403, "You don't have permission to knock") + elif target_user_id != event.user_id: + raise AuthError(403, "You cannot knock for other users") + elif target_in_room: + raise AuthError(403, "You cannot knock on a room you are already in") + elif target_banned: + raise AuthError(403, "You are banned from this room") else: raise AuthError(500, "Unknown membership %s" % membership) @@ -432,7 +433,10 @@ def _can_send_event(event: EventBase, auth_events: StateMap[EventBase]) -> bool: def check_redaction( - room_version_obj: RoomVersion, event: EventBase, auth_events: StateMap[EventBase], + room_version_obj: RoomVersion, + event: EventBase, + auth_events: StateMap[EventBase], + original_event: EventBase, ) -> bool: """Check whether the event sender is allowed to redact the target event. @@ -464,6 +468,13 @@ def check_redaction( event.internal_metadata.recheck_redaction = True return True + if ( + original_event.type == EventTypes.Member + and original_event.content + and original_event.content.get("membership", None) == Membership.KNOCK + ): + raise AuthError(403, "It is not possible to redact knocks") + raise AuthError(403, "You don't have permission to redact events") diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index 5891939bb1..f5f246138f 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -1116,7 +1116,7 @@ class EventCreationHandler: room_version_obj = KNOWN_ROOM_VERSIONS[room_version] if event_auth.check_redaction( - room_version_obj, event, auth_events=auth_events + room_version_obj, event, auth_events=auth_events, original_event=original_event ): # this user doesn't have 'redact' rights, so we need to do some more # checks on the original event. Let's start by checking the original