예제 #1
0
    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
예제 #2
0
    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, ), [])
예제 #3
0
    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
예제 #4
0
 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)
     ])
예제 #5
0
    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
예제 #6
0
    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,
                )
            ],
        )