Add all the necessary checks to make banning work.
							parent
							
								
									3faa2ae78c
								
							
						
					
					
						commit
						b8ab9f1c0a
					
				|  | @ -45,7 +45,10 @@ class Auth(object): | |||
|         """ | ||||
|         try: | ||||
|             if hasattr(event, "room_id"): | ||||
|                 is_state = hasattr(event, "state_key") | ||||
| 
 | ||||
|                 if event.type == RoomMemberEvent.TYPE: | ||||
|                     yield self._can_replace_state(event) | ||||
|                     allowed = yield self.is_membership_change_allowed(event) | ||||
|                     defer.returnValue(allowed) | ||||
|                     return | ||||
|  | @ -56,10 +59,11 @@ class Auth(object): | |||
|                     room_id=snapshot.room_id, | ||||
|                 ) | ||||
| 
 | ||||
|                 if hasattr(event, "state_key"): | ||||
|                 if is_state: | ||||
|                     # TODO (erikj): This really only should be called for *new* | ||||
|                     # state | ||||
|                     yield self._can_add_state(event) | ||||
|                     yield self._can_replace_state(event) | ||||
|                 else: | ||||
|                     yield self._can_send_event(event) | ||||
| 
 | ||||
|  | @ -175,7 +179,7 @@ class Auth(object): | |||
|             else: | ||||
|                 ban_level = 5  # FIXME (erikj): What should we do here? | ||||
| 
 | ||||
|             if ban_level < user_level: | ||||
|             if user_level < ban_level: | ||||
|                 raise AuthError(403, "You don't have permission to ban") | ||||
|         else: | ||||
|             raise AuthError(500, "Unknown membership %s" % membership) | ||||
|  | @ -267,3 +271,35 @@ class Auth(object): | |||
|             ) | ||||
| 
 | ||||
|         defer.returnValue(True) | ||||
| 
 | ||||
|     @defer.inlineCallbacks | ||||
|     def _can_replace_state(self, event): | ||||
|         current_state = yield self.store.get_current_state( | ||||
|             event.room_id, | ||||
|             event.type, | ||||
|             event.state_key, | ||||
|         ) | ||||
| 
 | ||||
|         if current_state: | ||||
|             current_state = current_state[0] | ||||
| 
 | ||||
|         user_level = yield self.store.get_power_level( | ||||
|             event.room_id, | ||||
|             event.user_id, | ||||
|         ) | ||||
| 
 | ||||
|         if user_level: | ||||
|             user_level = int(user_level) | ||||
|         else: | ||||
|             user_level = 0 | ||||
| 
 | ||||
|         logger.debug("Checking power level for %s, %s", event.user_id, user_level) | ||||
|         if current_state and hasattr(current_state, "required_power_level"): | ||||
|             req = current_state.required_power_level | ||||
| 
 | ||||
|             logger.debug("Checked power level for %s, %s", event.user_id, req) | ||||
|             if user_level < req: | ||||
|                 raise AuthError( | ||||
|                     403, | ||||
|                     "You don't have permission to change that state" | ||||
|                 ) | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ class SynapseEvent(JsonEncodedObject): | |||
|         "user_id",  # sender/initiator | ||||
|         "content",  # HTTP body, JSON | ||||
|         "state_key", | ||||
|         "required_power_level", | ||||
|     ] | ||||
| 
 | ||||
|     internal_keys = [ | ||||
|  | @ -52,6 +53,7 @@ class SynapseEvent(JsonEncodedObject): | |||
|         "destinations", | ||||
|         "origin", | ||||
|         "outlier", | ||||
|         "power_level", | ||||
|     ] | ||||
| 
 | ||||
|     required_keys = [ | ||||
|  |  | |||
|  | @ -68,6 +68,7 @@ class Pdu(JsonEncodedObject): | |||
|         "power_level", | ||||
|         "prev_state_id", | ||||
|         "prev_state_origin", | ||||
|         "required_power_level", | ||||
|     ] | ||||
| 
 | ||||
|     internal_keys = [ | ||||
|  |  | |||
|  | @ -166,7 +166,7 @@ class RoomCreationHandler(BaseRoomHandler): | |||
| 
 | ||||
|         power_levels_event = create( | ||||
|             etype=RoomPowerLevelsEvent.TYPE, | ||||
|             **{creator.to_string(): 10} | ||||
|             **{creator.to_string(): 10, "default": 0} | ||||
|         ) | ||||
| 
 | ||||
|         join_rule = JoinRules.PUBLIC if is_public else JoinRules.INVITE | ||||
|  | @ -343,6 +343,16 @@ class RoomMemberHandler(BaseRoomHandler): | |||
|             if do_auth: | ||||
|                 yield self.auth.check(event, snapshot, raises=True) | ||||
| 
 | ||||
|             # If we're banning someone, set a req power level | ||||
|             if event.membership == Membership.BAN: | ||||
|                 if not hasattr(event, "required_power_level") or event.required_power_level is None: | ||||
|                     # Add some default required_power_level | ||||
|                     user_level = yield self.store.get_power_level( | ||||
|                         event.room_id, | ||||
|                         event.user_id, | ||||
|                     ) | ||||
|                     event.required_power_level = user_level | ||||
| 
 | ||||
|             if prev_state and prev_state.membership == event.membership: | ||||
|                 # double same action, treat this event as a NOOP. | ||||
|                 defer.returnValue({}) | ||||
|  |  | |||
|  | @ -165,8 +165,7 @@ class RoomStore(SQLBaseStore): | |||
|         rows = txn.execute(sql, (room_id, user_id,)).fetchall() | ||||
| 
 | ||||
|         if len(rows) == 1: | ||||
|             defer.returnValue(rows[0][0]) | ||||
|             return | ||||
|             return rows[0][0] | ||||
| 
 | ||||
|         sql = ( | ||||
|             "SELECT level FROM room_default_levels as r " | ||||
|  |  | |||
|  | @ -150,7 +150,7 @@ CREATE TABLE IF NOT EXISTS room_ops_levels( | |||
|     event_id TEXT NOT NULL, | ||||
|     room_id TEXT NOT NULL, | ||||
|     ban_level INTEGER, | ||||
|     kick_level INTEGER, | ||||
|     kick_level INTEGER | ||||
| ); | ||||
| 
 | ||||
| CREATE INDEX IF NOT EXISTS room_ops_levels_event_id ON room_ops_levels(event_id); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Erik Johnston
						Erik Johnston