Example #1
0
    def test_notify_interested_services_ephemeral(self):
        """
        Test sending ephemeral events to the appservice handler are scheduled
        to be pushed out to interested appservices, and that the stream ID is
        updated accordingly.
        """
        interested_service = self._mkservice(is_interested=True)
        services = [interested_service]

        self.mock_store.get_app_services.return_value = services
        self.mock_store.get_type_stream_id_for_appservice.return_value = make_awaitable(
            579
        )

        event = Mock(event_id="event_1")
        self.event_source.sources.receipt.get_new_events_as.return_value = (
            make_awaitable(([event], None))
        )

        self.handler.notify_interested_services_ephemeral("receipt_key", 580)
        self.mock_scheduler.submit_ephemeral_events_for_as.assert_called_once_with(
            interested_service, [event]
        )
        self.mock_store.set_type_stream_id_for_appservice.assert_called_once_with(
            interested_service,
            "read_receipt",
            580,
        )
Example #2
0
    def test_join_too_large(self):

        u1 = self.register_user("u1", "pass")

        handler = self.hs.get_room_member_handler()
        fed_transport = self.hs.get_federation_transport_client()

        # Mock out some things, because we don't want to test the whole join
        fed_transport.client.get_json = Mock(
            return_value=make_awaitable({"v1": 9999}))
        handler.federation_handler.do_invite_join = Mock(
            return_value=make_awaitable(("", 1)))

        d = handler._remote_join(
            None,
            ["other.example.com"],
            "roomid",
            UserID.from_string(u1),
            {"membership": "join"},
        )

        self.pump()

        # The request failed with a SynapseError saying the resource limit was
        # exceeded.
        f = self.get_failure(d, SynapseError)
        self.assertEqual(f.value.code, 400, f.value)
        self.assertEqual(f.value.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
Example #3
0
    def test_query_room_alias_exists(self):
        room_alias_str = "#foo:bar"
        room_alias = Mock()
        room_alias.to_string.return_value = room_alias_str

        room_id = "!alpha:bet"
        servers = ["aperture"]
        interested_service = self._mkservice_alias(is_interested_in_alias=True)
        services = [
            self._mkservice_alias(is_interested_in_alias=False),
            interested_service,
            self._mkservice_alias(is_interested_in_alias=False),
        ]

        self.mock_as_api.query_alias.return_value = make_awaitable(True)
        self.mock_store.get_app_services.return_value = services
        self.mock_store.get_association_from_room_alias.return_value = make_awaitable(
            Mock(room_id=room_id, servers=servers)
        )

        result = self.successResultOf(
            defer.ensureDeferred(self.handler.query_room_alias_exists(room_alias))
        )

        self.mock_as_api.query_alias.assert_called_once_with(
            interested_service, room_alias_str
        )
        self.assertEquals(result.room_id, room_id)
        self.assertEquals(result.servers, servers)
Example #4
0
    def test_join_too_large_admin(self):
        # An admin should be able to join rooms where a complexity check fails.

        u1 = self.register_user("u1", "pass", admin=True)

        handler = self.hs.get_room_member_handler()
        fed_transport = self.hs.get_federation_transport_client()

        # Mock out some things, because we don't want to test the whole join
        fed_transport.client.get_json = Mock(
            return_value=make_awaitable({"v1": 9999}))
        handler.federation_handler.do_invite_join = Mock(
            return_value=make_awaitable(("", 1)))

        d = handler._remote_join(
            None,
            ["other.example.com"],
            "roomid",
            UserID.from_string(u1),
            {"membership": "join"},
        )

        self.pump()

        # The request success since the user is an admin
        self.get_success(d)
Example #5
0
    def test_mau_limits_parity(self):
        # Ensure we're not at the unix epoch.
        self.reactor.advance(1)
        self.auth_blocking._limit_usage_by_mau = True

        # Set the server to be at the edge of too many users.
        self.hs.get_datastore().get_monthly_active_count = Mock(
            return_value=make_awaitable(self.auth_blocking._max_mau_value))

        # If not in monthly active cohort
        self.get_failure(
            self.auth_handler.create_access_token_for_user_id(
                self.user1, device_id=None, valid_until_ms=None),
            ResourceLimitError,
        )
        self.get_failure(
            self.auth_handler.validate_short_term_login_token(
                self._get_macaroon().serialize()),
            ResourceLimitError,
        )

        # If in monthly active cohort
        self.hs.get_datastore().user_last_seen_monthly_active = Mock(
            return_value=make_awaitable(self.clock.time_msec()))
        self.get_success(
            self.auth_handler.create_access_token_for_user_id(
                self.user1, device_id=None, valid_until_ms=None))
        self.get_success(
            self.auth_handler.validate_short_term_login_token(
                self._get_macaroon().serialize()))
    def prepare(self, reactor, clock, hs):
        self.server_notices_sender = self.hs.get_server_notices_sender()

        # relying on [1] is far from ideal, but the only case where
        # ResourceLimitsServerNotices class needs to be isolated is this test,
        # general code should never have a reason to do so ...
        self._rlsn = self.server_notices_sender._server_notices[1]
        if not isinstance(self._rlsn, ResourceLimitsServerNotices):
            raise Exception(
                "Failed to find reference to ResourceLimitsServerNotices")

        self._rlsn._store.user_last_seen_monthly_active = Mock(
            return_value=make_awaitable(1000))
        self._rlsn._server_notices_manager.send_notice = Mock(
            return_value=defer.succeed(Mock()))
        self._send_notice = self._rlsn._server_notices_manager.send_notice

        self.user_id = "@user_id:test"

        self._rlsn._server_notices_manager.get_or_create_notice_room_for_user = Mock(
            return_value=defer.succeed("!something:localhost"))
        self._rlsn._store.add_tag_to_room = Mock(
            return_value=defer.succeed(None))
        self._rlsn._store.get_tags_for_room = Mock(
            return_value=make_awaitable({}))
Example #7
0
 def test_auto_create_auto_join_rooms_when_user_is_not_the_first_real_user(
         self):
     self.store.count_real_users = Mock(return_value=make_awaitable(2))
     self.store.is_real_user = Mock(return_value=make_awaitable(True))
     user_id = self.get_success(
         self.handler.register_user(localpart="real"))
     rooms = self.get_success(self.store.get_rooms_for_user(user_id))
     self.assertEqual(len(rooms), 0)
    def _test_3pid_allowed(self, username: str, registration: bool):
        """Tests that the "is_3pid_allowed" module callback is called correctly, using
        either /register or /account URLs depending on the arguments.

        Args:
            username: The username to use for the test.
            registration: Whether to test with registration URLs.
        """
        self.hs.get_identity_handler().send_threepid_validation = Mock(
            return_value=make_awaitable(0), )

        m = Mock(return_value=make_awaitable(False))
        self.hs.get_password_auth_provider().is_3pid_allowed_callbacks = [m]

        self.register_user(username, "password")
        tok = self.login(username, "password")

        if registration:
            url = "/register/email/requestToken"
        else:
            url = "/account/3pid/email/requestToken"

        channel = self.make_request(
            "POST",
            url,
            {
                "client_secret": "foo",
                "email": "*****@*****.**",
                "send_attempt": 0,
            },
            access_token=tok,
        )
        self.assertEqual(channel.code, 403, channel.result)
        self.assertEqual(
            channel.json_body["errcode"],
            Codes.THREEPID_DENIED,
            channel.json_body,
        )

        m.assert_called_once_with("email", "*****@*****.**", registration)

        m = Mock(return_value=make_awaitable(True))
        self.hs.get_password_auth_provider().is_3pid_allowed_callbacks = [m]

        channel = self.make_request(
            "POST",
            url,
            {
                "client_secret": "foo",
                "email": "*****@*****.**",
                "send_attempt": 0,
            },
            access_token=tok,
        )
        self.assertEqual(channel.code, 200, channel.result)
        self.assertIn("sid", channel.json_body)

        m.assert_called_once_with("email", "*****@*****.**", registration)
Example #9
0
    def prepare(self, reactor, clock, hs):
        mock_notifier = hs.get_notifier()
        self.on_new_event = mock_notifier.on_new_event

        self.handler = hs.get_typing_handler()

        self.event_source = hs.get_event_sources().sources["typing"]

        self.datastore = hs.get_datastore()
        retry_timings_res = {
            "destination": "",
            "retry_last_ts": 0,
            "retry_interval": 0,
            "failure_ts": None,
        }
        self.datastore.get_destination_retry_timings.return_value = defer.succeed(
            retry_timings_res)

        self.datastore.get_device_updates_by_remote.side_effect = lambda destination, from_stream_id, limit: make_awaitable(
            (0, []))

        def get_received_txn_response(*args):
            return defer.succeed(None)

        self.datastore.get_received_txn_response = get_received_txn_response

        self.room_members = []

        async def check_user_in_room(room_id, user_id):
            if user_id not in [u.to_string() for u in self.room_members]:
                raise AuthError(401, "User is not in the room")
            return None

        hs.get_auth().check_user_in_room = check_user_in_room

        def get_joined_hosts_for_room(room_id):
            return {member.domain for member in self.room_members}

        self.datastore.get_joined_hosts_for_room = get_joined_hosts_for_room

        def get_users_in_room(room_id):
            return defer.succeed({str(u) for u in self.room_members})

        self.datastore.get_users_in_room = get_users_in_room

        self.datastore.get_user_directory_stream_pos.side_effect = (
            # we deliberately return a non-None stream pos to avoid doing an initial_spam
            lambda: make_awaitable(1))

        self.datastore.get_current_state_deltas.return_value = (0, None)

        self.datastore.get_to_device_stream_token = lambda: 0
        self.datastore.get_new_device_msgs_for_remote = lambda *args, **kargs: make_awaitable(
            ([], 0))
        self.datastore.delete_device_msgs_for_remote = lambda *args, **kargs: make_awaitable(
            None)
        self.datastore.set_received_txn_response = lambda *args, **kwargs: make_awaitable(
            None)
Example #10
0
    def test_register_mau_blocked(self):
        self.store.get_monthly_active_count = Mock(
            return_value=make_awaitable(self.lots_of_users))
        self.get_failure(self.handler.register_user(localpart="local_part"),
                         ResourceLimitError)

        self.store.get_monthly_active_count = Mock(
            return_value=make_awaitable(self.hs.config.server.max_mau_value))
        self.get_failure(self.handler.register_user(localpart="local_part"),
                         ResourceLimitError)
    def test_on_user_deactivation_status_changed(self) -> None:
        """Tests that the on_user_deactivation_status_changed module callback is called
        correctly when processing a user's deactivation.
        """
        # Register a mocked callback.
        deactivation_mock = Mock(return_value=make_awaitable(None))
        third_party_rules = self.hs.get_third_party_event_rules()
        third_party_rules._on_user_deactivation_status_changed_callbacks.append(
            deactivation_mock, )
        # Also register a mocked callback for profile updates, to check that the
        # deactivation code calls it in a way that let modules know the user is being
        # deactivated.
        profile_mock = Mock(return_value=make_awaitable(None))
        self.hs.get_third_party_event_rules(
        )._on_profile_update_callbacks.append(profile_mock, )

        # Register a user that we'll deactivate.
        user_id = self.register_user("altan", "password")
        tok = self.login("altan", "password")

        # Deactivate that user.
        channel = self.make_request(
            "POST",
            "/_matrix/client/v3/account/deactivate",
            {
                "auth": {
                    "type": LoginType.PASSWORD,
                    "password": "******",
                    "identifier": {
                        "type": "m.id.user",
                        "user": user_id,
                    },
                },
                "erase": True,
            },
            access_token=tok,
        )
        self.assertEqual(channel.code, 200, channel.json_body)

        # Check that the mock was called once.
        deactivation_mock.assert_called_once()
        args = deactivation_mock.call_args[0]

        # Check that the mock was called with the right user ID, and with a True
        # deactivated flag and a False by_admin flag.
        self.assertEqual(args[0], user_id)
        self.assertTrue(args[1])
        self.assertFalse(args[2])

        # Check that the profile update callback was called twice (once for the display
        # name and once for the avatar URL), and that the "deactivation" boolean is true.
        self.assertEqual(profile_mock.call_count, 2)
        args = profile_mock.call_args[0]
        self.assertTrue(args[3])
    def custom_auth_provider_ui_auth_test_body(self):
        # register the user and log in twice, to get two devices
        self.register_user("localuser", "localpass")
        tok1 = self.login("localuser", "localpass")
        self.login("localuser", "localpass", device_id="dev2")

        # make the initial request which returns a 401
        channel = self._delete_device(tok1, "dev2")
        self.assertEqual(channel.code, 401)
        # Ensure that flows are what is expected.
        self.assertIn({"stages": ["m.login.password"]},
                      channel.json_body["flows"])
        self.assertIn({"stages": ["test.login_type"]},
                      channel.json_body["flows"])
        session = channel.json_body["session"]

        # missing param
        body = {
            "auth": {
                "type": "test.login_type",
                "identifier": {
                    "type": "m.id.user",
                    "user": "******"
                },
                "session": session,
            },
        }

        channel = self._delete_device(tok1, "dev2", body)
        self.assertEqual(channel.code, 400)
        # there's a perfectly good M_MISSING_PARAM errcode, but heaven forfend we should
        # use it...
        self.assertIn("Missing parameters", channel.json_body["error"])
        mock_password_provider.check_auth.assert_not_called()
        mock_password_provider.reset_mock()

        # right params, but authing as the wrong user
        mock_password_provider.check_auth.return_value = make_awaitable(
            ("@user:bz", None))
        body["auth"]["test_field"] = "foo"
        channel = self._delete_device(tok1, "dev2", body)
        self.assertEqual(channel.code, 403)
        self.assertEqual(channel.json_body["errcode"], "M_FORBIDDEN")
        mock_password_provider.check_auth.assert_called_once_with(
            "localuser", "test.login_type", {"test_field": "foo"})
        mock_password_provider.reset_mock()

        # and finally, succeed
        mock_password_provider.check_auth.return_value = make_awaitable(
            ("@localuser:test", None))
        channel = self._delete_device(tok1, "dev2", body)
        self.assertEqual(channel.code, 200)
        mock_password_provider.check_auth.assert_called_once_with(
            "localuser", "test.login_type", {"test_field": "foo"})
Example #13
0
 def setUp(self):
     self.mock_store = Mock()
     self.mock_as_api = Mock()
     self.mock_scheduler = Mock()
     hs = Mock()
     hs.get_datastore.return_value = self.mock_store
     self.mock_store.get_received_ts.return_value = make_awaitable(0)
     self.mock_store.set_appservice_last_pos.return_value = make_awaitable(None)
     hs.get_application_service_api.return_value = self.mock_as_api
     hs.get_application_service_scheduler.return_value = self.mock_scheduler
     hs.get_clock.return_value = MockClock()
     self.handler = ApplicationServicesHandler(hs)
    def test_user_email_bound_via_sydent_internal_api(self):
        """Tests that emails are bound after registration if this option is set"""
        # Register user with an email address
        email = "*****@*****.**"

        # Mock Synapse's threepid validator
        get_threepid_validation_session = Mock(
            return_value=make_awaitable(
                {"medium": "email", "address": email, "validated_at": 0}
            )
        )
        self.store.get_threepid_validation_session = get_threepid_validation_session
        delete_threepid_session = Mock(return_value=make_awaitable(None))
        self.store.delete_threepid_session = delete_threepid_session

        # Mock Synapse's http json post method to check for the internal bind call
        post_json_get_json = Mock(return_value=make_awaitable(None))
        self.hs.get_identity_handler().http_client.post_json_get_json = (
            post_json_get_json
        )

        # Retrieve a UIA session ID
        channel = self.uia_register(
            401, {"username": "******", "password": "******"}
        )
        session_id = channel.json_body["session"]

        # Register our email address using the fake validation session above
        channel = self.uia_register(
            200,
            {
                "username": "******",
                "password": "******",
                "auth": {
                    "session": session_id,
                    "type": "m.login.email.identity",
                    "threepid_creds": {"sid": "blabla", "client_secret": "blablabla"},
                },
            },
        )
        self.assertEqual(channel.json_body["user_id"], "@alice:test")

        # Check that a bind attempt was made to our fake identity server
        post_json_get_json.assert_called_with(
            "https://is.example.com/_matrix/identity/internal/bind",
            {"address": "*****@*****.**", "medium": "email", "mxid": "@alice:test"},
        )

        # Check that we stored a mapping of this bind
        bound_threepids = self.get_success(
            self.store.user_get_bound_threepids("@alice:test")
        )
        self.assertListEqual(bound_threepids, [{"medium": "email", "address": email}])
Example #15
0
    def test_maybe_send_server_notice_to_user_not_in_mau_cohort(self):
        """
        Test when user is not part of the MAU cohort - this should not ever
        happen - but ...
        """
        self._rlsn._auth_blocking.check_auth_blocking = Mock(
            return_value=make_awaitable(None))
        self._rlsn._store.user_last_seen_monthly_active = Mock(
            return_value=make_awaitable(None))
        self.get_success(
            self._rlsn.maybe_send_server_notice_to_user(self.user_id))

        self._send_notice.assert_not_called()
Example #16
0
    def test_auto_create_auto_join_rooms_when_user_is_the_first_real_user(self):
        room_alias_str = "#room:test"

        self.store.count_real_users = Mock(return_value=make_awaitable(1))
        self.store.is_real_user = Mock(return_value=make_awaitable(True))
        user_id = self.get_success(self.handler.register_user(localpart="real"))
        rooms = self.get_success(self.store.get_rooms_for_user(user_id))
        directory_handler = self.hs.get_directory_handler()
        room_alias = RoomAlias.from_string(room_alias_str)
        room_id = self.get_success(directory_handler.get_association(room_alias))

        self.assertTrue(room_id["room_id"] in rooms)
        self.assertEqual(len(rooms), 1)
Example #17
0
    def test_populate_monthly_users_should_not_update(self):
        self.store.upsert_monthly_active_user = Mock(
            return_value=make_awaitable(None))  # type: ignore[assignment]

        self.store.is_trial_user = Mock(
            return_value=make_awaitable(False))  # type: ignore[assignment]
        self.store.user_last_seen_monthly_active = Mock(
            return_value=make_awaitable(self.hs.get_clock().time_msec()))

        d = self.store.populate_monthly_active_users("user_id")
        self.get_success(d)

        self.store.upsert_monthly_active_user.assert_not_called()
Example #18
0
    def test_get_or_create_user_mau_blocked(self):
        self.store.get_monthly_active_count = Mock(
            return_value=make_awaitable(self.lots_of_users))
        self.get_failure(
            self.get_or_create_user(self.requester, "b", "display_name"),
            ResourceLimitError,
        )

        self.store.get_monthly_active_count = Mock(
            return_value=make_awaitable(self.hs.config.server.max_mau_value))
        self.get_failure(
            self.get_or_create_user(self.requester, "b", "display_name"),
            ResourceLimitError,
        )
Example #19
0
    def test_maybe_send_server_notice_to_user_remove_blocked_notice(self):
        """Test when user has blocked notice, but should have it removed"""

        self._rlsn._auth_blocking.check_auth_blocking = Mock(
            return_value=make_awaitable(None))
        mock_event = Mock(type=EventTypes.Message,
                          content={"msgtype": ServerNoticeMsgType})
        self._rlsn._store.get_events = Mock(
            return_value=make_awaitable({"123": mock_event}))
        self.get_success(
            self._rlsn.maybe_send_server_notice_to_user(self.user_id))
        # Would be better to check the content, but once == remove blocking event
        self._rlsn._server_notices_manager.maybe_get_notice_room_for_user.assert_called_once(
        )
        self._send_notice.assert_called_once()
Example #20
0
    def test_mau_limits_not_exceeded(self):
        self.auth_blocking._limit_usage_by_mau = True

        self.hs.get_datastore().get_monthly_active_count = Mock(
            return_value=make_awaitable(self.small_number_of_users))
        # Ensure does not raise exception
        self.get_success(
            self.auth_handler.get_access_token_for_user_id(
                "user_a", device_id=None, valid_until_ms=None))

        self.hs.get_datastore().get_monthly_active_count = Mock(
            return_value=make_awaitable(self.small_number_of_users))
        self.get_success(
            self.auth_handler.validate_short_term_login_token(
                self._get_macaroon().serialize()))
Example #21
0
    def test_send_receipts(self):
        mock_send_transaction = (
            self.hs.get_federation_transport_client().send_transaction)
        mock_send_transaction.return_value = make_awaitable({})

        sender = self.hs.get_federation_sender()
        receipt = ReadReceipt("room_id", "m.read", "user_id", ["event_id"],
                              {"ts": 1234})
        self.successResultOf(
            defer.ensureDeferred(sender.send_read_receipt(receipt)))

        self.pump()

        # expect a call to send_transaction
        mock_send_transaction.assert_called_once()
        json_cb = mock_send_transaction.call_args[0][1]
        data = json_cb()
        self.assertEqual(
            data["edus"],
            [{
                "edu_type": "m.receipt",
                "content": {
                    "room_id": {
                        "m.read": {
                            "user_id": {
                                "event_ids": ["event_id"],
                                "data": {
                                    "ts": 1234
                                },
                            }
                        }
                    }
                },
            }],
        )
Example #22
0
 def test_get_3pe_protocols_multiple_protocol(self):
     service_one = self._mkservice(False, ["my-protocol"])
     service_two = self._mkservice(False, ["other-protocol"])
     self.mock_store.get_app_services.return_value = [
         service_one, service_two
     ]
     self.mock_as_api.get_3pe_protocol.return_value = make_awaitable({
         "x-protocol-data":
         42,
         "instances": []
     })
     response = self.successResultOf(
         defer.ensureDeferred(self.handler.get_3pe_protocols()))
     self.mock_as_api.get_3pe_protocol.assert_called()
     self.assertEqual(
         response,
         {
             "my-protocol": {
                 "x-protocol-data": 42,
                 "instances": []
             },
             "other-protocol": {
                 "x-protocol-data": 42,
                 "instances": []
             },
         },
     )
Example #23
0
    def test_complexity_simple(self):

        u1 = self.register_user("u1", "pass")
        u1_token = self.login("u1", "pass")

        room_1 = self.helper.create_room_as(u1, tok=u1_token)
        self.helper.send_state(
            room_1, event_type="m.room.topic", body={"topic": "foo"}, tok=u1_token
        )

        # Get the room complexity
        channel = self.make_request(
            "GET", "/_matrix/federation/unstable/rooms/%s/complexity" % (room_1,)
        )
        self.assertEquals(200, channel.code)
        complexity = channel.json_body["v1"]
        self.assertTrue(complexity > 0, complexity)

        # Artificially raise the complexity
        store = self.hs.get_datastore()
        store.get_current_state_event_counts = lambda x: make_awaitable(500 * 1.23)

        # Get the room complexity again -- make sure it's our artificial value
        channel = self.make_request(
            "GET", "/_matrix/federation/unstable/rooms/%s/complexity" % (room_1,)
        )
        self.assertEquals(200, channel.code)
        complexity = channel.json_body["v1"]
        self.assertEqual(complexity, 1.23)
    def test_send_event_single_sender(self):
        """Test that using a single federation sender worker correctly sends a
        new event.
        """
        mock_client = Mock(spec=["put_json"])
        mock_client.put_json.return_value = make_awaitable({})

        self.make_worker_hs(
            "synapse.app.federation_sender",
            {"send_federation": False},
            federation_http_client=mock_client,
        )

        user = self.register_user("user", "pass")
        token = self.login("user", "pass")

        room = self.create_room_with_remote_server(user, token)

        mock_client.put_json.reset_mock()

        self.create_and_send_event(room, UserID.from_string(user))
        self.replicate()

        # Assert that the event was sent out over federation.
        mock_client.put_json.assert_called()
        self.assertEqual(mock_client.put_json.call_args[0][0], "other_server")
        self.assertTrue(mock_client.put_json.call_args[1]["data"].get("pdus"))
    def test_retry_device_list_resync(self):
        """Tests that device lists are marked as stale if they couldn't be synced, and
        that stale device lists are retried periodically.
        """
        remote_user_id = "@john:test_remote"
        remote_origin = "test_remote"

        # Track the number of attempts to resync the user's device list.
        self.resync_attempts = 0

        # When this function is called, increment the number of resync attempts (only if
        # we're querying devices for the right user ID), then raise a
        # NotRetryingDestination error to fail the resync gracefully.
        def query_user_devices(destination, user_id):
            if user_id == remote_user_id:
                self.resync_attempts += 1

            raise NotRetryingDestination(0, 0, destination)

        # Register the mock on the federation client.
        federation_client = self.homeserver.get_federation_client()
        federation_client.query_user_devices = Mock(
            side_effect=query_user_devices)

        # Register a mock on the store so that the incoming update doesn't fail because
        # we don't share a room with the user.
        store = self.homeserver.get_datastore()
        store.get_rooms_for_user = Mock(
            return_value=make_awaitable(["!someroom:test"]))

        # Manually inject a fake device list update. We need this update to include at
        # least one prev_id so that the user's device list will need to be retried.
        device_list_updater = self.homeserver.get_device_handler(
        ).device_list_updater
        self.get_success(
            device_list_updater.incoming_device_list_update(
                origin=remote_origin,
                edu_content={
                    "deleted": False,
                    "device_display_name": "Mobile",
                    "device_id": "QBUAZIFURK",
                    "prev_id": [5],
                    "stream_id": 6,
                    "user_id": remote_user_id,
                },
            ))

        # Check that there was one resync attempt.
        self.assertEqual(self.resync_attempts, 1)

        # Check that the resync attempt failed and caused the user's device list to be
        # marked as stale.
        need_resync = self.get_success(
            store.get_user_ids_requiring_device_list_resync())
        self.assertIn(remote_user_id, need_resync)

        # Check that waiting for 30 seconds caused Synapse to retry resyncing the device
        # list.
        self.reactor.advance(30)
        self.assertEqual(self.resync_attempts, 2)
 def _mkservice(self, is_interested, protocols=None):
     service = Mock()
     service.is_interested.return_value = make_awaitable(is_interested)
     service.token = "mock_service_token"
     service.url = "mock_service_url"
     service.protocols = protocols
     return service
Example #27
0
    def test_query_user_exists_unknown_user(self):
        user_id = "@someone:anywhere"
        services = [self._mkservice(is_interested=True)]
        services[0].is_interested_in_user.return_value = True
        self.mock_store.get_app_services.return_value = services
        self.mock_store.get_user_by_id.return_value = make_awaitable(None)

        event = Mock(sender=user_id, type="m.room.message", room_id="!foo:bar")
        self.mock_as_api.query_user.return_value = make_awaitable(True)
        self.mock_store.get_new_events_for_appservice.side_effect = [
            make_awaitable((0, [event])),
        ]

        self.handler.notify_interested_services(RoomStreamToken(None, 0))

        self.mock_as_api.query_user.assert_called_once_with(services[0], user_id)
    def local_user_fallback_ui_auth_test_body(self):
        """rejected login should fall back to local db"""
        self.register_user("localuser", "localpass")

        # have the auth provider deny the request
        mock_password_provider.check_password.return_value = make_awaitable(
            False)

        # log in twice, to get two devices
        tok1 = self.login("localuser", "localpass")
        self.login("localuser", "localpass", device_id="dev2")
        mock_password_provider.check_password.reset_mock()

        # first delete should give a 401
        session = self._start_delete_device_session(tok1, "dev2")
        mock_password_provider.check_password.assert_not_called()

        # Wrong password
        channel = self._authed_delete_device(tok1, "dev2", session,
                                             "localuser", "xxx")
        self.assertEqual(channel.code, 401)  # XXX why not a 403?
        self.assertEqual(channel.json_body["errcode"], "M_FORBIDDEN")
        mock_password_provider.check_password.assert_called_once_with(
            "@localuser:test", "xxx")
        mock_password_provider.reset_mock()

        # Right password
        channel = self._authed_delete_device(tok1, "dev2", session,
                                             "localuser", "localpass")
        self.assertEqual(channel.code, 200)
        mock_password_provider.check_password.assert_called_once_with(
            "@localuser:test", "localpass")
    def password_only_auth_provider_login_test_body(self):
        # login flows should only have m.login.password
        flows = self._get_login_flows()
        self.assertEqual(flows, [{
            "type": "m.login.password"
        }] + ADDITIONAL_LOGIN_FLOWS)

        # check_password must return an awaitable
        mock_password_provider.check_password.return_value = make_awaitable(
            True)
        channel = self._send_password_login("u", "p")
        self.assertEqual(channel.code, 200, channel.result)
        self.assertEqual("@u:test", channel.json_body["user_id"])
        mock_password_provider.check_password.assert_called_once_with(
            "@u:test", "p")
        mock_password_provider.reset_mock()

        # login with mxid should work too
        channel = self._send_password_login("@u:bz", "p")
        self.assertEqual(channel.code, 200, channel.result)
        self.assertEqual("@u:bz", channel.json_body["user_id"])
        mock_password_provider.check_password.assert_called_once_with(
            "@u:bz", "p")
        mock_password_provider.reset_mock()

        # try a weird username / pass. Honestly it's unclear what we *expect* to happen
        # in these cases, but at least we can guard against the API changing
        # unexpectedly
        channel = self._send_password_login(" USER🙂NAME ",
                                            " pASS\U0001F622word ")
        self.assertEqual(channel.code, 200, channel.result)
        self.assertEqual("@ USER🙂NAME :test", channel.json_body["user_id"])
        mock_password_provider.check_password.assert_called_once_with(
            "@ USER🙂NAME :test", " pASS😢word ")
Example #30
0
    def test_single_service_up_txn_not_sent(self):
        # Test: The AS is up and the txn is not sent. A Recoverer is made and
        # started.
        service = Mock()
        events = [Mock(), Mock()]
        txn_id = "foobar"
        txn = Mock(id=txn_id, service=service, events=events)

        # mock methods
        self.store.get_appservice_state = Mock(
            return_value=defer.succeed(ApplicationServiceState.UP)
        )
        self.store.set_appservice_state = Mock(return_value=defer.succeed(True))
        txn.send = Mock(return_value=make_awaitable(False))  # fails to send
        self.store.create_appservice_txn = Mock(return_value=defer.succeed(txn))

        # actual call
        self.successResultOf(defer.ensureDeferred(self.txnctrl.send(service, events)))

        self.store.create_appservice_txn.assert_called_once_with(
            service=service, events=events, ephemeral=[]
        )
        self.assertEquals(1, self.recoverer_fn.call_count)  # recoverer made
        self.assertEquals(1, self.recoverer.recover.call_count)  # and invoked
        self.assertEquals(1, len(self.txnctrl.recoverers))  # and stored
        self.assertEquals(0, txn.complete.call_count)  # txn not completed
        self.store.set_appservice_state.assert_called_once_with(
            service, ApplicationServiceState.DOWN  # service marked as down
        )