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

Commit f8f6eea

Browse files
committed
WIP: Ported existing tests
1 parent 84dee3d commit f8f6eea

2 files changed

Lines changed: 171 additions & 9 deletions

File tree

tests/handlers/test_user_directory.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
from urllib.parse import quote
1717

1818
from twisted.test.proto_helpers import MemoryReactor
19+
from synapse.api.errors import Code
1920

2021
import synapse.rest.admin
2122
from synapse.api.constants import UserTypes
2223
from synapse.api.room_versions import RoomVersion, RoomVersions
2324
from synapse.appservice import ApplicationService
2425
from synapse.rest.client import login, register, room, user_directory
2526
from synapse.server import HomeServer
27+
from synapse.spam_checker_api import ALLOW, Decision
2628
from synapse.storage.roommember import ProfileInfo
2729
from synapse.types import create_requester
2830
from synapse.util import Clock
@@ -773,12 +775,24 @@ def test_spam_checker(self) -> None:
773775
s = self.get_success(self.handler.search_users(u1, "user2", 10))
774776
self.assertEqual(len(s["results"]), 1)
775777

776-
async def allow_all(user_profile: ProfileInfo) -> bool:
778+
async def allow_all_old(user_profile: ProfileInfo) -> bool:
777779
# Allow all users.
778780
return False
779781

780-
# Configure a spam checker that does not filter any users.
782+
# Configure a spam checker that does not filter any users (old-style)
781783
spam_checker = self.hs.get_spam_checker()
784+
spam_checker._check_username_for_spam_callbacks = [allow_all_old]
785+
786+
# The results do not change:
787+
# We get one search result when searching for user2 by user1.
788+
s = self.get_success(self.handler.search_users(u1, "user2", 10))
789+
self.assertEqual(len(s["results"]), 1)
790+
791+
async def allow_all(user_profile: ProfileInfo) -> Decision:
792+
# Allow all users.
793+
return ALLOW
794+
795+
# Configure a spam checker that does not filter any users
782796
spam_checker._check_username_for_spam_callbacks = [allow_all]
783797

784798
# The results do not change:
@@ -787,16 +801,28 @@ async def allow_all(user_profile: ProfileInfo) -> bool:
787801
self.assertEqual(len(s["results"]), 1)
788802

789803
# Configure a spam checker that filters all users.
790-
async def block_all(user_profile: ProfileInfo) -> bool:
804+
async def block_all_old(user_profile: ProfileInfo) -> bool:
791805
# All users are spammy.
792806
return True
793807

808+
spam_checker._check_username_for_spam_callbacks = [block_all_old]
809+
810+
# User1 now gets no search results for any of the other users.
811+
s = self.get_success(self.handler.search_users(u1, "user2", 10))
812+
self.assertEqual(len(s["results"]), 0)
813+
814+
# Configure a spam checker that filters all users.
815+
async def block_all(user_profile: ProfileInfo) -> bool:
816+
# All users are spammy.
817+
return Code.FORBIDDEN
818+
794819
spam_checker._check_username_for_spam_callbacks = [block_all]
795820

796821
# User1 now gets no search results for any of the other users.
797822
s = self.get_success(self.handler.search_users(u1, "user2", 10))
798823
self.assertEqual(len(s["results"]), 0)
799824

825+
800826
def test_legacy_spam_checker(self) -> None:
801827
"""
802828
A spam checker without the expected method should be ignored.

tests/rest/client/test_rooms.py

Lines changed: 142 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@
3131
Membership,
3232
RelationTypes,
3333
)
34-
from synapse.api.errors import Codes, HttpResponseException
34+
from synapse.api.errors import Code, Codes, HttpResponseException
3535
from synapse.handlers.pagination import PurgeStatus
3636
from synapse.rest import admin
3737
from synapse.rest.client import account, directory, login, profile, room, sync
3838
from synapse.server import HomeServer
39+
from synapse.spam_checker_api import ALLOW, Decision
3940
from synapse.types import JsonDict, RoomAlias, UserID, create_requester
4041
from synapse.util import Clock
4142
from synapse.util.stringutils import random_string
@@ -676,9 +677,9 @@ def test_post_room_invitees_ratelimit(self) -> None:
676677
channel = self.make_request("POST", "/createRoom", content)
677678
self.assertEqual(200, channel.code)
678679

679-
def test_spam_checker_may_join_room(self) -> None:
680+
def test_spam_checker_may_join_room_old(self) -> None:
680681
"""Tests that the user_may_join_room spam checker callback is correctly bypassed
681-
when creating a new room.
682+
when creating a new room (old-style API, returning a boolean).
682683
"""
683684

684685
async def user_may_join_room(
@@ -700,6 +701,29 @@ async def user_may_join_room(
700701

701702
self.assertEqual(join_mock.call_count, 0)
702703

704+
def test_spam_checker_may_join_room(self) -> None:
705+
"""Tests that the user_may_join_room spam checker callback is correctly bypassed
706+
when creating a new room.
707+
"""
708+
709+
async def user_may_join_room(
710+
mxid: str,
711+
room_id: str,
712+
is_invite: bool,
713+
) -> Decision:
714+
return Code.FORBIDDEN
715+
716+
join_mock = Mock(side_effect=user_may_join_room)
717+
self.hs.get_spam_checker()._user_may_join_room_callbacks.append(join_mock)
718+
719+
channel = self.make_request(
720+
"POST",
721+
"/createRoom",
722+
{},
723+
)
724+
self.assertEqual(channel.code, 200, channel.json_body)
725+
726+
self.assertEqual(join_mock.call_count, 0)
703727

704728
class RoomTopicTestCase(RoomBase):
705729
"""Tests /rooms/$room_id/topic REST events."""
@@ -910,9 +934,9 @@ def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
910934
self.room2 = self.helper.create_room_as(room_creator=self.user1, tok=self.tok1)
911935
self.room3 = self.helper.create_room_as(room_creator=self.user1, tok=self.tok1)
912936

913-
def test_spam_checker_may_join_room(self) -> None:
937+
def test_spam_checker_may_join_room_old(self) -> None:
914938
"""Tests that the user_may_join_room spam checker callback is correctly called
915-
and blocks room joins when needed.
939+
and blocks room joins when needed (old-style API, return a boolean).
916940
"""
917941

918942
# Register a dummy callback. Make it allow all room joins for now.
@@ -967,6 +991,63 @@ async def user_may_join_room(
967991
return_value = False
968992
self.helper.join(self.room3, self.user2, expect_code=403, tok=self.tok2)
969993

994+
def test_spam_checker_may_join_room(self) -> None:
995+
"""Tests that the user_may_join_room spam checker callback is correctly called
996+
and blocks room joins when needed.
997+
"""
998+
999+
# Register a dummy callback. Make it allow all room joins for now.
1000+
return_value = ALLOW
1001+
1002+
async def user_may_join_room(
1003+
userid: str,
1004+
room_id: str,
1005+
is_invited: bool,
1006+
) -> Decision:
1007+
return return_value
1008+
1009+
callback_mock = Mock(side_effect=user_may_join_room)
1010+
self.hs.get_spam_checker()._user_may_join_room_callbacks.append(callback_mock)
1011+
1012+
# Join a first room, without being invited to it.
1013+
self.helper.join(self.room1, self.user2, tok=self.tok2)
1014+
1015+
# Check that the callback was called with the right arguments.
1016+
expected_call_args = (
1017+
(
1018+
self.user2,
1019+
self.room1,
1020+
False,
1021+
),
1022+
)
1023+
self.assertEqual(
1024+
callback_mock.call_args,
1025+
expected_call_args,
1026+
callback_mock.call_args,
1027+
)
1028+
1029+
# Join a second room, this time with an invite for it.
1030+
self.helper.invite(self.room2, self.user1, self.user2, tok=self.tok1)
1031+
self.helper.join(self.room2, self.user2, tok=self.tok2)
1032+
1033+
# Check that the callback was called with the right arguments.
1034+
expected_call_args = (
1035+
(
1036+
self.user2,
1037+
self.room2,
1038+
True,
1039+
),
1040+
)
1041+
self.assertEqual(
1042+
callback_mock.call_args,
1043+
expected_call_args,
1044+
callback_mock.call_args,
1045+
)
1046+
1047+
# Now make the callback deny all room joins, and check that a join actually fails.
1048+
return_value = Code.FORBIDDEN
1049+
self.helper.join(self.room3, self.user2, expect_code=403, tok=self.tok2)
1050+
9701051

9711052
class RoomJoinRatelimitTestCase(RoomBase):
9721053
user_id = "@sid1:red"
@@ -2586,7 +2667,7 @@ def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
25862667

25872668
self.room_id = self.helper.create_room_as(self.user_id, tok=self.tok)
25882669

2589-
def test_threepid_invite_spamcheck(self) -> None:
2670+
def test_threepid_invite_spamcheck_old(self) -> None:
25902671
# Mock a few functions to prevent the test from failing due to failing to talk to
25912672
# a remote IS. We keep the mock for _mock_make_and_store_3pid_invite around so we
25922673
# can check its call_count later on during the test.
@@ -2640,3 +2721,58 @@ def test_threepid_invite_spamcheck(self) -> None:
26402721

26412722
# Also check that it stopped before calling _make_and_store_3pid_invite.
26422723
make_invite_mock.assert_called_once()
2724+
2725+
def test_threepid_invite_spamcheck(self) -> None:
2726+
# Mock a few functions to prevent the test from failing due to failing to talk to
2727+
# a remote IS. We keep the mock for _mock_make_and_store_3pid_invite around so we
2728+
# can check its call_count later on during the test.
2729+
make_invite_mock = Mock(return_value=make_awaitable(0))
2730+
self.hs.get_room_member_handler()._make_and_store_3pid_invite = make_invite_mock
2731+
self.hs.get_identity_handler().lookup_3pid = Mock(
2732+
return_value=make_awaitable(None),
2733+
)
2734+
2735+
# Add a mock to the spamchecker callbacks for user_may_send_3pid_invite. Make it
2736+
# allow everything for now.
2737+
mock = Mock(return_value=make_awaitable(ALLOW))
2738+
self.hs.get_spam_checker()._user_may_send_3pid_invite_callbacks.append(mock)
2739+
2740+
# Send a 3PID invite into the room and check that it succeeded.
2741+
email_to_invite = "teresa@example.com"
2742+
channel = self.make_request(
2743+
method="POST",
2744+
path="/rooms/" + self.room_id + "/invite",
2745+
content={
2746+
"id_server": "example.com",
2747+
"id_access_token": "sometoken",
2748+
"medium": "email",
2749+
"address": email_to_invite,
2750+
},
2751+
access_token=self.tok,
2752+
)
2753+
self.assertEqual(channel.code, 200)
2754+
2755+
# Check that the callback was called with the right params.
2756+
mock.assert_called_with(self.user_id, "email", email_to_invite, self.room_id)
2757+
2758+
# Check that the call to send the invite was made.
2759+
make_invite_mock.assert_called_once()
2760+
2761+
# Now change the return value of the callback to deny any invite and test that
2762+
# we can't send the invite.
2763+
mock.return_value = make_awaitable(Code.FORBIDDEN)
2764+
channel = self.make_request(
2765+
method="POST",
2766+
path="/rooms/" + self.room_id + "/invite",
2767+
content={
2768+
"id_server": "example.com",
2769+
"id_access_token": "sometoken",
2770+
"medium": "email",
2771+
"address": email_to_invite,
2772+
},
2773+
access_token=self.tok,
2774+
)
2775+
self.assertEqual(channel.code, 403)
2776+
2777+
# Also check that it stopped before calling _make_and_store_3pid_invite.
2778+
make_invite_mock.assert_called_once()

0 commit comments

Comments
 (0)