Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Rename various ApplicationServices interested methods (#11915)
Browse files Browse the repository at this point in the history
  • Loading branch information
anoadragon453 authored Mar 3, 2022
1 parent 9297d04 commit fb0ffa9
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 76 deletions.
1 change: 1 addition & 0 deletions changelog.d/11915.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Simplify the `ApplicationService` class' set of public methods related to interest checking.
133 changes: 91 additions & 42 deletions synapse/appservice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,27 +175,14 @@ def _is_exclusive(self, namespace_key: str, test_string: str) -> bool:
return namespace.exclusive
return False

async def _matches_user(self, event: EventBase, store: "DataStore") -> bool:
if self.is_interested_in_user(event.sender):
return True

# also check m.room.member state key
if event.type == EventTypes.Member and self.is_interested_in_user(
event.state_key
):
return True

does_match = await self.matches_user_in_member_list(event.room_id, store)
return does_match

@cached(num_args=1, cache_context=True)
async def matches_user_in_member_list(
async def _matches_user_in_member_list(
self,
room_id: str,
store: "DataStore",
cache_context: _CacheContext,
) -> bool:
"""Check if this service is interested a room based upon it's membership
"""Check if this service is interested a room based upon its membership
Args:
room_id: The room to check.
Expand All @@ -214,47 +201,110 @@ async def matches_user_in_member_list(
return True
return False

def _matches_room_id(self, event: EventBase) -> bool:
if hasattr(event, "room_id"):
return self.is_interested_in_room(event.room_id)
return False
def is_interested_in_user(
self,
user_id: str,
) -> bool:
"""
Returns whether the application is interested in a given user ID.
The appservice is considered to be interested in a user if either: the
user ID is in the appservice's user namespace, or if the user is the
appservice's configured sender_localpart.
Args:
user_id: The ID of the user to check.
Returns:
True if the application service is interested in the user, False if not.
"""
return (
# User is the appservice's sender_localpart user
user_id == self.sender
# User is in the appservice's user namespace
or self.is_user_in_namespace(user_id)
)

@cached(num_args=1, cache_context=True)
async def is_interested_in_room(
self,
room_id: str,
store: "DataStore",
cache_context: _CacheContext,
) -> bool:
"""
Returns whether the application service is interested in a given room ID.
The appservice is considered to be interested in the room if either: the ID or one
of the aliases of the room is in the appservice's room ID or alias namespace
respectively, or if one of the members of the room fall into the appservice's user
namespace.
async def _matches_aliases(self, event: EventBase, store: "DataStore") -> bool:
alias_list = await store.get_aliases_for_room(event.room_id)
Args:
room_id: The ID of the room to check.
store: The homeserver's datastore class.
Returns:
True if the application service is interested in the room, False if not.
"""
# Check if we have interest in this room ID
if self.is_room_id_in_namespace(room_id):
return True

# likewise with the room's aliases (if it has any)
alias_list = await store.get_aliases_for_room(room_id)
for alias in alias_list:
if self.is_interested_in_alias(alias):
if self.is_room_alias_in_namespace(alias):
return True

return False
# And finally, perform an expensive check on whether any of the
# users in the room match the appservice's user namespace
return await self._matches_user_in_member_list(
room_id, store, on_invalidate=cache_context.invalidate
)

async def is_interested(self, event: EventBase, store: "DataStore") -> bool:
@cached(num_args=1, cache_context=True)
async def is_interested_in_event(
self,
event_id: str,
event: EventBase,
store: "DataStore",
cache_context: _CacheContext,
) -> bool:
"""Check if this service is interested in this event.
Args:
event_id: The ID of the event to check. This is purely used for simplifying the
caching of calls to this method.
event: The event to check.
store: The datastore to query.
Returns:
True if this service would like to know about this event.
True if this service would like to know about this event, otherwise False.
"""
# Do cheap checks first
if self._matches_room_id(event):
# Check if we're interested in this event's sender by namespace (or if they're the
# sender_localpart user)
if self.is_interested_in_user(event.sender):
return True

# This will check the namespaces first before
# checking the store, so should be run before _matches_aliases
if await self._matches_user(event, store):
# additionally, if this is a membership event, perform the same checks on
# the user it references
if event.type == EventTypes.Member and self.is_interested_in_user(
event.state_key
):
return True

# This will check the store, so should be run last
if await self._matches_aliases(event, store):
# This will check the datastore, so should be run last
if await self.is_interested_in_room(
event.room_id, store, on_invalidate=cache_context.invalidate
):
return True

return False

@cached(num_args=1)
@cached(num_args=1, cache_context=True)
async def is_interested_in_presence(
self, user_id: UserID, store: "DataStore"
self, user_id: UserID, store: "DataStore", cache_context: _CacheContext
) -> bool:
"""Check if this service is interested a user's presence
Expand All @@ -272,20 +322,19 @@ async def is_interested_in_presence(

# Then find out if the appservice is interested in any of those rooms
for room_id in room_ids:
if await self.matches_user_in_member_list(room_id, store):
if await self.is_interested_in_room(
room_id, store, on_invalidate=cache_context.invalidate
):
return True
return False

def is_interested_in_user(self, user_id: str) -> bool:
return (
bool(self._matches_regex(ApplicationService.NS_USERS, user_id))
or user_id == self.sender
)
def is_user_in_namespace(self, user_id: str) -> bool:
return bool(self._matches_regex(ApplicationService.NS_USERS, user_id))

def is_interested_in_alias(self, alias: str) -> bool:
def is_room_alias_in_namespace(self, alias: str) -> bool:
return bool(self._matches_regex(ApplicationService.NS_ALIASES, alias))

def is_interested_in_room(self, room_id: str) -> bool:
def is_room_id_in_namespace(self, room_id: str) -> bool:
return bool(self._matches_regex(ApplicationService.NS_ROOMS, room_id))

def is_exclusive_user(self, user_id: str) -> bool:
Expand Down
4 changes: 2 additions & 2 deletions synapse/handlers/appservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ async def query_room_alias_exists(
room_alias_str = room_alias.to_string()
services = self.store.get_app_services()
alias_query_services = [
s for s in services if (s.is_interested_in_alias(room_alias_str))
s for s in services if (s.is_room_alias_in_namespace(room_alias_str))
]
for alias_service in alias_query_services:
is_known_alias = await self.appservice_api.query_alias(
Expand Down Expand Up @@ -660,7 +660,7 @@ async def _get_services_for_event(
# inside of a list comprehension anymore.
interested_list = []
for s in services:
if await s.is_interested(event, self.store):
if await s.is_interested_in_event(event.event_id, event, self.store):
interested_list.append(s)

return interested_list
Expand Down
6 changes: 3 additions & 3 deletions synapse/handlers/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ async def create_association(

service = requester.app_service
if service:
if not service.is_interested_in_alias(room_alias_str):
if not service.is_room_alias_in_namespace(room_alias_str):
raise SynapseError(
400,
"This application service has not reserved this kind of alias.",
Expand Down Expand Up @@ -221,7 +221,7 @@ async def delete_association(
async def delete_appservice_association(
self, service: ApplicationService, room_alias: RoomAlias
) -> None:
if not service.is_interested_in_alias(room_alias.to_string()):
if not service.is_room_alias_in_namespace(room_alias.to_string()):
raise SynapseError(
400,
"This application service has not reserved this kind of alias",
Expand Down Expand Up @@ -376,7 +376,7 @@ def can_modify_alias(self, alias: RoomAlias, user_id: Optional[str] = None) -> b
# non-exclusive locks on the alias (or there are no interested services)
services = self.store.get_app_services()
interested_services = [
s for s in services if s.is_interested_in_alias(alias.to_string())
s for s in services if s.is_room_alias_in_namespace(alias.to_string())
]

for service in interested_services:
Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/receipts.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ async def get_new_events_as(
# Then filter down to rooms that the AS can read
events = []
for room_id, event in rooms_to_events.items():
if not await service.matches_user_in_member_list(room_id, self.store):
if not await service.is_interested_in_room(room_id, self.store):
continue

events.append(event)
Expand Down
4 changes: 1 addition & 3 deletions synapse/handlers/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,7 @@ async def get_new_events_as(
if handler._room_serials[room_id] <= from_key:
continue

if not await service.matches_user_in_member_list(
room_id, self._main_store
):
if not await service.is_interested_in_room(room_id, self._main_store):
continue

events.append(self._make_event_for(room_id))
Expand Down
45 changes: 34 additions & 11 deletions tests/appservice/test_appservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ def setUp(self):
hostname="matrix.org", # only used by get_groups_for_user
)
self.event = Mock(
type="m.something", room_id="!foo:bar", sender="@someone:somewhere"
event_id="$abc:xyz",
type="m.something",
room_id="!foo:bar",
sender="@someone:somewhere",
)

self.store = Mock()
Expand All @@ -50,7 +53,9 @@ def test_regex_user_id_prefix_match(self):
self.assertTrue(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -62,7 +67,9 @@ def test_regex_user_id_prefix_no_match(self):
self.assertFalse(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -76,7 +83,9 @@ def test_regex_room_member_is_checked(self):
self.assertTrue(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -90,7 +99,9 @@ def test_regex_room_id_match(self):
self.assertTrue(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -104,7 +115,9 @@ def test_regex_room_id_no_match(self):
self.assertFalse(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -121,7 +134,9 @@ def test_regex_alias_match(self):
self.assertTrue(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand Down Expand Up @@ -174,7 +189,9 @@ def test_regex_alias_no_match(self):
self.assertFalse(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -191,7 +208,9 @@ def test_regex_multiple_matches(self):
self.assertTrue(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -207,7 +226,9 @@ def test_interested_in_self(self):
self.assertTrue(
(
yield defer.ensureDeferred(
self.service.is_interested(self.event, self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Expand All @@ -225,7 +246,9 @@ def test_member_list_match(self):
self.assertTrue(
(
yield defer.ensureDeferred(
self.service.is_interested(event=self.event, store=self.store)
self.service.is_interested_in_event(
self.event.event_id, self.event, self.store
)
)
)
)
Loading

0 comments on commit fb0ffa9

Please sign in to comment.