Exemplo n.º 1
0
    def _ensure_admin_power_levels(self, room_id: Optional[str], room_alias: str) -> None:
        if not room_id:
            return

        log.info(f"Ensuring power levels for {room_alias}")
        api = self._own_api
        own_user = f"@{self._username}:{self._own_server_name}"
        supposed_power_levels = self._create_server_user_power_levels()

        try:
            current_power_levels = api.get_room_state_type(room_id, "m.room.power_levels", "")
        except MatrixError:
            log.debug("Could not fetch power levels", room_aliases=room_alias)
            return

        if own_user not in current_power_levels["users"]:
            log.warning(
                f"{own_user} has not been granted administrative power levels yet. Doing nothing."
            )
            return

        # the supposed power level dict could be just a subset of the current
        # because providers who left cannot be removed from other admins
        if set(supposed_power_levels["users"].keys()).issubset(
            set(current_power_levels["users"].keys())
        ):
            log.debug(f"Power levels are up to date. Doing nothing.")
            return

        merge_dict(current_power_levels, supposed_power_levels)
        try:
            api.set_power_levels(room_id, supposed_power_levels)
        except MatrixError:
            log.debug("Could not set power levels", room_aliases=room_alias)
Exemplo n.º 2
0
    def create_sync_filter(
        self,
        rooms: Optional[Iterable[Room]] = None,
        not_rooms: Optional[Iterable[Room]] = None,
        limit: Optional[int] = None,
    ) -> Optional[int]:
        """ Create a matrix sync filter

        A whitelist and blacklist of rooms can be supplied optionally. If
        no whitelist ist given, all rooms are whitelisted. The blacklist is
        applied on top of the whitelist.

        Ref. https://matrix.org/docs/spec/client_server/r0.6.0#api-endpoints

        Args:
            rooms: whitelist of rooms, if not given all rooms are whitelisted
            not_rooms: blacklist of rooms, applied after the whitelist
            limit: maximum number of messages to return

        """
        if not_rooms is None and rooms is None and limit is None:
            return None

        broadcast_room_filter: Dict[str, Dict] = {
            # Get all presence updates
            "presence": {
                "types": ["m.presence"]
            },
            # filter account data
            "account_data": {
                "not_types": ["*"]
            },
            # Ignore "message receipts" from all rooms
            "room": {
                "ephemeral": {
                    "not_types": ["m.receipt"]
                }
            },
        }
        if not_rooms:
            negative_rooms = [room.room_id for room in not_rooms]
            broadcast_room_filter["room"].update({
                # Filter out all unwanted rooms
                "not_rooms": negative_rooms
            })
        if rooms:
            positive_rooms = [room.room_id for room in rooms]
            broadcast_room_filter["room"].update({
                # Set all wanted rooms
                "rooms": positive_rooms
            })

        limit_filter: Dict[str, Any] = {}
        if limit is not None:
            limit_filter = {"room": {"timeline": {"limit": limit}}}

        final_filter = broadcast_room_filter
        merge_dict(final_filter, limit_filter)

        try:
            # 0 is a valid filter ID
            filter_response = self.api.create_filter(self.user_id,
                                                     final_filter)
            filter_id = filter_response.get("filter_id")
            log.debug("Sync filter created",
                      filter_id=filter_id,
                      filter=final_filter)

        except MatrixRequestError as ex:
            raise TransportError(
                f"Failed to create filter: {final_filter} for user {self.user_id}"
            ) from ex

        return filter_id