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}")
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()
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()
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()
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}")