def _get_rooms_for_user_where_membership_is_txn(self, txn, user_id, membership_list): do_invite = Membership.INVITE in membership_list membership_list = [ m for m in membership_list if m != Membership.INVITE ] results = [] if membership_list: if self._current_state_events_membership_up_to_date: clause, args = make_in_list_sql_clause(self.database_engine, "c.membership", membership_list) sql = """ SELECT room_id, e.sender, c.membership, event_id, e.stream_ordering FROM current_state_events AS c INNER JOIN events AS e USING (room_id, event_id) WHERE c.type = 'm.room.member' AND state_key = ? AND %s """ % (clause, ) else: clause, args = make_in_list_sql_clause(self.database_engine, "m.membership", membership_list) sql = """ SELECT room_id, e.sender, m.membership, event_id, e.stream_ordering FROM current_state_events AS c INNER JOIN room_memberships AS m USING (room_id, event_id) INNER JOIN events AS e USING (room_id, event_id) WHERE c.type = 'm.room.member' AND state_key = ? AND %s """ % (clause, ) txn.execute(sql, (user_id, *args)) results = [RoomsForUser(**r) for r in self.cursor_to_dict(txn)] if do_invite: sql = ("SELECT i.room_id, inviter, i.event_id, e.stream_ordering" " FROM local_invites as i" " INNER JOIN events as e USING (event_id)" " WHERE invitee = ? AND locally_rejected is NULL" " AND replaced_by is NULL") txn.execute(sql, (user_id, )) results.extend( RoomsForUser( room_id=r["room_id"], sender=r["inviter"], event_id=r["event_id"], stream_ordering=r["stream_ordering"], membership=Membership.INVITE, ) for r in self.cursor_to_dict(txn)) return results
def test_room_members(self): create = yield self.persist(type="m.room.create", key="", creator=USER_ID) yield self.replicate() yield self.check("get_rooms_for_user", (USER_ID, ), []) yield self.check("get_users_in_room", (ROOM_ID, ), []) # Join the room. join = yield self.persist(type="m.room.member", key=USER_ID, membership="join") yield self.replicate() yield self.check("get_rooms_for_user", (USER_ID, ), [ RoomsForUser( room_id=ROOM_ID, sender=USER_ID, membership="join", event_id=join.event_id, stream_ordering=join.internal_metadata.stream_ordering, ) ]) yield self.check("get_users_in_room", (ROOM_ID, ), [USER_ID]) # Leave the room. yield self.persist(type="m.room.member", key=USER_ID, membership="leave") yield self.replicate() yield self.check("get_rooms_for_user", (USER_ID, ), []) yield self.check("get_users_in_room", (ROOM_ID, ), []) # Add some other user to the room. join = yield self.persist(type="m.room.member", key=USER_ID_2, membership="join") yield self.replicate() yield self.check("get_rooms_for_user", (USER_ID_2, ), [ RoomsForUser( room_id=ROOM_ID, sender=USER_ID, membership="join", event_id=join.event_id, stream_ordering=join.internal_metadata.stream_ordering, ) ]) yield self.check("get_users_in_room", (ROOM_ID, ), [USER_ID_2]) # Join the room clobbering the state. # This should remove any evidence of the other user being in the room. yield self.persist(type="m.room.member", key=USER_ID, membership="join", reset_state=[create]) yield self.replicate() yield self.check("get_users_in_room", (ROOM_ID, ), [USER_ID]) yield self.check("get_rooms_for_user", (USER_ID_2, ), [])
def _get_rooms_for_local_user_where_membership_is_txn( self, txn, user_id: str, membership_list: List[str]) -> List[RoomsForUser]: # Paranoia check. if not self.hs.is_mine_id(user_id): raise Exception( "Cannot call 'get_rooms_for_local_user_where_membership_is' on non-local user %r" % (user_id, ), ) clause, args = make_in_list_sql_clause(self.database_engine, "c.membership", membership_list) sql = """ SELECT room_id, e.sender, c.membership, event_id, e.stream_ordering, r.room_version FROM local_current_membership AS c INNER JOIN events AS e USING (room_id, event_id) INNER JOIN rooms AS r USING (room_id) WHERE user_id = ? AND %s """ % (clause, ) txn.execute(sql, (user_id, *args)) results = [RoomsForUser(*r) for r in txn] return results
def test_invites(self): yield self.check("get_invited_rooms_for_user", [USER_ID_2], []) event = yield self.persist(type="m.room.member", key=USER_ID_2, membership="invite") yield self.replicate() yield self.check("get_invited_rooms_for_user", [USER_ID_2], [ RoomsForUser(ROOM_ID, USER_ID, "invite", event.event_id, event.internal_metadata.stream_ordering) ])
def _get_app_service_rooms_txn(self, txn, service): # get all rooms matching the room ID regex. room_entries = self._simple_select_list_txn(txn=txn, table="rooms", keyvalues=None, retcols=["room_id"]) matching_room_list = set([ r["room_id"] for r in room_entries if service.is_interested_in_room(r["room_id"]) ]) # resolve room IDs for matching room alias regex. room_alias_mappings = self._simple_select_list_txn( txn=txn, table="room_aliases", keyvalues=None, retcols=["room_id", "room_alias"]) matching_room_list |= set([ r["room_id"] for r in room_alias_mappings if service.is_interested_in_alias(r["room_alias"]) ]) # get all rooms for every user for this AS. This is scoped to users on # this HS only. user_list = self._simple_select_list_txn(txn=txn, table="users", keyvalues=None, retcols=["name"]) user_list = [ u["name"] for u in user_list if service.is_interested_in_user(u["name"]) ] rooms_for_user_matching_user_id = set() # RoomsForUser list for user_id in user_list: # FIXME: This assumes this store is linked with RoomMemberStore :( rooms_for_user = self._get_rooms_for_user_where_membership_is_txn( txn=txn, user_id=user_id, membership_list=[Membership.JOIN]) rooms_for_user_matching_user_id |= set(rooms_for_user) # make RoomsForUser tuples for room ids and aliases which are not in the # main rooms_for_user_list - e.g. they are rooms which do not have AS # registered users in it. known_room_ids = [r.room_id for r in rooms_for_user_matching_user_id] missing_rooms_for_user = [ RoomsForUser(r, service.sender, "join") for r in matching_room_list if r not in known_room_ids ] rooms_for_user_matching_user_id |= set(missing_rooms_for_user) return rooms_for_user_matching_user_id
def test_invites(self): self.persist(type="m.room.create", key="", creator=USER_ID) self.check("get_invited_rooms_for_local_user", [USER_ID_2], []) event = self.persist(type="m.room.member", key=USER_ID_2, membership="invite") self.replicate() self.check( "get_invited_rooms_for_local_user", [USER_ID_2], [ RoomsForUser( ROOM_ID, USER_ID, "invite", event.event_id, event.internal_metadata.stream_ordering, RoomVersions.V1.identifier, ) ], )