Esempio n. 1
0
    def _send_chart_response(
        self,
        result: Dict[Any, Any],
        form_data: Optional[Dict[str, Any]] = None,
        datasource: Optional[BaseDatasource] = None,
    ) -> Response:
        result_type = result["query_context"].result_type
        result_format = result["query_context"].result_format

        # Post-process the data so it matches the data presented in the chart.
        # This is needed for sending reports based on text charts that do the
        # post-processing of data, eg, the pivot table.
        if result_type == ChartDataResultType.POST_PROCESSED:
            result = apply_post_process(result, form_data, datasource)

        if result_format == ChartDataResultFormat.CSV:
            # Verify user has permission to export CSV file
            if not security_manager.can_access("can_csv", "Superset"):
                return self.response_403()

            if not result["queries"]:
                return self.response_400(_("Empty query result"))

            if len(result["queries"]) == 1:
                # return single query results csv format
                data = result["queries"][0]["data"]
                return CsvResponse(data,
                                   headers=generate_download_headers("csv"))

            # return multi-query csv results bundled as a zip file
            encoding = current_app.config["CSV_EXPORT"].get(
                "encoding", "utf-8")
            files = {
                f"query_{idx + 1}.csv": result["data"].encode(encoding)
                for idx, result in enumerate(result["queries"])
            }
            return Response(
                create_zip(files),
                headers=generate_download_headers("zip"),
                mimetype="application/zip",
            )

        if result_format == ChartDataResultFormat.JSON:
            response_data = simplejson.dumps(
                {"result": result["queries"]},
                default=json_int_dttm_ser,
                ignore_nan=True,
            )
            resp = make_response(response_data, 200)
            resp.headers["Content-Type"] = "application/json; charset=utf-8"
            return resp

        return self.response_400(
            message=f"Unsupported result_format: {result_format}")
Esempio n. 2
0
def check_access(dataset_id: int, chart_id: Optional[int],
                 actor: User) -> None:
    check_dataset_access(dataset_id)
    if not chart_id:
        return
    chart = ChartDAO.find_by_id(chart_id)
    if chart:
        can_access_chart = (is_user_admin() or is_owner(chart, actor)
                            or security_manager.can_access(
                                "can_read", "Chart"))
        if can_access_chart:
            return
        raise ChartAccessDeniedError()
    raise ChartNotFoundError()
Esempio n. 3
0
def check_access(
    datasource_id: int,
    chart_id: Optional[int],
    datasource_type: DatasourceType,
) -> Optional[bool]:
    check_datasource_access(datasource_id, datasource_type)
    if not chart_id:
        return True
    chart = ChartDAO.find_by_id(chart_id)
    if chart:
        can_access_chart = security_manager.is_owner(
            chart
        ) or security_manager.can_access("can_read", "Chart")
        if can_access_chart:
            return True
        raise ChartAccessDeniedError()
    raise ChartNotFoundError()
Esempio n. 4
0
def check_access(
    datasource_id: int,
    chart_id: Optional[int],
    datasource_type: DatasourceType,
) -> Optional[bool]:
    check_datasource_access(datasource_id, datasource_type)
    if not chart_id:
        return True
    # Access checks below, no need to validate them twice as they can be expensive.
    chart = ChartDAO.find_by_id(chart_id, skip_base_filter=True)
    if chart:
        can_access_chart = security_manager.is_owner(
            chart
        ) or security_manager.can_access("can_read", "Chart")
        if can_access_chart:
            return True
        raise ChartAccessDeniedError()
    raise ChartNotFoundError()
Esempio n. 5
0
    def _send_chart_response(
        self,
        result: Dict[Any, Any],
        form_data: Optional[Dict[str, Any]] = None,
        datasource: Optional[BaseDatasource] = None,
    ) -> Response:
        result_type = result["query_context"].result_type
        result_format = result["query_context"].result_format

        # Post-process the data so it matches the data presented in the chart.
        # This is needed for sending reports based on text charts that do the
        # post-processing of data, eg, the pivot table.
        if result_type == ChartDataResultType.POST_PROCESSED:
            result = apply_post_process(result, form_data, datasource)

        if result_format == ChartDataResultFormat.CSV:
            # Verify user has permission to export CSV file
            if not security_manager.can_access("can_csv", "Superset"):
                return self.response_403()

            # return the first result
            data = result["queries"][0]["data"]
            return CsvResponse(data, headers=generate_download_headers("csv"))

        if result_format == ChartDataResultFormat.JSON:
            response_data = simplejson.dumps(
                {"result": result["queries"]},
                default=json_int_dttm_ser,
                ignore_nan=True,
            )
            resp = make_response(response_data, 200)
            resp.headers["Content-Type"] = "application/json; charset=utf-8"
            return resp

        return self.response_400(
            message=f"Unsupported result_format: {result_format}")