|  | 
| 23 | 23 | from synapse.util.stringutils import random_string | 
| 24 | 24 | 
 | 
| 25 | 25 | from tests import unittest | 
|  | 26 | +from tests.test_utils.event_injection import create_event | 
| 26 | 27 | 
 | 
| 27 | 28 | logger = logging.getLogger(__name__) | 
| 28 | 29 | 
 | 
| @@ -51,6 +52,24 @@ def prepare(self, reactor, clock, hs): | 
| 51 | 52 | 
 | 
| 52 | 53 |         self.requester = create_requester(self.user_id, access_token_id=self.token_id) | 
| 53 | 54 | 
 | 
|  | 55 | +    def _create_and_persist_member_event(self) -> Tuple[EventBase, EventContext]: | 
|  | 56 | +        # Create a member event we can use as an auth_event | 
|  | 57 | +        memberEvent, memberEventContext = self.get_success( | 
|  | 58 | +            create_event( | 
|  | 59 | +                self.hs, | 
|  | 60 | +                room_id=self.room_id, | 
|  | 61 | +                type="m.room.member", | 
|  | 62 | +                sender=self.requester.user.to_string(), | 
|  | 63 | +                state_key=self.requester.user.to_string(), | 
|  | 64 | +                content={"membership": "join"}, | 
|  | 65 | +            ) | 
|  | 66 | +        ) | 
|  | 67 | +        self.get_success( | 
|  | 68 | +            self.persist_event_storage.persist_event(memberEvent, memberEventContext) | 
|  | 69 | +        ) | 
|  | 70 | + | 
|  | 71 | +        return memberEvent, memberEventContext | 
|  | 72 | + | 
| 54 | 73 |     def _create_duplicate_event(self, txn_id: str) -> Tuple[EventBase, EventContext]: | 
| 55 | 74 |         """Create a new event with the given transaction ID. All events produced | 
| 56 | 75 |         by this method will be considered duplicates. | 
| @@ -156,6 +175,90 @@ def test_duplicated_txn_id_one_call(self): | 
| 156 | 175 |         self.assertEqual(len(events), 2) | 
| 157 | 176 |         self.assertEqual(events[0].event_id, events[1].event_id) | 
| 158 | 177 | 
 | 
|  | 178 | +    def test_when_empty_prev_events_allowed_create_event_with_empty_prev_events(self): | 
|  | 179 | +        """When we set allow_no_prev_events=True, should be able to create a | 
|  | 180 | +        event without any prev_events (only auth_events). | 
|  | 181 | +        """ | 
|  | 182 | +        # Create a member event we can use as an auth_event | 
|  | 183 | +        memberEvent, _ = self._create_and_persist_member_event() | 
|  | 184 | + | 
|  | 185 | +        # Try to create the event with empty prev_events bit with some auth_events | 
|  | 186 | +        event, _ = self.get_success( | 
|  | 187 | +            self.handler.create_event( | 
|  | 188 | +                self.requester, | 
|  | 189 | +                { | 
|  | 190 | +                    "type": EventTypes.Message, | 
|  | 191 | +                    "room_id": self.room_id, | 
|  | 192 | +                    "sender": self.requester.user.to_string(), | 
|  | 193 | +                    "content": {"msgtype": "m.text", "body": random_string(5)}, | 
|  | 194 | +                }, | 
|  | 195 | +                # Empty prev_events is the key thing we're testing here | 
|  | 196 | +                prev_event_ids=[], | 
|  | 197 | +                # But with some auth_events | 
|  | 198 | +                auth_event_ids=[memberEvent.event_id], | 
|  | 199 | +                # Allow no prev_events! | 
|  | 200 | +                allow_no_prev_events=True, | 
|  | 201 | +            ) | 
|  | 202 | +        ) | 
|  | 203 | +        self.assertIsNotNone(event) | 
|  | 204 | + | 
|  | 205 | +    def test_when_empty_prev_events_not_allowed_reject_event_with_empty_prev_events( | 
|  | 206 | +        self, | 
|  | 207 | +    ): | 
|  | 208 | +        """When we set allow_no_prev_events=False, shouldn't be able to create a | 
|  | 209 | +        event without any prev_events even if it has auth_events. Expect an | 
|  | 210 | +        exception to be raised. | 
|  | 211 | +        """ | 
|  | 212 | +        # Create a member event we can use as an auth_event | 
|  | 213 | +        memberEvent, _ = self._create_and_persist_member_event() | 
|  | 214 | + | 
|  | 215 | +        # Try to create the event with empty prev_events but with some auth_events | 
|  | 216 | +        self.get_failure( | 
|  | 217 | +            self.handler.create_event( | 
|  | 218 | +                self.requester, | 
|  | 219 | +                { | 
|  | 220 | +                    "type": EventTypes.Message, | 
|  | 221 | +                    "room_id": self.room_id, | 
|  | 222 | +                    "sender": self.requester.user.to_string(), | 
|  | 223 | +                    "content": {"msgtype": "m.text", "body": random_string(5)}, | 
|  | 224 | +                }, | 
|  | 225 | +                # Empty prev_events is the key thing we're testing here | 
|  | 226 | +                prev_event_ids=[], | 
|  | 227 | +                # But with some auth_events | 
|  | 228 | +                auth_event_ids=[memberEvent.event_id], | 
|  | 229 | +                # We expect the test to fail because empty prev_events are not | 
|  | 230 | +                # allowed here! | 
|  | 231 | +                allow_no_prev_events=False, | 
|  | 232 | +            ), | 
|  | 233 | +            AssertionError, | 
|  | 234 | +        ) | 
|  | 235 | + | 
|  | 236 | +    def test_when_empty_prev_events_allowed_reject_event_with_empty_prev_events_and_auth_events( | 
|  | 237 | +        self, | 
|  | 238 | +    ): | 
|  | 239 | +        """When we set allow_no_prev_events=True, should be able to create a | 
|  | 240 | +        event without any prev_events or auth_events. Expect an exception to be | 
|  | 241 | +        raised. | 
|  | 242 | +        """ | 
|  | 243 | +        # Try to create the event with empty prev_events and empty auth_events | 
|  | 244 | +        self.get_failure( | 
|  | 245 | +            self.handler.create_event( | 
|  | 246 | +                self.requester, | 
|  | 247 | +                { | 
|  | 248 | +                    "type": EventTypes.Message, | 
|  | 249 | +                    "room_id": self.room_id, | 
|  | 250 | +                    "sender": self.requester.user.to_string(), | 
|  | 251 | +                    "content": {"msgtype": "m.text", "body": random_string(5)}, | 
|  | 252 | +                }, | 
|  | 253 | +                prev_event_ids=[], | 
|  | 254 | +                # The event should be rejected when there are no auth_events | 
|  | 255 | +                auth_event_ids=[], | 
|  | 256 | +                # Allow no prev_events! | 
|  | 257 | +                allow_no_prev_events=True, | 
|  | 258 | +            ), | 
|  | 259 | +            AssertionError, | 
|  | 260 | +        ) | 
|  | 261 | + | 
| 159 | 262 | 
 | 
| 160 | 263 | class ServerAclValidationTestCase(unittest.HomeserverTestCase): | 
| 161 | 264 |     servlets = [ | 
|  | 
0 commit comments