@@ -189,34 +189,40 @@ async def on_create_room(
189189 ) and access_rule == AccessRules .DIRECT :
190190 raise SynapseError (400 , "Invalid access rule" )
191191
192+ default_power_levels = self ._get_default_power_levels (
193+ requester .user .to_string ()
194+ )
195+
192196 # Check if the creator can override values for the power levels.
193197 allowed = self ._is_power_level_content_allowed (
194- config .get ("power_level_content_override" , {}), access_rule
198+ config .get ("power_level_content_override" , {}),
199+ access_rule ,
200+ default_power_levels ,
195201 )
196202 if not allowed :
197203 raise SynapseError (400 , "Invalid power levels content override" )
198204
199- use_default_power_levels = True
200- if config .get ("power_level_content_override" ):
201- use_default_power_levels = False
205+ custom_user_power_levels = config .get ("power_level_content_override" )
202206
203207 # Second loop for events we need to know the current rule to process.
204208 for event in config .get ("initial_state" , []):
205209 if event ["type" ] == EventTypes .PowerLevels :
206210 allowed = self ._is_power_level_content_allowed (
207- event ["content" ], access_rule
211+ event ["content" ], access_rule , default_power_levels
208212 )
209213 if not allowed :
210214 raise SynapseError (400 , "Invalid power levels content" )
211215
212- use_default_power_levels = False
213-
214- # If power levels were not overridden by the user, override with DINUM's preferred
215- # defaults instead
216- if use_default_power_levels :
217- config ["power_level_content_override" ] = self ._get_default_power_levels (
218- requester .user .to_string ()
219- )
216+ custom_user_power_levels = event ["content" ]
217+ if custom_user_power_levels :
218+ # If the user is using their own power levels, but failed to provide an expected
219+ # key in the power levels content dictionary, fill it in from the defaults instead
220+ for key , value in default_power_levels .items ():
221+ custom_user_power_levels .setdefault (key , value )
222+ else :
223+ # If power levels were not overridden by the user, completely override with the
224+ # defaults instead
225+ config ["power_level_content_override" ] = default_power_levels
220226
221227 return True
222228
@@ -710,7 +716,11 @@ def _on_membership_or_invite_direct(
710716 return True
711717
712718 def _is_power_level_content_allowed (
713- self , content : Dict , access_rule : str , on_room_creation : bool = True
719+ self ,
720+ content : Dict ,
721+ access_rule : str ,
722+ default_power_levels : Optional [Dict ] = None ,
723+ on_room_creation : bool = True ,
714724 ) -> bool :
715725 """Check if a given power levels event is permitted under the given access rule.
716726
@@ -721,6 +731,8 @@ def _is_power_level_content_allowed(
721731 Args:
722732 content: The content of the m.room.power_levels event to check.
723733 access_rule: The access rule in place in this room.
734+ default_power_levels: The default power levels when a room is created with
735+ the specified access rule. Required if on_room_creation is True.
724736 on_room_creation: True if this call is happening during a room's
725737 creation, False otherwise.
726738
@@ -733,12 +745,19 @@ def _is_power_level_content_allowed(
733745 # have a special circumstance, but still want to encourage a certain pattern during
734746 # room creation.
735747 if on_room_creation :
736- # If invite requirements are <PL50
737- if content .get ("invite" , 50 ) < 50 :
748+ # We specifically don't fail if "invite" or "state_default" are None, as those
749+ # values should be replaced with our "default" power level values anyways,
750+ # which are compliant
751+
752+ invite = default_power_levels ["invite" ]
753+ state_default = default_power_levels ["state_default" ]
754+
755+ # If invite requirements are less than our required defaults
756+ if content .get ("invite" , invite ) < invite :
738757 return False
739758
740- # If "other" state requirements are <PL100
741- if content .get ("state_default" , 100 ) < 100 :
759+ # If "other" state requirements are less than our required defaults
760+ if content .get ("state_default" , state_default ) < state_default :
742761 return False
743762
744763 # Check if we need to apply the restrictions with the current rule.
0 commit comments