Example #1
0
def inject_event(hs: synapse.server.HomeServer,
                 room_version: Optional[str] = None,
                 prev_event_ids: Optional[Collection[str]] = None,
                 **kwargs) -> EventBase:
    """Inject a generic event into a room

    Args:
        hs: the homeserver under test
        room_version: the version of the room we're inserting into.
            if not specified, will be looked up
        prev_event_ids: prev_events for the event. If not specified, will be looked up
        kwargs: fields for the event to be created
    """
    test_reactor = hs.get_reactor()

    if room_version is None:
        d = hs.get_datastore().get_room_version_id(kwargs["room_id"])
        test_reactor.advance(0)
        room_version = get_awaitable_result(d)

    builder = hs.get_event_builder_factory().for_room_version(
        KNOWN_ROOM_VERSIONS[room_version], kwargs)
    d = hs.get_event_creation_handler().create_new_client_event(
        builder, prev_event_ids=prev_event_ids)
    test_reactor.advance(0)
    event, context = get_awaitable_result(d)

    d = hs.get_storage().persistence.persist_event(event, context)
    test_reactor.advance(0)
    get_awaitable_result(d)

    return event
Example #2
0
    def test_unexpected_auth_events(self):
        """Events with excess auth_events should be rejected

        https://spec.matrix.org/v1.3/rooms/v9/#authorization-rules
        2. Reject if event has auth_events that:
           2. have entries whose type and state_key don’t match those specified by the
              auth events selection algorithm described in the server specification.
        """
        creator = "@creator:example.com"

        create_event = _create_event(RoomVersions.V9, creator)
        join_event = _join_event(RoomVersions.V9, creator)
        pl_event = _power_levels_event(
            RoomVersions.V9,
            creator,
            {
                "state_default": 30,
                "users": {
                    "creator": 100
                }
            },
        )
        join_rules_event = _join_rules_event(RoomVersions.V9, creator,
                                             "public")

        event_store = _StubEventSourceStore()
        event_store.add_events(
            [create_event, join_event, pl_event, join_rules_event])

        good_event = _random_state_event(RoomVersions.V9, creator,
                                         [create_event, join_event, pl_event])
        # join rules should *not* be included in the auth events.
        bad_event = _random_state_event(
            RoomVersions.V9,
            creator,
            [create_event, join_event, pl_event, join_rules_event],
        )

        get_awaitable_result(
            event_auth.check_state_independent_auth_rules(
                event_store, good_event))
        with self.assertRaises(AuthError):
            get_awaitable_result(
                event_auth.check_state_independent_auth_rules(
                    event_store, bad_event))
Example #3
0
def create_event(hs: synapse.server.HomeServer,
                 room_version: Optional[str] = None,
                 prev_event_ids: Optional[Collection[str]] = None,
                 **kwargs) -> Tuple[EventBase, EventContext]:
    test_reactor = hs.get_reactor()

    if room_version is None:
        d = hs.get_datastore().get_room_version_id(kwargs["room_id"])
        test_reactor.advance(0)
        room_version = get_awaitable_result(d)

    builder = hs.get_event_builder_factory().for_room_version(
        KNOWN_ROOM_VERSIONS[room_version], kwargs)
    d = hs.get_event_creation_handler().create_new_client_event(
        builder, prev_event_ids=prev_event_ids)
    test_reactor.advance(0)
    event, context = get_awaitable_result(d)

    return event, context
Example #4
0
    def test_fast_call(self):
        """
        Test the behaviour when the underlying function completes immediately
        """
        async def f():
            return 12

        fast_call = Mock(side_effect=f)
        cached_call = CachedCall(fast_call)

        # the mock should not yet have been called
        fast_call.assert_not_called()

        # run the call a couple of times, which should complete immediately
        self.assertEqual(get_awaitable_result(cached_call.get()), 12)
        self.assertEqual(get_awaitable_result(cached_call.get()), 12)

        # the mock should have been called once
        fast_call.assert_called_once_with()
Example #5
0
    def test_create_event_with_prev_events(self):
        """A create event with prev_events should be rejected

        https://spec.matrix.org/v1.3/rooms/v9/#authorization-rules
        1: If type is m.room.create:
            1. If it has any previous events, reject.
        """
        creator = f"@creator:{TEST_DOMAIN}"

        # we make both a good event and a bad event, to check that we are rejecting
        # the bad event for the reason we think we are.
        good_event = make_event_from_dict(
            {
                "room_id": TEST_ROOM_ID,
                "type": "m.room.create",
                "state_key": "",
                "sender": creator,
                "content": {
                    "creator": creator,
                    "room_version": RoomVersions.V9.identifier,
                },
                "auth_events": [],
                "prev_events": [],
            },
            room_version=RoomVersions.V9,
        )
        bad_event = make_event_from_dict(
            {
                **good_event.get_dict(), "prev_events": ["$fakeevent"]
            },
            room_version=RoomVersions.V9,
        )

        event_store = _StubEventSourceStore()

        get_awaitable_result(
            event_auth.check_state_independent_auth_rules(
                event_store, good_event))
        with self.assertRaises(AuthError):
            get_awaitable_result(
                event_auth.check_state_independent_auth_rules(
                    event_store, bad_event))
Example #6
0
def inject_event(hs: synapse.server.HomeServer,
                 room_version: Optional[str] = None,
                 prev_event_ids: Optional[Collection[str]] = None,
                 **kwargs) -> EventBase:
    """Inject a generic event into a room

    Args:
        hs: the homeserver under test
        room_version: the version of the room we're inserting into.
            if not specified, will be looked up
        prev_event_ids: prev_events for the event. If not specified, will be looked up
        kwargs: fields for the event to be created
    """
    test_reactor = hs.get_reactor()

    event, context = create_event(hs, room_version, prev_event_ids, **kwargs)

    d = hs.get_storage().persistence.persist_event(event, context)
    test_reactor.advance(0)
    get_awaitable_result(d)

    return event
Example #7
0
    def test_get(self):
        """
        Happy-path test case: makes a couple of calls and makes sure they behave
        correctly
        """
        d = Deferred()

        async def f():
            return await d

        slow_call = Mock(side_effect=f)

        cached_call = CachedCall(slow_call)

        # the mock should not yet have been called
        slow_call.assert_not_called()

        # now fire off a couple of calls
        completed_results = []

        async def r():
            res = await cached_call.get()
            completed_results.append(res)

        r1 = defer.ensureDeferred(r())
        r2 = defer.ensureDeferred(r())

        # neither result should be complete yet
        self.assertNoResult(r1)
        self.assertNoResult(r2)

        # and the mock should have been called *once*, with no params
        slow_call.assert_called_once_with()

        # allow the deferred to complete, which should complete both the pending results
        d.callback(123)
        self.assertEqual(completed_results, [123, 123])
        self.successResultOf(r1)
        self.successResultOf(r2)

        # another call to the getter should complete immediately
        slow_call.reset_mock()
        r3 = get_awaitable_result(cached_call.get())
        self.assertEqual(r3, 123)
        slow_call.assert_not_called()
Example #8
0
    def test_duplicate_auth_events(self):
        """Events with duplicate auth_events should be rejected

        https://spec.matrix.org/v1.3/rooms/v9/#authorization-rules
        2. Reject if event has auth_events that:
            1. have duplicate entries for a given type and state_key pair
        """
        creator = "@creator:example.com"

        create_event = _create_event(RoomVersions.V9, creator)
        join_event1 = _join_event(RoomVersions.V9, creator)
        pl_event = _power_levels_event(
            RoomVersions.V9,
            creator,
            {
                "state_default": 30,
                "users": {
                    "creator": 100
                }
            },
        )

        # create a second join event, so that we can make a duplicate
        join_event2 = _join_event(RoomVersions.V9, creator)

        event_store = _StubEventSourceStore()
        event_store.add_events(
            [create_event, join_event1, join_event2, pl_event])

        good_event = _random_state_event(RoomVersions.V9, creator,
                                         [create_event, join_event2, pl_event])
        bad_event = _random_state_event(
            RoomVersions.V9, creator,
            [create_event, join_event1, join_event2, pl_event])
        # a variation: two instances of the *same* event
        bad_event2 = _random_state_event(
            RoomVersions.V9, creator,
            [create_event, join_event2, join_event2, pl_event])

        get_awaitable_result(
            event_auth.check_state_independent_auth_rules(
                event_store, good_event))
        with self.assertRaises(AuthError):
            get_awaitable_result(
                event_auth.check_state_independent_auth_rules(
                    event_store, bad_event))
        with self.assertRaises(AuthError):
            get_awaitable_result(
                event_auth.check_state_independent_auth_rules(
                    event_store, bad_event2))
Example #9
0
    def test_rejected_auth_events(self):
        """
        Events that refer to rejected events in their auth events are rejected
        """
        creator = "@creator:example.com"
        auth_events = [
            _create_event(RoomVersions.V9, creator),
            _join_event(RoomVersions.V9, creator),
        ]

        event_store = _StubEventSourceStore()
        event_store.add_events(auth_events)

        # creator should be able to send state
        event = _random_state_event(RoomVersions.V9, creator, auth_events)
        get_awaitable_result(
            event_auth.check_state_independent_auth_rules(event_store, event))
        event_auth.check_state_dependent_auth_rules(event, auth_events)

        # ... but a rejected join_rules event should cause it to be rejected
        rejected_join_rules = _join_rules_event(
            RoomVersions.V9,
            creator,
            "public",
        )
        rejected_join_rules.rejected_reason = "stinky"
        auth_events.append(rejected_join_rules)
        event_store.add_event(rejected_join_rules)

        with self.assertRaises(AuthError):
            get_awaitable_result(
                event_auth.check_state_independent_auth_rules(
                    event_store,
                    _random_state_event(RoomVersions.V9, creator),
                ))

        # ... even if there is *also* a good join rules
        auth_events.append(
            _join_rules_event(RoomVersions.V9, creator, "public"))
        event_store.add_event(rejected_join_rules)

        with self.assertRaises(AuthError):
            get_awaitable_result(
                event_auth.check_state_independent_auth_rules(
                    event_store,
                    _random_state_event(RoomVersions.V9, creator),
                ))
Example #10
0
    def test_invalidate_cascade(self):
        """Invalidations should cascade up through cache contexts"""
        class Cls:
            @cached(cache_context=True)
            async def func1(self, key, cache_context):
                return await self.func2(key,
                                        on_invalidate=cache_context.invalidate)

            @cached(cache_context=True)
            async def func2(self, key, cache_context):
                return self.func3(key, on_invalidate=cache_context.invalidate)

            @lru_cache(cache_context=True)
            def func3(self, key, cache_context):
                self.invalidate = cache_context.invalidate
                return 42

        obj = Cls()

        top_invalidate = mock.Mock()
        r = get_awaitable_result(obj.func1("k1", on_invalidate=top_invalidate))
        self.assertEqual(r, 42)
        obj.invalidate()
        top_invalidate.assert_called_once()
Example #11
0
 def test_skip_verification(self):
     """Provider metadata validation can be disabled by config."""
     with self.metadata_edit({"issuer": "http://insecure"}):
         # This should not throw
         get_awaitable_result(self.provider.load_metadata())
Example #12
0
        def force_load_metadata():
            async def force_load():
                return await h.load_metadata(force=True)

            return get_awaitable_result(force_load())
Example #13
0
    def test_get(self):
        # set up the RetryOnExceptionCachedCall around a function which will fail
        # (after a while)
        d = Deferred()

        async def f1():
            await d
            raise ValueError("moo")

        slow_call = Mock(side_effect=f1)
        cached_call = RetryOnExceptionCachedCall(slow_call)

        # the mock should not yet have been called
        slow_call.assert_not_called()

        # now fire off a couple of calls
        completed_results = []

        async def r():
            try:
                await cached_call.get()
            except Exception as e1:
                completed_results.append(e1)

        r1 = defer.ensureDeferred(r())
        r2 = defer.ensureDeferred(r())

        # neither result should be complete yet
        self.assertNoResult(r1)
        self.assertNoResult(r2)

        # and the mock should have been called *once*, with no params
        slow_call.assert_called_once_with()

        # complete the deferred, which should make the pending calls fail
        d.callback(0)
        self.assertEqual(len(completed_results), 2)
        for e in completed_results:
            self.assertIsInstance(e, ValueError)
            self.assertEqual(e.args, ("moo", ))

        # reset the mock to return a successful result, and make another pair of calls
        # to the getter
        d = Deferred()

        async def f2():
            return await d

        slow_call.reset_mock()
        slow_call.side_effect = f2
        r3 = defer.ensureDeferred(cached_call.get())
        r4 = defer.ensureDeferred(cached_call.get())

        self.assertNoResult(r3)
        self.assertNoResult(r4)
        slow_call.assert_called_once_with()

        # let that call complete, and check the results
        d.callback(123)
        self.assertEqual(self.successResultOf(r3), 123)
        self.assertEqual(self.successResultOf(r4), 123)

        # and now more calls to the getter should complete immediately
        slow_call.reset_mock()
        self.assertEqual(get_awaitable_result(cached_call.get()), 123)
        slow_call.assert_not_called()