1515
1616import logging
1717import string
18- from typing import List
18+ from typing import Iterable , List , Optional
1919
2020from twisted .internet import defer
2121
2828 StoreError ,
2929 SynapseError ,
3030)
31+ from synapse .appservice import ApplicationService
3132from synapse .types import Requester , RoomAlias , UserID , get_domain_from_id
3233
3334from ._base import BaseHandler
@@ -55,7 +56,13 @@ def __init__(self, hs):
5556 self .spam_checker = hs .get_spam_checker ()
5657
5758 @defer .inlineCallbacks
58- def _create_association (self , room_alias , room_id , servers = None , creator = None ):
59+ def _create_association (
60+ self ,
61+ room_alias : RoomAlias ,
62+ room_id : str ,
63+ servers : Optional [Iterable [str ]] = None ,
64+ creator : Optional [str ] = None ,
65+ ):
5966 # general association creation for both human users and app services
6067
6168 for wchar in string .whitespace :
@@ -81,17 +88,21 @@ def _create_association(self, room_alias, room_id, servers=None, creator=None):
8188
8289 @defer .inlineCallbacks
8390 def create_association (
84- self , requester , room_alias , room_id , servers = None , check_membership = True ,
91+ self ,
92+ requester : Requester ,
93+ room_alias : RoomAlias ,
94+ room_id : str ,
95+ servers : Optional [List [str ]] = None ,
96+ check_membership : bool = True ,
8597 ):
8698 """Attempt to create a new alias
8799
88100 Args:
89- requester (Requester)
90- room_alias (RoomAlias)
91- room_id (str)
92- servers (list[str]|None): List of servers that others servers
93- should try and join via
94- check_membership (bool): Whether to check if the user is in the room
101+ requester
102+ room_alias
103+ room_id
104+ servers: Iterable of servers that others servers should try and join via
105+ check_membership: Whether to check if the user is in the room
95106 before the alias can be set (if the server's config requires it).
96107
97108 Returns:
@@ -145,15 +156,15 @@ def create_association(
145156 yield self ._create_association (room_alias , room_id , servers , creator = user_id )
146157
147158 @defer .inlineCallbacks
148- def delete_association (self , requester , room_alias ):
159+ def delete_association (self , requester : Requester , room_alias : RoomAlias ):
149160 """Remove an alias from the directory
150161
151162 (this is only meant for human users; AS users should call
152163 delete_appservice_association)
153164
154165 Args:
155- requester (Requester):
156- room_alias (RoomAlias):
166+ requester
167+ room_alias
157168
158169 Returns:
159170 Deferred[unicode]: room id that the alias used to point to
@@ -189,16 +200,16 @@ def delete_association(self, requester, room_alias):
189200 room_id = yield self ._delete_association (room_alias )
190201
191202 try :
192- yield self ._update_canonical_alias (
193- requester , requester .user .to_string (), room_id , room_alias
194- )
203+ yield self ._update_canonical_alias (requester , user_id , room_id , room_alias )
195204 except AuthError as e :
196205 logger .info ("Failed to update alias events: %s" , e )
197206
198207 return room_id
199208
200209 @defer .inlineCallbacks
201- def delete_appservice_association (self , service , room_alias ):
210+ def delete_appservice_association (
211+ self , service : ApplicationService , room_alias : RoomAlias
212+ ):
202213 if not service .is_interested_in_alias (room_alias .to_string ()):
203214 raise SynapseError (
204215 400 ,
@@ -208,7 +219,7 @@ def delete_appservice_association(self, service, room_alias):
208219 yield self ._delete_association (room_alias )
209220
210221 @defer .inlineCallbacks
211- def _delete_association (self , room_alias ):
222+ def _delete_association (self , room_alias : RoomAlias ):
212223 if not self .hs .is_mine (room_alias ):
213224 raise SynapseError (400 , "Room alias must be local" )
214225
@@ -217,7 +228,7 @@ def _delete_association(self, room_alias):
217228 return room_id
218229
219230 @defer .inlineCallbacks
220- def get_association (self , room_alias ):
231+ def get_association (self , room_alias : RoomAlias ):
221232 room_id = None
222233 if self .hs .is_mine (room_alias ):
223234 result = yield self .get_association_from_room_alias (room_alias )
@@ -282,7 +293,9 @@ def on_directory_query(self, args):
282293 )
283294
284295 @defer .inlineCallbacks
285- def _update_canonical_alias (self , requester , user_id , room_id , room_alias ):
296+ def _update_canonical_alias (
297+ self , requester : Requester , user_id : str , room_id : str , room_alias : RoomAlias
298+ ):
286299 """
287300 Send an updated canonical alias event if the removed alias was set as
288301 the canonical alias or listed in the alt_aliases field.
@@ -331,15 +344,15 @@ def _update_canonical_alias(self, requester, user_id, room_id, room_alias):
331344 )
332345
333346 @defer .inlineCallbacks
334- def get_association_from_room_alias (self , room_alias ):
347+ def get_association_from_room_alias (self , room_alias : RoomAlias ):
335348 result = yield self .store .get_association_from_room_alias (room_alias )
336349 if not result :
337350 # Query AS to see if it exists
338351 as_handler = self .appservice_handler
339352 result = yield as_handler .query_room_alias_exists (room_alias )
340353 return result
341354
342- def can_modify_alias (self , alias , user_id = None ):
355+ def can_modify_alias (self , alias : RoomAlias , user_id : Optional [ str ] = None ):
343356 # Any application service "interested" in an alias they are regexing on
344357 # can modify the alias.
345358 # Users can only modify the alias if ALL the interested services have
@@ -360,22 +373,42 @@ def can_modify_alias(self, alias, user_id=None):
360373 return defer .succeed (True )
361374
362375 @defer .inlineCallbacks
363- def _user_can_delete_alias (self , alias , user_id ):
376+ def _user_can_delete_alias (self , alias : RoomAlias , user_id : str ):
377+ """Determine whether a user can delete an alias.
378+
379+ One of the following must be true:
380+
381+ 1. The user created the alias.
382+ 2. The user is a server administrator.
383+ 3. The user has a power-level sufficient to send a canonical alias event
384+ for the current room.
385+
386+ """
364387 creator = yield self .store .get_room_alias_creator (alias .to_string ())
365388
366389 if creator is not None and creator == user_id :
367390 return True
368391
369- is_admin = yield self .auth .is_server_admin (UserID .from_string (user_id ))
370- return is_admin
392+ # Resolve the alias to the corresponding room.
393+ room_mapping = yield self .get_association (alias )
394+ room_id = room_mapping ["room_id" ]
395+ if not room_id :
396+ return False
397+
398+ res = yield self .auth .check_can_change_room_list (
399+ room_id , UserID .from_string (user_id )
400+ )
401+ return res
371402
372403 @defer .inlineCallbacks
373- def edit_published_room_list (self , requester , room_id , visibility ):
404+ def edit_published_room_list (
405+ self , requester : Requester , room_id : str , visibility : str
406+ ):
374407 """Edit the entry of the room in the published room list.
375408
376409 requester
377- room_id (str)
378- visibility (str) : "public" or "private"
410+ room_id
411+ visibility: "public" or "private"
379412 """
380413 user_id = requester .user .to_string ()
381414
@@ -400,7 +433,15 @@ def edit_published_room_list(self, requester, room_id, visibility):
400433 if room is None :
401434 raise SynapseError (400 , "Unknown room" )
402435
403- yield self .auth .check_can_change_room_list (room_id , requester .user )
436+ can_change_room_list = yield self .auth .check_can_change_room_list (
437+ room_id , requester .user
438+ )
439+ if not can_change_room_list :
440+ raise AuthError (
441+ 403 ,
442+ "This server requires you to be a moderator in the room to"
443+ " edit its room list entry" ,
444+ )
404445
405446 making_public = visibility == "public"
406447 if making_public :
@@ -421,16 +462,16 @@ def edit_published_room_list(self, requester, room_id, visibility):
421462
422463 @defer .inlineCallbacks
423464 def edit_published_appservice_room_list (
424- self , appservice_id , network_id , room_id , visibility
465+ self , appservice_id : str , network_id : str , room_id : str , visibility : str
425466 ):
426467 """Add or remove a room from the appservice/network specific public
427468 room list.
428469
429470 Args:
430- appservice_id (str) : ID of the appservice that owns the list
431- network_id (str) : The ID of the network the list is associated with
432- room_id (str)
433- visibility (str) : either "public" or "private"
471+ appservice_id: ID of the appservice that owns the list
472+ network_id: The ID of the network the list is associated with
473+ room_id
474+ visibility: either "public" or "private"
434475 """
435476 if visibility not in ["public" , "private" ]:
436477 raise SynapseError (400 , "Invalid visibility setting" )
0 commit comments