@@ -175,27 +175,14 @@ def _is_exclusive(self, namespace_key: str, test_string: str) -> bool:
175175 return namespace .exclusive
176176 return False
177177
178- async def _matches_user (self , event : EventBase , store : "DataStore" ) -> bool :
179- if self .is_interested_in_user (event .sender ):
180- return True
181-
182- # also check m.room.member state key
183- if event .type == EventTypes .Member and self .is_interested_in_user (
184- event .state_key
185- ):
186- return True
187-
188- does_match = await self .matches_user_in_member_list (event .room_id , store )
189- return does_match
190-
191178 @cached (num_args = 1 , cache_context = True )
192- async def matches_user_in_member_list (
179+ async def _matches_user_in_member_list (
193180 self ,
194181 room_id : str ,
195182 store : "DataStore" ,
196183 cache_context : _CacheContext ,
197184 ) -> bool :
198- """Check if this service is interested a room based upon it's membership
185+ """Check if this service is interested a room based upon its membership
199186
200187 Args:
201188 room_id: The room to check.
@@ -214,47 +201,110 @@ async def matches_user_in_member_list(
214201 return True
215202 return False
216203
217- def _matches_room_id (self , event : EventBase ) -> bool :
218- if hasattr (event , "room_id" ):
219- return self .is_interested_in_room (event .room_id )
220- return False
204+ def is_interested_in_user (
205+ self ,
206+ user_id : str ,
207+ ) -> bool :
208+ """
209+ Returns whether the application is interested in a given user ID.
210+
211+ The appservice is considered to be interested in a user if either: the
212+ user ID is in the appservice's user namespace, or if the user is the
213+ appservice's configured sender_localpart.
214+
215+ Args:
216+ user_id: The ID of the user to check.
217+
218+ Returns:
219+ True if the application service is interested in the user, False if not.
220+ """
221+ return (
222+ # User is the appservice's sender_localpart user
223+ user_id == self .sender
224+ # User is in the appservice's user namespace
225+ or self .is_user_in_namespace (user_id )
226+ )
227+
228+ @cached (num_args = 1 , cache_context = True )
229+ async def is_interested_in_room (
230+ self ,
231+ room_id : str ,
232+ store : "DataStore" ,
233+ cache_context : _CacheContext ,
234+ ) -> bool :
235+ """
236+ Returns whether the application service is interested in a given room ID.
237+
238+ The appservice is considered to be interested in the room if either: the ID or one
239+ of the aliases of the room is in the appservice's room ID or alias namespace
240+ respectively, or if one of the members of the room fall into the appservice's user
241+ namespace.
221242
222- async def _matches_aliases (self , event : EventBase , store : "DataStore" ) -> bool :
223- alias_list = await store .get_aliases_for_room (event .room_id )
243+ Args:
244+ room_id: The ID of the room to check.
245+ store: The homeserver's datastore class.
246+
247+ Returns:
248+ True if the application service is interested in the room, False if not.
249+ """
250+ # Check if we have interest in this room ID
251+ if self .is_room_id_in_namespace (room_id ):
252+ return True
253+
254+ # likewise with the room's aliases (if it has any)
255+ alias_list = await store .get_aliases_for_room (room_id )
224256 for alias in alias_list :
225- if self .is_interested_in_alias (alias ):
257+ if self .is_room_alias_in_namespace (alias ):
226258 return True
227259
228- return False
260+ # And finally, perform an expensive check on whether any of the
261+ # users in the room match the appservice's user namespace
262+ return await self ._matches_user_in_member_list (
263+ room_id , store , on_invalidate = cache_context .invalidate
264+ )
229265
230- async def is_interested (self , event : EventBase , store : "DataStore" ) -> bool :
266+ @cached (num_args = 1 , cache_context = True )
267+ async def is_interested_in_event (
268+ self ,
269+ event_id : str ,
270+ event : EventBase ,
271+ store : "DataStore" ,
272+ cache_context : _CacheContext ,
273+ ) -> bool :
231274 """Check if this service is interested in this event.
232275
233276 Args:
277+ event_id: The ID of the event to check. This is purely used for simplifying the
278+ caching of calls to this method.
234279 event: The event to check.
235280 store: The datastore to query.
236281
237282 Returns:
238- True if this service would like to know about this event.
283+ True if this service would like to know about this event, otherwise False .
239284 """
240- # Do cheap checks first
241- if self ._matches_room_id (event ):
285+ # Check if we're interested in this event's sender by namespace (or if they're the
286+ # sender_localpart user)
287+ if self .is_interested_in_user (event .sender ):
242288 return True
243289
244- # This will check the namespaces first before
245- # checking the store, so should be run before _matches_aliases
246- if await self ._matches_user (event , store ):
290+ # additionally, if this is a membership event, perform the same checks on
291+ # the user it references
292+ if event .type == EventTypes .Member and self .is_interested_in_user (
293+ event .state_key
294+ ):
247295 return True
248296
249- # This will check the store, so should be run last
250- if await self ._matches_aliases (event , store ):
297+ # This will check the datastore, so should be run last
298+ if await self .is_interested_in_room (
299+ event .room_id , store , on_invalidate = cache_context .invalidate
300+ ):
251301 return True
252302
253303 return False
254304
255- @cached (num_args = 1 )
305+ @cached (num_args = 1 , cache_context = True )
256306 async def is_interested_in_presence (
257- self , user_id : UserID , store : "DataStore"
307+ self , user_id : UserID , store : "DataStore" , cache_context : _CacheContext
258308 ) -> bool :
259309 """Check if this service is interested a user's presence
260310
@@ -272,20 +322,19 @@ async def is_interested_in_presence(
272322
273323 # Then find out if the appservice is interested in any of those rooms
274324 for room_id in room_ids :
275- if await self .matches_user_in_member_list (room_id , store ):
325+ if await self .is_interested_in_room (
326+ room_id , store , on_invalidate = cache_context .invalidate
327+ ):
276328 return True
277329 return False
278330
279- def is_interested_in_user (self , user_id : str ) -> bool :
280- return (
281- bool (self ._matches_regex (ApplicationService .NS_USERS , user_id ))
282- or user_id == self .sender
283- )
331+ def is_user_in_namespace (self , user_id : str ) -> bool :
332+ return bool (self ._matches_regex (ApplicationService .NS_USERS , user_id ))
284333
285- def is_interested_in_alias (self , alias : str ) -> bool :
334+ def is_room_alias_in_namespace (self , alias : str ) -> bool :
286335 return bool (self ._matches_regex (ApplicationService .NS_ALIASES , alias ))
287336
288- def is_interested_in_room (self , room_id : str ) -> bool :
337+ def is_room_id_in_namespace (self , room_id : str ) -> bool :
289338 return bool (self ._matches_regex (ApplicationService .NS_ROOMS , room_id ))
290339
291340 def is_exclusive_user (self , user_id : str ) -> bool :
0 commit comments