summary refs log tree commit diff
path: root/synapse/third_party_rules/access_rules.py
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/third_party_rules/access_rules.py')
-rw-r--r--synapse/third_party_rules/access_rules.py55
1 files changed, 37 insertions, 18 deletions
diff --git a/synapse/third_party_rules/access_rules.py b/synapse/third_party_rules/access_rules.py

index 2519e05ae0..f158ab6676 100644 --- a/synapse/third_party_rules/access_rules.py +++ b/synapse/third_party_rules/access_rules.py
@@ -189,34 +189,40 @@ class RoomAccessRules(object): ) and access_rule == AccessRules.DIRECT: raise SynapseError(400, "Invalid access rule") + default_power_levels = self._get_default_power_levels( + requester.user.to_string() + ) + # Check if the creator can override values for the power levels. allowed = self._is_power_level_content_allowed( - config.get("power_level_content_override", {}), access_rule + config.get("power_level_content_override", {}), + access_rule, + default_power_levels, ) if not allowed: raise SynapseError(400, "Invalid power levels content override") - use_default_power_levels = True - if config.get("power_level_content_override"): - use_default_power_levels = False + custom_user_power_levels = config.get("power_level_content_override") # Second loop for events we need to know the current rule to process. for event in config.get("initial_state", []): if event["type"] == EventTypes.PowerLevels: allowed = self._is_power_level_content_allowed( - event["content"], access_rule + event["content"], access_rule, default_power_levels ) if not allowed: raise SynapseError(400, "Invalid power levels content") - use_default_power_levels = False - - # If power levels were not overridden by the user, override with DINUM's preferred - # defaults instead - if use_default_power_levels: - config["power_level_content_override"] = self._get_default_power_levels( - requester.user.to_string() - ) + custom_user_power_levels = event["content"] + if custom_user_power_levels: + # If the user is using their own power levels, but failed to provide an expected + # key in the power levels content dictionary, fill it in from the defaults instead + for key, value in default_power_levels.items(): + custom_user_power_levels.setdefault(key, value) + else: + # If power levels were not overridden by the user, completely override with the + # defaults instead + config["power_level_content_override"] = default_power_levels return True @@ -710,7 +716,11 @@ class RoomAccessRules(object): return True def _is_power_level_content_allowed( - self, content: Dict, access_rule: str, on_room_creation: bool = True + self, + content: Dict, + access_rule: str, + default_power_levels: Optional[Dict] = None, + on_room_creation: bool = True, ) -> bool: """Check if a given power levels event is permitted under the given access rule. @@ -721,6 +731,8 @@ class RoomAccessRules(object): Args: content: The content of the m.room.power_levels event to check. access_rule: The access rule in place in this room. + default_power_levels: The default power levels when a room is created with + the specified access rule. Required if on_room_creation is True. on_room_creation: True if this call is happening during a room's creation, False otherwise. @@ -733,12 +745,19 @@ class RoomAccessRules(object): # have a special circumstance, but still want to encourage a certain pattern during # room creation. if on_room_creation: - # If invite requirements are <PL50 - if content.get("invite", 50) < 50: + # We specifically don't fail if "invite" or "state_default" are None, as those + # values should be replaced with our "default" power level values anyways, + # which are compliant + + invite = default_power_levels["invite"] + state_default = default_power_levels["state_default"] + + # If invite requirements are less than our required defaults + if content.get("invite", invite) < invite: return False - # If "other" state requirements are <PL100 - if content.get("state_default", 100) < 100: + # If "other" state requirements are less than our required defaults + if content.get("state_default", state_default) < state_default: return False # Check if we need to apply the restrictions with the current rule.