def test_can_access_datasource(self, mock_raise_for_access): datasource = self.get_datasource_mock() mock_raise_for_access.return_value = None self.assertTrue(security_manager.can_access_datasource(datasource=datasource)) mock_raise_for_access.side_effect = SupersetSecurityException( SupersetError( "dummy", SupersetErrorType.DATASOURCE_SECURITY_ACCESS_ERROR, ErrorLevel.ERROR, ) ) self.assertFalse(security_manager.can_access_datasource(datasource=datasource))
def check_dataset_access(dataset_id: int) -> Optional[bool]: if dataset_id: dataset = DatasetDAO.find_by_id(dataset_id) if dataset: can_access_datasource = security_manager.can_access_datasource(dataset) if can_access_datasource: return True raise DatasetAccessDeniedError() raise DatasetNotFoundError()
def check_dataset_access(dataset_id: int) -> Optional[bool]: if dataset_id: # Access checks below, no need to validate them twice as they can be expensive. dataset = DatasetDAO.find_by_id(dataset_id, skip_base_filter=True) if dataset: can_access_datasource = security_manager.can_access_datasource(dataset) if can_access_datasource: return True raise DatasetAccessDeniedError() raise DatasetNotFoundError()
def check_dashboard_perms(_self: Any, dashboard_id_or_slug: str) -> None: """ Check if user can access a cached response from explore_json. This function takes `self` since it must have the same signature as the the decorated method. """ dash = get_dashboard(dashboard_id_or_slug) datasources = list(dash.datasources) if app.config["ENABLE_ACCESS_REQUEST"]: for datasource in datasources: if datasource and not security_manager.can_access_datasource(datasource): flash( __(security_manager.get_datasource_access_error_msg(datasource)), "danger", ) redirect("superset/request_access/?" f"dashboard_id={dash.id}&")
def run(self) -> Optional[Dict[str, Any]]: initial_form_data = {} if self._permalink_key is not None: command = GetExplorePermalinkCommand(self._permalink_key) permalink_value = command.run() if not permalink_value: raise ExplorePermalinkGetFailedError() state = permalink_value["state"] initial_form_data = state["formData"] url_params = state.get("urlParams") if url_params: initial_form_data["url_params"] = dict(url_params) elif self._form_data_key: parameters = FormDataCommandParameters(key=self._form_data_key) value = GetFormDataCommand(parameters).run() initial_form_data = json.loads(value) if value else {} message = None if not initial_form_data: if self._slice_id: initial_form_data["slice_id"] = self._slice_id if self._form_data_key: message = _( "Form data not found in cache, reverting to chart metadata." ) elif self._dataset_id: initial_form_data[ "datasource" ] = f"{self._dataset_id}__{self._dataset_type}" if self._form_data_key: message = _( "Form data not found in cache, reverting to dataset metadata." ) form_data, slc = get_form_data( use_slice_data=True, initial_form_data=initial_form_data ) try: self._dataset_id, self._dataset_type = get_datasource_info( self._dataset_id, self._dataset_type, form_data ) except SupersetException: self._dataset_id = None # fallback unkonw datasource to table type self._dataset_type = SqlaTable.type dataset: Optional[BaseDatasource] = None if self._dataset_id is not None: try: dataset = DatasourceDAO.get_datasource( db.session, cast(str, self._dataset_type), self._dataset_id ) except DatasetNotFoundError: pass dataset_name = dataset.name if dataset else _("[Missing Dataset]") if dataset: if app.config["ENABLE_ACCESS_REQUEST"] and ( not security_manager.can_access_datasource(dataset) ): message = __(security_manager.get_datasource_access_error_msg(dataset)) raise DatasetAccessDeniedError( message=message, dataset_type=self._dataset_type, dataset_id=self._dataset_id, ) viz_type = form_data.get("viz_type") if not viz_type and dataset and dataset.default_endpoint: raise WrongEndpointError(redirect=dataset.default_endpoint) form_data["datasource"] = ( str(self._dataset_id) + "__" + cast(str, self._dataset_type) ) # On explore, merge legacy and extra filters into the form data utils.convert_legacy_filters_into_adhoc(form_data) utils.merge_extra_filters(form_data) dummy_dataset_data: Dict[str, Any] = { "type": self._dataset_type, "name": dataset_name, "columns": [], "metrics": [], "database": {"id": 0, "backend": ""}, } try: dataset_data = dataset.data if dataset else dummy_dataset_data except (SupersetException, SQLAlchemyError): dataset_data = dummy_dataset_data return { "dataset": sanitize_datasource_data(dataset_data), "form_data": form_data, "slice": slc.data if slc else None, "message": message, }