summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--synapse/api/auth.py3
-rw-r--r--synapse/event_auth.py27
-rw-r--r--synapse/handlers/message.py2
3 files changed, 23 insertions, 9 deletions
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