def update_group_summary_room(self, group_id, requester_user_id, room_id, category_id, content): """Add/update a room to the group summary """ yield self.check_group_is_ours( group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id, ) RoomID.from_string(room_id) # Ensure valid room id order = content.get("order", None) is_public = _parse_visibility_from_contents(content) yield self.store.add_room_to_summary( group_id=group_id, room_id=room_id, category_id=category_id, order=order, is_public=is_public, ) defer.returnValue({})
def add_room_to_group(self, group_id, requester_user_id, room_id, content): """Add room to group """ RoomID.from_string(room_id) # Ensure valid room id yield self.check_group_is_ours( group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id ) is_public = _parse_visibility_from_contents(content) yield self.store.add_room_to_group(group_id, room_id, is_public=is_public) defer.returnValue({})
def setUp(self): hs = yield setup_test_homeserver(resource_for_federation=Mock(), http_client=None) self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.handlers = hs.get_handlers() self.message_handler = self.handlers.message_handler self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") self.room1 = RoomID.from_string("!abc123:test") self.room2 = RoomID.from_string("!xyx987:test") self.depth = 1
async def lookup_room_alias( self, room_alias: RoomAlias) -> Tuple[RoomID, List[str]]: """ Get the room ID associated with a room alias. Args: room_alias: The alias to look up. Returns: A tuple of: The room ID as a RoomID object. Hosts likely to be participating in the room ([str]). Raises: SynapseError if room alias could not be found. """ directory_handler = self.directory_handler mapping = await directory_handler.get_association(room_alias) if not mapping: raise SynapseError(404, "No such room alias") room_id = mapping["room_id"] servers = mapping["servers"] # put the server which owns the alias at the front of the server list. if room_alias.domain in servers: servers.remove(room_alias.domain) servers.insert(0, room_alias.domain) return RoomID.from_string(room_id), servers
def setUp(self): hs = yield setup_test_homeserver(self.addCleanup) self.store = hs.get_datastore() self.room = RoomID.from_string("!abcde:test") self.alias = RoomAlias.from_string("#my-room:test")
def lookup_room_alias(self, room_alias): """ Get the room ID associated with a room alias. Args: room_alias (RoomAlias): The alias to look up. Returns: A tuple of: The room ID as a RoomID object. Hosts likely to be participating in the room ([str]). Raises: SynapseError if room alias could not be found. """ directory_handler = self.directory_handler mapping = yield directory_handler.get_association(room_alias) if not mapping: raise SynapseError(404, "No such room alias") room_id = mapping["room_id"] servers = mapping["servers"] # put the server which owns the alias at the front of the server list. if room_alias.domain in servers: servers.remove(room_alias.domain) servers.insert(0, room_alias.domain) defer.returnValue((RoomID.from_string(room_id), servers))
def setUp(self): hs = yield setup_test_homeserver() self.store = DirectoryStore(None, hs) self.room = RoomID.from_string("!abcde:test") self.alias = RoomAlias.from_string("#my-room:test")
def add_room_to_group(self, group_id, requester_user_id, room_id, content): """Add room to group """ RoomID.from_string(room_id) # Ensure valid room id yield self.check_group_is_ours(group_id, and_exists=True, and_is_admin=requester_user_id) is_public = _parse_visibility_from_contents(content) yield self.store.add_room_to_group(group_id, room_id, is_public=is_public) defer.returnValue({})
def setUp(self): hs = yield setup_test_homeserver() self.store = DirectoryStore(hs) self.room = RoomID.from_string("!abcde:test") self.alias = RoomAlias.from_string("#my-room:test")
def _check_definition(self, definition): """Check if the provided definition is valid. This inspects not only the types but also the values to make sure they make sense. Args: definition(dict): The filter definition Raises: SynapseError: If there was a problem with this definition. """ # NB: Filters are the complete json blobs. "Definitions" are an # individual top-level key e.g. public_user_data. Filters are made of # many definitions. if type(definition) != dict: raise SynapseError( 400, "Expected JSON object, not %s" % (definition,) ) # check rooms are valid room IDs room_id_keys = ["rooms", "not_rooms"] for key in room_id_keys: if key in definition: if type(definition[key]) != list: raise SynapseError(400, "Expected %s to be a list." % key) for room_id in definition[key]: RoomID.from_string(room_id) # check senders are valid user IDs user_id_keys = ["senders", "not_senders"] for key in user_id_keys: if key in definition: if type(definition[key]) != list: raise SynapseError(400, "Expected %s to be a list." % key) for user_id in definition[key]: UserID.from_string(user_id) # TODO: We don't limit event type values but we probably should... # check types are valid event types event_keys = ["types", "not_types"] for key in event_keys: if key in definition: if type(definition[key]) != list: raise SynapseError(400, "Expected %s to be a list." % key) for event_type in definition[key]: if not isinstance(event_type, basestring): raise SynapseError(400, "Event type should be a string")
def validate_builder(self, event: Union[EventBase, EventBuilder]): """Validates that the builder/event has roughly the right format. Only checks values that we expect a proto event to have, rather than all the fields an event would have """ strings = ["room_id", "sender", "type"] if hasattr(event, "state_key"): strings.append("state_key") for s in strings: if not isinstance(getattr(event, s), str): raise SynapseError(400, "Not '%s' a string type" % (s,)) RoomID.from_string(event.room_id) UserID.from_string(event.sender) if event.type == EventTypes.Message: strings = ["body", "msgtype"] self._ensure_strings(event.content, strings) elif event.type == EventTypes.Topic: self._ensure_strings(event.content, ["topic"]) self._ensure_state_event(event) elif event.type == EventTypes.Name: self._ensure_strings(event.content, ["name"]) self._ensure_state_event(event) elif event.type == EventTypes.Member: if "membership" not in event.content: raise SynapseError(400, "Content has not membership key") if event.content["membership"] not in Membership.LIST: raise SynapseError(400, "Invalid membership key") self._ensure_state_event(event) elif event.type == EventTypes.Tombstone: if "replacement_room" not in event.content: raise SynapseError(400, "Content has no replacement_room key") if event.content["replacement_room"] == event.room_id: raise SynapseError( 400, "Tombstone cannot reference the room it was sent in" ) self._ensure_state_event(event)
async def on_POST(self, request, room_identifier): requester = await self.auth.get_user_by_req(request) await assert_user_is_admin(self.auth, requester.user) content = parse_json_object_from_request(request) assert_params_in_dict(content, ["user_id"]) target_user = UserID.from_string(content["user_id"]) if not self.hs.is_mine(target_user): raise SynapseError(400, "This endpoint can only be used with local users") if not await self.admin_handler.get_user(target_user): raise NotFoundError("User not found") if RoomID.is_valid(room_identifier): room_id = room_identifier try: remote_room_hosts = [ x.decode("ascii") for x in request.args[b"server_name"] ] # type: Optional[List[str]] except Exception: remote_room_hosts = None elif RoomAlias.is_valid(room_identifier): handler = self.room_member_handler room_alias = RoomAlias.from_string(room_identifier) room_id, remote_room_hosts = await handler.lookup_room_alias(room_alias) room_id = room_id.to_string() else: raise SynapseError( 400, "%s was not legal room ID or room alias" % (room_identifier,) ) fake_requester = create_requester(target_user) # send invite if room has "JoinRules.INVITE" room_state = await self.state_handler.get_current_state(room_id) join_rules_event = room_state.get((EventTypes.JoinRules, "")) if join_rules_event: if not (join_rules_event.content.get("join_rule") == JoinRules.PUBLIC): await self.room_member_handler.update_membership( requester=requester, target=fake_requester.user, room_id=room_id, action="invite", remote_room_hosts=remote_room_hosts, ratelimit=False, ) await self.room_member_handler.update_membership( requester=fake_requester, target=fake_requester.user, room_id=room_id, action="join", remote_room_hosts=remote_room_hosts, ratelimit=False, ) return 200, {"room_id": room_id}
def _check_definition_room_lists(self, definition): """Check that "rooms" and "not_rooms" are lists of room ids if they are present Args: definition(dict): The filter definition Raises: SynapseError: If there was a problem with this definition. """ # check rooms are valid room IDs room_id_keys = ["rooms", "not_rooms"] for key in room_id_keys: if key in definition: if type(definition[key]) != list: raise SynapseError(400, "Expected %s to be a list." % key) for room_id in definition[key]: RoomID.from_string(room_id)
async def add_room_to_group(self, group_id: str, requester_user_id: str, room_id: str, content: JsonDict) -> JsonDict: """Add room to group""" RoomID.from_string(room_id) # Ensure valid room id await self.check_group_is_ours(group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id) is_public = _parse_visibility_from_contents(content) await self.store.add_room_to_group(group_id, room_id, is_public=is_public) return {}
def setUp(self): hs = yield setup_test_homeserver( resource_for_federation=Mock(), http_client=None, ) self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_injector = EventInjector(hs) self.handlers = hs.get_handlers() self.message_handler = self.handlers.message_handler self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") self.room1 = RoomID.from_string("!abc123:test") self.room2 = RoomID.from_string("!xyx987:test")
def set_avatar_url(self, target_user, requester, new_avatar_url, by_admin=False): yield self.store.set_room_avatar_url(RoomID.from_string(room_id), new_avatar_url)
def validate_builder(self, event): """Validates that the builder/event has roughly the right format. Only checks values that we expect a proto event to have, rather than all the fields an event would have Args: event (EventBuilder|FrozenEvent) """ strings = [ "room_id", "sender", "type", ] if hasattr(event, "state_key"): strings.append("state_key") for s in strings: if not isinstance(getattr(event, s), string_types): raise SynapseError(400, "Not '%s' a string type" % (s,)) RoomID.from_string(event.room_id) UserID.from_string(event.sender) if event.type == EventTypes.Message: strings = [ "body", "msgtype", ] self._ensure_strings(event.content, strings) elif event.type == EventTypes.Topic: self._ensure_strings(event.content, ["topic"]) elif event.type == EventTypes.Name: self._ensure_strings(event.content, ["name"]) elif event.type == EventTypes.Member: if "membership" not in event.content: raise SynapseError(400, "Content has not membership key") if event.content["membership"] not in Membership.LIST: raise SynapseError(400, "Invalid membership key")
def validate_builder(self, event): """Validates that the builder/event has roughly the right format. Only checks values that we expect a proto event to have, rather than all the fields an event would have Args: event (EventBuilder|FrozenEvent) """ strings = [ "room_id", "sender", "type", ] if hasattr(event, "state_key"): strings.append("state_key") for s in strings: if not isinstance(getattr(event, s), string_types): raise SynapseError(400, "Not '%s' a string type" % (s, )) RoomID.from_string(event.room_id) UserID.from_string(event.sender) if event.type == EventTypes.Message: strings = [ "body", "msgtype", ] self._ensure_strings(event.content, strings) elif event.type == EventTypes.Topic: self._ensure_strings(event.content, ["topic"]) elif event.type == EventTypes.Name: self._ensure_strings(event.content, ["name"]) elif event.type == EventTypes.Member: if "membership" not in event.content: raise SynapseError(400, "Content has not membership key") if event.content["membership"] not in Membership.LIST: raise SynapseError(400, "Invalid membership key")
def test_count_daily_messages(self): self.db_pool.runQuery("DELETE FROM stats_reporting") self.hs.clock.now = 100 # Never reported before, and nothing which could be reported count = yield self.store.count_daily_messages() self.assertIsNone(count) count = yield self.db_pool.runQuery("SELECT COUNT(*) FROM stats_reporting") self.assertEqual([(0,)], count) # Create something to report room = RoomID.from_string("!abc123:test") user = UserID.from_string("@raccoonlover:test") yield self.event_injector.create_room(room) self.base_event = yield self._get_last_stream_token() yield self.event_injector.inject_message(room, user, "Raccoons are really cute") # Never reported before, something could be reported, but isn't because # it isn't old enough. count = yield self.store.count_daily_messages() self.assertIsNone(count) self._assert_stats_reporting(1, self.hs.clock.now) # Already reported yesterday, two new events from today. yield self.event_injector.inject_message(room, user, "Yeah they are!") yield self.event_injector.inject_message(room, user, "Incredibly!") self.hs.clock.now += 60 * 60 * 24 count = yield self.store.count_daily_messages() self.assertEqual(2, count) # 2 since yesterday self._assert_stats_reporting(3, self.hs.clock.now) # 3 ever # Last reported too recently. yield self.event_injector.inject_message(room, user, "Who could disagree?") self.hs.clock.now += 60 * 60 * 22 count = yield self.store.count_daily_messages() self.assertIsNone(count) self._assert_stats_reporting(4, self.hs.clock.now) # Last reported too long ago yield self.event_injector.inject_message(room, user, "No one.") self.hs.clock.now += 60 * 60 * 26 count = yield self.store.count_daily_messages() self.assertIsNone(count) self._assert_stats_reporting(5, self.hs.clock.now) # And now let's actually report something yield self.event_injector.inject_message(room, user, "Indeed.") yield self.event_injector.inject_message(room, user, "Indeed.") yield self.event_injector.inject_message(room, user, "Indeed.") # A little over 24 hours is fine :) self.hs.clock.now += (60 * 60 * 24) + 50 count = yield self.store.count_daily_messages() self.assertEqual(3, count) self._assert_stats_reporting(8, self.hs.clock.now)
def _generate_room_id(self, creator_id, is_public): # autogen room IDs and try to create it. We may clash, so just # try a few times till one goes through, giving up eventually. attempts = 0 while attempts < 5: try: random_string = stringutils.random_string(18) gen_room_id = RoomID(random_string, self.hs.hostname).to_string() if isinstance(gen_room_id, bytes): gen_room_id = gen_room_id.decode("utf-8") yield self.store.store_room( room_id=gen_room_id, room_creator_user_id=creator_id, is_public=is_public, ) return gen_room_id except StoreError: attempts += 1 raise StoreError(500, "Couldn't generate a room ID.")
def on_GET(self, request, room_id): room = RoomID.from_string(room_id) avatar_url = yield self.profile_handler.get_room_avatar_url(room, ) ret = {} if avatar_url is not None: ret["room_icon_url"] = avatar_url defer.returnValue((200, ret))
def update_group_summary_room(self, group_id, user_id, room_id, category_id, content): """Add/update a room to the group summary """ yield self.check_group_is_ours(group_id, and_exists=True, and_is_admin=user_id) RoomID.from_string(room_id) # Ensure valid room id order = content.get("order", None) is_public = _parse_visibility_from_contents(content) yield self.store.add_room_to_summary( group_id=group_id, room_id=room_id, category_id=category_id, order=order, is_public=is_public, ) defer.returnValue({})
async def update_room_in_group(self, group_id, requester_user_id, room_id, config_key, content): """Update room in group """ RoomID.from_string(room_id) # Ensure valid room id await self.check_group_is_ours(group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id) if config_key == "m.visibility": is_public = _parse_visibility_dict(content) await self.store.update_room_in_group_visibility( group_id, room_id, is_public=is_public) else: raise SynapseError(400, "Uknown config option") return {}
async def on_DELETE(self, request: SynapseRequest, room_id: str) -> Tuple[int, JsonDict]: requester = await self._auth.get_user_by_req(request) await assert_user_is_admin(self._auth, requester.user) content = parse_json_object_from_request(request) block = content.get("block", False) if not isinstance(block, bool): raise SynapseError( HTTPStatus.BAD_REQUEST, "Param 'block' must be a boolean, if given", Codes.BAD_JSON, ) purge = content.get("purge", True) if not isinstance(purge, bool): raise SynapseError( HTTPStatus.BAD_REQUEST, "Param 'purge' must be a boolean, if given", Codes.BAD_JSON, ) force_purge = content.get("force_purge", False) if not isinstance(force_purge, bool): raise SynapseError( HTTPStatus.BAD_REQUEST, "Param 'force_purge' must be a boolean, if given", Codes.BAD_JSON, ) if not RoomID.is_valid(room_id): raise SynapseError(HTTPStatus.BAD_REQUEST, "%s is not a legal room ID" % (room_id, )) # Check this here, as otherwise we'll only fail after the background job has been started. if not await self._third_party_rules.check_can_shutdown_room( requester.user.to_string(), room_id): raise SynapseError(403, "Shutdown of this room is forbidden", Codes.FORBIDDEN) delete_id = self._pagination_handler.start_shutdown_and_purge_room( room_id=room_id, new_room_user_id=content.get("new_room_user_id"), new_room_name=content.get("room_name"), message=content.get("message"), requester_user_id=requester.user.to_string(), block=block, purge=purge, force_purge=force_purge, ) return HTTPStatus.OK, {"delete_id": delete_id}
def update_room_in_group(self, group_id, requester_user_id, room_id, config_key, content): """Update room in group """ RoomID.from_string(room_id) # Ensure valid room id yield self.check_group_is_ours( group_id, requester_user_id, and_exists=True, and_is_admin=requester_user_id ) if config_key == "m.visibility": is_public = _parse_visibility_dict(content) yield self.store.update_room_in_group_visibility( group_id, room_id, is_public=is_public, ) else: raise SynapseError(400, "Uknown config option") defer.returnValue({})
def setUp(self): hs = setup_test_homeserver(self.addCleanup) # Room events need the full datastore, for persist_event() and # get_room_state() self.store = hs.get_datastore() self.event_factory = hs.get_event_factory() self.room = RoomID.from_string("!abcde:test") yield self.store.store_room( self.room.to_string(), room_creator_user_id="@creator:text", is_public=True )
def _generate_room_id(self, creator_id, is_public): # autogen room IDs and try to create it. We may clash, so just # try a few times till one goes through, giving up eventually. attempts = 0 while attempts < 5: try: random_string = stringutils.random_string(18) gen_room_id = RoomID( random_string, self.hs.hostname, ).to_string() if isinstance(gen_room_id, bytes): gen_room_id = gen_room_id.decode('utf-8') yield self.store.store_room( room_id=gen_room_id, room_creator_user_id=creator_id, is_public=is_public, ) defer.returnValue(gen_room_id) except StoreError: attempts += 1 raise StoreError(500, "Couldn't generate a room ID.")
def setUp(self): hs = setup_test_homeserver() # Room events need the full datastore, for persist_event() and # get_room_state() self.store = hs.get_datastore() self.event_factory = hs.get_event_factory() self.room = RoomID.from_string("!abcde:test") yield self.store.store_room(self.room.to_string(), room_creator_user_id="@creator:text", is_public=True)
def validate(self, event): EventID.from_string(event.event_id) RoomID.from_string(event.room_id) required = [ # "auth_events", "content", # "hashes", "origin", # "prev_events", "sender", "type", ] for k in required: if not hasattr(event, k): raise SynapseError(400, "Event does not have key %s" % (k, )) # Check that the following keys have string values strings = [ "origin", "sender", "type", ] if hasattr(event, "state_key"): strings.append("state_key") for s in strings: if not isinstance(getattr(event, s), string_types): raise SynapseError(400, "Not '%s' a string type" % (s, )) if event.type == EventTypes.Member: if "membership" not in event.content: raise SynapseError(400, "Content has not membership key") if event.content["membership"] not in Membership.LIST: raise SynapseError(400, "Invalid membership key")
def validate(self, event): EventID.from_string(event.event_id) RoomID.from_string(event.room_id) required = [ # "auth_events", "content", # "hashes", "origin", # "prev_events", "sender", "type", ] for k in required: if not hasattr(event, k): raise SynapseError(400, "Event does not have key %s" % (k,)) # Check that the following keys have string values strings = [ "origin", "sender", "type", ] if hasattr(event, "state_key"): strings.append("state_key") for s in strings: if not isinstance(getattr(event, s), basestring): raise SynapseError(400, "Not '%s' a string type" % (s,)) if event.type == EventTypes.Member: if "membership" not in event.content: raise SynapseError(400, "Content has not membership key") if event.content["membership"] not in Membership.LIST: raise SynapseError(400, "Invalid membership key")
def prepare(self, reactor, clock, hs): self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_creation_handler = hs.get_event_creation_handler() self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") self.room1 = RoomID.from_string("!abc123:test") self.get_success( create_room(hs, self.room1.to_string(), self.u_alice.to_string())) self.depth = 1
async def on_DELETE( self, request: SynapseRequest, room_id: str ) -> Tuple[int, JsonDict]: requester = await self._auth.get_user_by_req(request) await assert_user_is_admin(self._auth, requester.user) content = parse_json_object_from_request(request) block = content.get("block", False) if not isinstance(block, bool): raise SynapseError( HTTPStatus.BAD_REQUEST, "Param 'block' must be a boolean, if given", Codes.BAD_JSON, ) purge = content.get("purge", True) if not isinstance(purge, bool): raise SynapseError( HTTPStatus.BAD_REQUEST, "Param 'purge' must be a boolean, if given", Codes.BAD_JSON, ) force_purge = content.get("force_purge", False) if not isinstance(force_purge, bool): raise SynapseError( HTTPStatus.BAD_REQUEST, "Param 'force_purge' must be a boolean, if given", Codes.BAD_JSON, ) if not RoomID.is_valid(room_id): raise SynapseError( HTTPStatus.BAD_REQUEST, "%s is not a legal room ID" % (room_id,) ) delete_id = self._pagination_handler.start_shutdown_and_purge_room( room_id=room_id, new_room_user_id=content.get("new_room_user_id"), new_room_name=content.get("room_name"), message=content.get("message"), requester_user_id=requester.user.to_string(), block=block, purge=purge, force_purge=force_purge, ) return HTTPStatus.OK, {"delete_id": delete_id}
def setUp(self): hs = yield tests.utils.setup_test_homeserver(self.addCleanup) self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_creation_handler = hs.get_event_creation_handler() self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") self.room = RoomID.from_string("!abc123:test") yield self.store.store_room( self.room.to_string(), room_creator_user_id="@creator:text", is_public=True )
def setUp(self): hs = yield setup_test_homeserver() # We can't test RoomStore on its own without the DirectoryStore, for # management of the 'room_aliases' table self.store = hs.get_datastore() self.room = RoomID.from_string("!abcde:test") self.alias = RoomAlias.from_string("#a-room-name:test") self.u_creator = UserID.from_string("@creator:test") yield self.store.store_room( self.room.to_string(), room_creator_user_id=self.u_creator.to_string(), is_public=True)
def setUp(self): hs = yield setup_test_homeserver() # We can't test RoomStore on its own without the DirectoryStore, for # management of the 'room_aliases' table self.store = hs.get_datastore() self.room = RoomID.from_string("!abcde:test") self.alias = RoomAlias.from_string("#a-room-name:test") self.u_creator = UserID.from_string("@creator:test") yield self.store.store_room(self.room.to_string(), room_creator_user_id=self.u_creator.to_string(), is_public=True )
def setUp(self): hs = yield tests.utils.setup_test_homeserver(self.addCleanup) self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_creation_handler = hs.get_event_creation_handler() self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") self.room = RoomID.from_string("!abc123:test") yield self.store.store_room(self.room.to_string(), room_creator_user_id="@creator:text", is_public=True)
def setUp(self): hs = yield setup_test_homeserver(self.addCleanup, resource_for_federation=Mock(), http_client=None) self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_creation_handler = hs.get_event_creation_handler() self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") self.room1 = RoomID.from_string("!abc123:test") self.depth = 1
def prepare(self, reactor, clock, hs): # Room events need the full datastore, for persist_event() and # get_room_state() self.store = hs.get_datastore() self.storage = hs.get_storage() self.event_factory = hs.get_event_factory() self.room = RoomID.from_string("!abcde:test") self.get_success( self.store.store_room( self.room.to_string(), room_creator_user_id="@creator:text", is_public=True, room_version=RoomVersions.V1, ))
def prepare(self, reactor, clock, hs): # We can't test RoomStore on its own without the DirectoryStore, for # management of the 'room_aliases' table self.store = hs.get_datastore() self.room = RoomID.from_string("!abcde:test") self.alias = RoomAlias.from_string("#a-room-name:test") self.u_creator = UserID.from_string("@creator:test") self.get_success( self.store.store_room( self.room.to_string(), room_creator_user_id=self.u_creator.to_string(), is_public=True, room_version=RoomVersions.V1, ))
async def on_GET(self, request: SynapseRequest, room_id: str) -> Tuple[int, JsonDict]: await assert_requester_is_admin(self._auth, request) if not RoomID.is_valid(room_id): raise SynapseError(HTTPStatus.BAD_REQUEST, "%s is not a legal room ID" % (room_id, )) blocked_by = await self._store.room_is_blocked_by(room_id) # Test `not None` if `user_id` is an empty string # if someone add manually an entry in database if blocked_by is not None: response = {"block": True, "user_id": blocked_by} else: response = {"block": False} return HTTPStatus.OK, response
def setUp(self): hs = yield setup_test_homeserver(self.addCleanup, resource_for_federation=Mock(), http_client=None) # We can't test the RoomMemberStore on its own without the other event # storage logic self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_creation_handler = hs.get_event_creation_handler() self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") # User elsewhere on another host self.u_charlie = UserID.from_string("@charlie:elsewhere") self.room = RoomID.from_string("!abc123:test")
def setUp(self): hs = yield setup_test_homeserver( self.addCleanup, resource_for_federation=Mock(), http_client=None ) self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_creation_handler = hs.get_event_creation_handler() self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") self.room1 = RoomID.from_string("!abc123:test") yield create_room(hs, self.room1.to_string(), self.u_alice.to_string()) self.depth = 1
async def resolve_room_id(self, room_identifier: str) -> str: """Resolve to a room ID, if necessary.""" if RoomID.is_valid(room_identifier): resolved_room_id = room_identifier elif RoomAlias.is_valid(room_identifier): room_alias = RoomAlias.from_string(room_identifier) room_id, _ = await self.room_member_handler.lookup_room_alias( room_alias) resolved_room_id = room_id.to_string() else: raise SynapseError( 400, "%s was not legal room ID or room alias" % (room_identifier, )) if not resolved_room_id: raise SynapseError( 400, "Unknown room ID or room alias %s" % room_identifier) return resolved_room_id
def on_POST(self, request, room_identifier, txn_id=None): requester = yield self.auth.get_user_by_req( request, allow_guest=True, ) # the identifier could be a room alias or a room id. Try one then the # other if it fails to parse, without swallowing other valid # SynapseErrors. identifier = None is_room_alias = False try: identifier = RoomAlias.from_string(room_identifier) is_room_alias = True except SynapseError: identifier = RoomID.from_string(room_identifier) # TODO: Support for specifying the home server to join with? if is_room_alias: handler = self.handlers.room_member_handler ret_dict = yield handler.join_room_alias( requester.user, identifier, ) defer.returnValue((200, ret_dict)) else: # room id msg_handler = self.handlers.message_handler content = {"membership": Membership.JOIN} if requester.is_guest: content["kind"] = "guest" yield msg_handler.create_and_send_event( { "type": EventTypes.Member, "content": content, "room_id": identifier.to_string(), "sender": requester.user.to_string(), "state_key": requester.user.to_string(), }, token_id=requester.access_token_id, txn_id=txn_id, is_guest=requester.is_guest, ) defer.returnValue((200, {"room_id": identifier.to_string()}))
async def on_POST( self, request: SynapseRequest, room_identifier: str, txn_id: Optional[str] = None, ) -> Tuple[int, JsonDict]: requester = await self.auth.get_user_by_req(request) content = parse_json_object_from_request(request) event_content = None if "reason" in content: event_content = {"reason": content["reason"]} if RoomID.is_valid(room_identifier): room_id = room_identifier # twisted.web.server.Request.args is incorrectly defined as Optional[Any] args: Dict[bytes, List[bytes]] = request.args # type: ignore remote_room_hosts = parse_strings_from_args(args, "server_name", required=False) elif RoomAlias.is_valid(room_identifier): handler = self.room_member_handler room_alias = RoomAlias.from_string(room_identifier) room_id_obj, remote_room_hosts = await handler.lookup_room_alias( room_alias) room_id = room_id_obj.to_string() else: raise SynapseError( 400, "%s was not legal room ID or room alias" % (room_identifier, )) await self.room_member_handler.update_membership( requester=requester, target=requester.user, room_id=room_id, action=Membership.KNOCK, txn_id=txn_id, third_party_signed=None, remote_room_hosts=remote_room_hosts, content=event_content, ) return 200, {"room_id": room_id}
def on_PUT(self, request, room_id): requester = yield self.auth.get_user_by_req(request) room = RoomID.from_string(room_id) is_admin = yield self.auth.is_server_admin(requester.user) content = parse_json_object_from_request(request) new_avatar_url = content["group_avatar_url"] try: new_name = content["room_icon_url"] except Exception: defer.returnValue((400, "Unable to parse name")) yield self.profile_handler.set_room_avatar_url(room, requester, new_avatar_url, is_admin) defer.returnValue((200, {}))
def setUp(self): hs = yield setup_test_homeserver( resource_for_federation=Mock(), http_client=None, ) # We can't test the RoomMemberStore on its own without the other event # storage logic self.store = hs.get_datastore() self.event_builder_factory = hs.get_event_builder_factory() self.event_creation_handler = hs.get_event_creation_handler() self.u_alice = UserID.from_string("@alice:test") self.u_bob = UserID.from_string("@bob:test") # User elsewhere on another host self.u_charlie = UserID.from_string("@charlie:elsewhere") self.room = RoomID.from_string("!abc123:test")
def on_POST(self, request, room_identifier, txn_id=None): requester = yield self.auth.get_user_by_req( request, allow_guest=True, ) try: content = parse_json_object_from_request(request) except Exception: # Turns out we used to ignore the body entirely, and some clients # cheekily send invalid bodies. content = {} if RoomID.is_valid(room_identifier): room_id = room_identifier try: remote_room_hosts = [ x.decode('ascii') for x in request.args[b"server_name"] ] except Exception: remote_room_hosts = None elif RoomAlias.is_valid(room_identifier): handler = self.room_member_handler room_alias = RoomAlias.from_string(room_identifier) room_id, remote_room_hosts = yield handler.lookup_room_alias(room_alias) room_id = room_id.to_string() else: raise SynapseError(400, "%s was not legal room ID or room alias" % ( room_identifier, )) yield self.room_member_handler.update_membership( requester=requester, target=requester.user, room_id=room_id, action="join", txn_id=txn_id, remote_room_hosts=remote_room_hosts, content=content, third_party_signed=content.get("third_party_signed", None), ) defer.returnValue((200, {"room_id": room_id}))
def _join_user_to_room(self, requester, room_identifier): room_id = None room_member_handler = self.hs.get_room_member_handler() if RoomID.is_valid(room_identifier): room_id = room_identifier elif RoomAlias.is_valid(room_identifier): room_alias = RoomAlias.from_string(room_identifier) room_id, remote_room_hosts = ( yield room_member_handler.lookup_room_alias(room_alias) ) room_id = room_id.to_string() else: raise SynapseError(400, "%s was not legal room ID or room alias" % ( room_identifier, )) yield room_member_handler.update_membership( requester=requester, target=requester.user, room_id=room_id, remote_room_hosts=remote_room_hosts, action="join", )
def _check_definition(self, definition): """Check if the provided definition is valid. This inspects not only the types but also the values to make sure they make sense. Args: definition(dict): The filter definition Raises: SynapseError: If there was a problem with this definition. """ # NB: Filters are the complete json blobs. "Definitions" are an # individual top-level key e.g. public_user_data. Filters are made of # many definitions. if type(definition) != dict: raise SynapseError( 400, "Expected JSON object, not %s" % (definition,) ) # check rooms are valid room IDs room_id_keys = ["rooms", "not_rooms"] for key in room_id_keys: if key in definition: if type(definition[key]) != list: raise SynapseError(400, "Expected %s to be a list." % key) for room_id in definition[key]: RoomID.from_string(room_id) # check senders are valid user IDs user_id_keys = ["senders", "not_senders"] for key in user_id_keys: if key in definition: if type(definition[key]) != list: raise SynapseError(400, "Expected %s to be a list." % key) for user_id in definition[key]: UserID.from_string(user_id) # TODO: We don't limit event type values but we probably should... # check types are valid event types event_keys = ["types", "not_types"] for key in event_keys: if key in definition: if type(definition[key]) != list: raise SynapseError(400, "Expected %s to be a list." % key) for event_type in definition[key]: if not isinstance(event_type, basestring): raise SynapseError(400, "Event type should be a string") if "format" in definition: event_format = definition["format"] if event_format not in ["federation", "events"]: raise SynapseError(400, "Invalid format: %s" % (event_format,)) if "select" in definition: event_select_list = definition["select"] for select_key in event_select_list: if select_key not in ["event_id", "origin_server_ts", "thread_id", "content", "content.body"]: raise SynapseError(400, "Bad select: %s" % (select_key,)) if ("bundle_updates" in definition and type(definition["bundle_updates"]) != bool): raise SynapseError(400, "Bad bundle_updates: expected bool.")
def create_room(self, user_id, room_id, config): """ Creates a new room. Args: user_id (str): The ID of the user creating the new room. room_id (str): The proposed ID for the new room. Can be None, in which case one will be created for you. config (dict) : A dict of configuration options. Returns: The new room ID. Raises: SynapseError if the room ID was taken, couldn't be stored, or something went horribly wrong. """ self.ratelimit(user_id) if "room_alias_name" in config: for wchar in string.whitespace: if wchar in config["room_alias_name"]: raise SynapseError(400, "Invalid characters in room alias") room_alias = RoomAlias.create( config["room_alias_name"], self.hs.hostname, ) mapping = yield self.store.get_association_from_room_alias( room_alias ) if mapping: raise SynapseError(400, "Room alias already taken") else: room_alias = None invite_list = config.get("invite", []) for i in invite_list: try: UserID.from_string(i) except: raise SynapseError(400, "Invalid user_id: %s" % (i,)) is_public = config.get("visibility", None) == "public" if room_id: # Ensure room_id is the correct type room_id_obj = RoomID.from_string(room_id) if not self.hs.is_mine(room_id_obj): raise SynapseError(400, "Room id must be local") yield self.store.store_room( room_id=room_id, room_creator_user_id=user_id, is_public=is_public ) else: # autogen room IDs and try to create it. We may clash, so just # try a few times till one goes through, giving up eventually. attempts = 0 room_id = None while attempts < 5: try: random_string = stringutils.random_string(18) gen_room_id = RoomID.create( random_string, self.hs.hostname, ) yield self.store.store_room( room_id=gen_room_id.to_string(), room_creator_user_id=user_id, is_public=is_public ) room_id = gen_room_id.to_string() break except StoreError: attempts += 1 if not room_id: raise StoreError(500, "Couldn't generate a room ID.") if room_alias: directory_handler = self.hs.get_handlers().directory_handler yield directory_handler.create_association( user_id=user_id, room_id=room_id, room_alias=room_alias, servers=[self.hs.hostname], ) preset_config = config.get( "preset", RoomCreationPreset.PUBLIC_CHAT if is_public else RoomCreationPreset.PRIVATE_CHAT ) raw_initial_state = config.get("initial_state", []) initial_state = OrderedDict() for val in raw_initial_state: initial_state[(val["type"], val.get("state_key", ""))] = val["content"] creation_content = config.get("creation_content", {}) user = UserID.from_string(user_id) creation_events = self._create_events_for_new_room( user, room_id, preset_config=preset_config, invite_list=invite_list, initial_state=initial_state, creation_content=creation_content, room_alias=room_alias, ) msg_handler = self.hs.get_handlers().message_handler for event in creation_events: yield msg_handler.create_and_send_event(event, ratelimit=False) if "name" in config: name = config["name"] yield msg_handler.create_and_send_event({ "type": EventTypes.Name, "room_id": room_id, "sender": user_id, "state_key": "", "content": {"name": name}, }, ratelimit=False) if "topic" in config: topic = config["topic"] yield msg_handler.create_and_send_event({ "type": EventTypes.Topic, "room_id": room_id, "sender": user_id, "state_key": "", "content": {"topic": topic}, }, ratelimit=False) for invitee in invite_list: yield msg_handler.create_and_send_event({ "type": EventTypes.Member, "state_key": invitee, "room_id": room_id, "sender": user_id, "content": {"membership": Membership.INVITE}, }, ratelimit=False) result = {"room_id": room_id} if room_alias: result["room_alias"] = room_alias.to_string() yield directory_handler.send_room_alias_update_event( user_id, room_id ) defer.returnValue(result)
def create_room(self, requester, config): """ Creates a new room. Args: requester (Requester): The user who requested the room creation. config (dict) : A dict of configuration options. Returns: The new room ID. Raises: SynapseError if the room ID couldn't be stored, or something went horribly wrong. """ user_id = requester.user.to_string() self.ratelimit(requester) if "room_alias_name" in config: for wchar in string.whitespace: if wchar in config["room_alias_name"]: raise SynapseError(400, "Invalid characters in room alias") room_alias = RoomAlias.create( config["room_alias_name"], self.hs.hostname, ) mapping = yield self.store.get_association_from_room_alias( room_alias ) if mapping: raise SynapseError(400, "Room alias already taken") else: room_alias = None invite_list = config.get("invite", []) for i in invite_list: try: UserID.from_string(i) except: raise SynapseError(400, "Invalid user_id: %s" % (i,)) invite_3pid_list = config.get("invite_3pid", []) visibility = config.get("visibility", None) is_public = visibility == "public" # autogen room IDs and try to create it. We may clash, so just # try a few times till one goes through, giving up eventually. attempts = 0 room_id = None while attempts < 5: try: random_string = stringutils.random_string(18) gen_room_id = RoomID.create( random_string, self.hs.hostname, ) yield self.store.store_room( room_id=gen_room_id.to_string(), room_creator_user_id=user_id, is_public=is_public ) room_id = gen_room_id.to_string() break except StoreError: attempts += 1 if not room_id: raise StoreError(500, "Couldn't generate a room ID.") if room_alias: directory_handler = self.hs.get_handlers().directory_handler yield directory_handler.create_association( user_id=user_id, room_id=room_id, room_alias=room_alias, servers=[self.hs.hostname], ) preset_config = config.get( "preset", RoomCreationPreset.PRIVATE_CHAT if visibility == "private" else RoomCreationPreset.PUBLIC_CHAT ) raw_initial_state = config.get("initial_state", []) initial_state = OrderedDict() for val in raw_initial_state: initial_state[(val["type"], val.get("state_key", ""))] = val["content"] creation_content = config.get("creation_content", {}) msg_handler = self.hs.get_handlers().message_handler room_member_handler = self.hs.get_handlers().room_member_handler yield self._send_events_for_new_room( requester, room_id, msg_handler, room_member_handler, preset_config=preset_config, invite_list=invite_list, initial_state=initial_state, creation_content=creation_content, room_alias=room_alias, ) if "name" in config: name = config["name"] yield msg_handler.create_and_send_nonmember_event( requester, { "type": EventTypes.Name, "room_id": room_id, "sender": user_id, "state_key": "", "content": {"name": name}, }, ratelimit=False) if "topic" in config: topic = config["topic"] yield msg_handler.create_and_send_nonmember_event( requester, { "type": EventTypes.Topic, "room_id": room_id, "sender": user_id, "state_key": "", "content": {"topic": topic}, }, ratelimit=False) for invitee in invite_list: yield room_member_handler.update_membership( requester, UserID.from_string(invitee), room_id, "invite", ratelimit=False, ) for invite_3pid in invite_3pid_list: id_server = invite_3pid["id_server"] address = invite_3pid["address"] medium = invite_3pid["medium"] yield self.hs.get_handlers().room_member_handler.do_3pid_invite( room_id, requester.user, medium, address, id_server, requester, txn_id=None, ) result = {"room_id": room_id} if room_alias: result["room_alias"] = room_alias.to_string() yield directory_handler.send_room_alias_update_event( requester, user_id, room_id ) defer.returnValue(result)
def is_membership_change_allowed(self, event, auth_events): membership = event.content["membership"] # Check if this is the room creator joining: if len(event.prev_events) == 1 and Membership.JOIN == membership: # Get room creation event: key = (EventTypes.Create, "", ) create = auth_events.get(key) if create and event.prev_events[0][0] == create.event_id: if create.content["creator"] == event.state_key: return True target_user_id = event.state_key creating_domain = RoomID.from_string(event.room_id).domain target_domain = UserID.from_string(target_user_id).domain if creating_domain != target_domain: if not self.can_federate(event, auth_events): raise AuthError( 403, "This room has been marked as unfederatable." ) # get info about the caller key = (EventTypes.Member, event.user_id, ) caller = auth_events.get(key) caller_in_room = caller and caller.membership == Membership.JOIN caller_invited = caller and caller.membership == Membership.INVITE # get info about the target key = (EventTypes.Member, target_user_id, ) target = auth_events.get(key) target_in_room = target and target.membership == Membership.JOIN target_banned = target and target.membership == Membership.BAN key = (EventTypes.JoinRules, "", ) join_rule_event = auth_events.get(key) if join_rule_event: join_rule = join_rule_event.content.get( "join_rule", JoinRules.INVITE ) else: join_rule = JoinRules.INVITE user_level = self._get_user_power_level(event.user_id, auth_events) target_level = self._get_user_power_level( target_user_id, auth_events ) # FIXME (erikj): What should we do here as the default? ban_level = self._get_named_level(auth_events, "ban", 50) logger.debug( "is_membership_change_allowed: %s", { "caller_in_room": caller_in_room, "caller_invited": caller_invited, "target_banned": target_banned, "target_in_room": target_in_room, "membership": membership, "join_rule": join_rule, "target_user_id": target_user_id, "event.user_id": event.user_id, } ) if Membership.INVITE == membership and "third_party_invite" in event.content: if not self._verify_third_party_invite(event, auth_events): raise AuthError(403, "You are not invited to this room.") return True if Membership.JOIN != membership: if (caller_invited and Membership.LEAVE == membership and target_user_id == event.user_id): return True if not caller_in_room: # caller isn't joined raise AuthError( 403, "%s not in room %s." % (event.user_id, event.room_id,) ) if Membership.INVITE == membership: # TODO (erikj): We should probably handle this more intelligently # PRIVATE join rules. # Invites are valid iff caller is in the room and target isn't. if target_banned: raise AuthError( 403, "%s is banned from the room" % (target_user_id,) ) elif target_in_room: # the target is already in the room. raise AuthError(403, "%s is already in the room." % target_user_id) else: invite_level = self._get_named_level(auth_events, "invite", 0) if user_level < invite_level: raise AuthError( 403, "You cannot invite user %s." % target_user_id ) elif Membership.JOIN == membership: # Joins are valid iff caller == target and they were: # invited: They are accepting the invitation # joined: It's a NOOP if event.user_id != target_user_id: raise AuthError(403, "Cannot force another user to join.") elif target_banned: raise AuthError(403, "You are banned from this room") elif join_rule == JoinRules.PUBLIC: pass elif join_rule == JoinRules.INVITE: if not caller_in_room and not caller_invited: raise AuthError(403, "You are not invited to this room.") else: # TODO (erikj): may_join list # TODO (erikj): private rooms raise AuthError(403, "You are not allowed to join this room") elif Membership.LEAVE == membership: # TODO (erikj): Implement kicks. if target_banned and user_level < ban_level: raise AuthError( 403, "You cannot unban user &s." % (target_user_id,) ) elif target_user_id != event.user_id: kick_level = self._get_named_level(auth_events, "kick", 50) if user_level < kick_level or user_level <= target_level: raise AuthError( 403, "You cannot kick user %s." % target_user_id ) elif Membership.BAN == membership: if user_level < ban_level or user_level <= target_level: raise AuthError(403, "You don't have permission to ban") else: raise AuthError(500, "Unknown membership %s" % membership) return True
def matrix_room_id_validator(room_id_str): return RoomID.from_string(room_id_str)
def parse_roomid(self, s): """Parse the string given by 's' as a Room ID and return a RoomID object.""" return RoomID.from_string(s, hs=self)
def create_room(self, user_id, room_id, config): """ Creates a new room. Args: user_id (str): The ID of the user creating the new room. room_id (str): The proposed ID for the new room. Can be None, in which case one will be created for you. config (dict) : A dict of configuration options. Returns: The new room ID. Raises: SynapseError if the room ID was taken, couldn't be stored, or something went horribly wrong. """ self.ratelimit(user_id) if "room_alias_name" in config: room_alias = RoomAlias.create_local( config["room_alias_name"], self.hs ) mapping = yield self.store.get_association_from_room_alias( room_alias ) if mapping: raise SynapseError(400, "Room alias already taken") else: room_alias = None invite_list = config.get("invite", []) for i in invite_list: try: self.hs.parse_userid(i) except: raise SynapseError(400, "Invalid user_id: %s" % (i,)) is_public = config.get("visibility", None) == "public" if room_id: # Ensure room_id is the correct type room_id_obj = RoomID.from_string(room_id, self.hs) if not room_id_obj.is_mine: raise SynapseError(400, "Room id must be local") yield self.store.store_room( room_id=room_id, room_creator_user_id=user_id, is_public=is_public ) else: # autogen room IDs and try to create it. We may clash, so just # try a few times till one goes through, giving up eventually. attempts = 0 room_id = None while attempts < 5: try: random_string = stringutils.random_string(18) gen_room_id = RoomID.create_local(random_string, self.hs) yield self.store.store_room( room_id=gen_room_id.to_string(), room_creator_user_id=user_id, is_public=is_public ) room_id = gen_room_id.to_string() break except StoreError: attempts += 1 if not room_id: raise StoreError(500, "Couldn't generate a room ID.") if room_alias: directory_handler = self.hs.get_handlers().directory_handler yield directory_handler.create_association( user_id=user_id, room_id=room_id, room_alias=room_alias, servers=[self.hs.hostname], ) user = self.hs.parse_userid(user_id) creation_events = self._create_events_for_new_room( user, room_id, is_public=is_public ) room_member_handler = self.hs.get_handlers().room_member_handler @defer.inlineCallbacks def handle_event(event): snapshot = yield self.store.snapshot_room(event) logger.debug("Event: %s", event) if event.type == RoomMemberEvent.TYPE: yield room_member_handler.change_membership( event, do_auth=True ) else: yield self._on_new_room_event( event, snapshot, extra_users=[user], suppress_auth=True ) for event in creation_events: yield handle_event(event) if "name" in config: name = config["name"] name_event = self.event_factory.create_event( etype=RoomNameEvent.TYPE, room_id=room_id, user_id=user_id, content={"name": name}, ) yield handle_event(name_event) if "topic" in config: topic = config["topic"] topic_event = self.event_factory.create_event( etype=RoomTopicEvent.TYPE, room_id=room_id, user_id=user_id, content={"topic": topic}, ) yield handle_event(topic_event) content = {"membership": Membership.INVITE} for invitee in invite_list: invite_event = self.event_factory.create_event( etype=RoomMemberEvent.TYPE, state_key=invitee, room_id=room_id, user_id=user_id, content=content ) yield handle_event(invite_event) result = {"room_id": room_id} if room_alias: result["room_alias"] = room_alias.to_string() yield directory_handler.send_room_alias_update_event( user_id, room_id ) defer.returnValue(result)
def check(self, event, auth_events): """ Checks if this event is correctly authed. Args: event: the event being checked. auth_events (dict: event-key -> event): the existing room state. Returns: True if the auth checks pass. """ self.check_size_limits(event) try: if not hasattr(event, "room_id"): raise AuthError(500, "Event has no room_id: %s" % event) if auth_events is None: # Oh, we don't know what the state of the room was, so we # are trusting that this is allowed (at least for now) logger.warn("Trusting event: %s", event.event_id) return True if event.type == EventTypes.Create: # FIXME return True creation_event = auth_events.get((EventTypes.Create, ""), None) if not creation_event: raise SynapseError( 403, "Room %r does not exist" % (event.room_id,) ) creating_domain = RoomID.from_string(event.room_id).domain originating_domain = UserID.from_string(event.sender).domain if creating_domain != originating_domain: if not self.can_federate(event, auth_events): raise AuthError( 403, "This room has been marked as unfederatable." ) # FIXME: Temp hack if event.type == EventTypes.Aliases: return True logger.debug( "Auth events: %s", [a.event_id for a in auth_events.values()] ) if event.type == EventTypes.Member: allowed = self.is_membership_change_allowed( event, auth_events ) if allowed: logger.debug("Allowing! %s", event) else: logger.debug("Denying! %s", event) return allowed self.check_event_sender_in_room(event, auth_events) self._can_send_event(event, auth_events) if event.type == EventTypes.PowerLevels: self._check_power_levels(event, auth_events) if event.type == EventTypes.Redaction: self.check_redaction(event, auth_events) logger.debug("Allowing! %s", event) except AuthError as e: logger.info( "Event auth check failed on event %s with msg: %s", event, e.msg ) logger.info("Denying! %s", event) raise