Example #1
0
 def run(self) -> None:
     self.validate()
     try:
         ChartDAO.bulk_delete(self._models)
     except DeleteFailedError as ex:
         logger.exception(ex.exception)
         raise ChartBulkDeleteFailedError() from ex
Example #2
0
    def datasources(self) -> Response:
        """Get available datasources
        ---
        get:
          description: Get available datasources.
          responses:
            200:
              description: Query result
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/ChartGetDatasourceResponseSchema"
            400:
              $ref: '#/components/responses/400'
            401:
              $ref: '#/components/responses/401'
            404:
              $ref: '#/components/responses/404'
            422:
              $ref: '#/components/responses/422'
            500:
              $ref: '#/components/responses/500'
        """
        datasources = ChartDAO.fetch_all_datasources()
        if not datasources:
            return self.response(200, count=0, result=[])

        result = [
            {
                "label": str(ds),
                "value": {"datasource_id": ds.id, "datasource_type": ds.type},
            }
            for ds in datasources
        ]
        return self.response(200, count=len(result), result=result)
Example #3
0
    def validate_chart_dashboard(
        self, exceptions: List[ValidationError], update: bool = False
    ) -> None:
        """Validate chart or dashboard relation"""
        chart_id = self._properties.get("chart")
        dashboard_id = self._properties.get("dashboard")
        creation_method = self._properties.get("creation_method")

        if creation_method == ReportCreationMethod.CHARTS and not chart_id:
            # User has not saved chart yet in Explore view
            exceptions.append(ChartNotSavedValidationError())
            return

        if creation_method == ReportCreationMethod.DASHBOARDS and not dashboard_id:
            exceptions.append(DashboardNotSavedValidationError())
            return

        if chart_id and dashboard_id:
            exceptions.append(ReportScheduleOnlyChartOrDashboardError())

        if chart_id:
            chart = ChartDAO.find_by_id(chart_id)
            if not chart:
                exceptions.append(ChartNotFoundValidationError())
            self._properties["chart"] = chart
        elif dashboard_id:
            dashboard = DashboardDAO.find_by_id(dashboard_id)
            if not dashboard:
                exceptions.append(DashboardNotFoundValidationError())
            self._properties["dashboard"] = dashboard
        elif not update:
            exceptions.append(ReportScheduleEitherChartOrDashboardError())
Example #4
0
 def run(self) -> Model:
     self.validate()
     try:
         chart = ChartDAO.update(self._model, self._properties)
     except DAOUpdateFailedError as e:
         logger.exception(e.exception)
         raise ChartUpdateFailedError()
     return chart
Example #5
0
 def run(self) -> Model:
     self.validate()
     try:
         chart = ChartDAO.create(self._properties)
     except DAOCreateFailedError as ex:
         logger.exception(ex.exception)
         raise ChartCreateFailedError()
     return chart
Example #6
0
 def run(self):
     self.validate()
     try:
         chart = ChartDAO.delete(self._model)
     except DAODeleteFailedError as e:
         logger.exception(e.exception)
         raise ChartDeleteFailedError()
     return chart
Example #7
0
def test_datasource_find_by_id_skip_base_filter_not_found(
    session_with_data: Session, ) -> None:
    from superset.charts.dao import ChartDAO

    result = ChartDAO.find_by_id(125326326,
                                 session=session_with_data,
                                 skip_base_filter=True)
    assert result is None
Example #8
0
 def run(self) -> Model:
     self.validate()
     try:
         Dashboard.clear_cache_for_slice(slice_id=self._model_id)
         chart = ChartDAO.delete(self._model)
     except DAODeleteFailedError as ex:
         logger.exception(ex.exception)
         raise ChartDeleteFailedError()
     return chart
Example #9
0
 def run(self) -> Model:
     self.validate()
     try:
         self._properties["last_saved_at"] = datetime.now()
         self._properties["last_saved_by"] = self._actor
         chart = ChartDAO.create(self._properties)
     except DAOCreateFailedError as ex:
         logger.exception(ex.exception)
         raise ChartCreateFailedError()
     return chart
Example #10
0
 def validate(self) -> None:
     # Validate/populate model exists
     self._model = ChartDAO.find_by_id(self._model_id)
     if not self._model:
         raise ChartNotFoundError()
     # Check ownership
     try:
         check_ownership(self._model)
     except SupersetSecurityException:
         raise ChartForbiddenError()
Example #11
0
 def run(self) -> Model:
     self.validate()
     try:
         if self._properties.get("query_context_generation") is None:
             self._properties["last_saved_at"] = datetime.now()
             self._properties["last_saved_by"] = self._actor
         chart = ChartDAO.update(self._model, self._properties)
     except DAOUpdateFailedError as ex:
         logger.exception(ex.exception)
         raise ChartUpdateFailedError() from ex
     return chart
Example #12
0
 def validate(self) -> None:
     # Validate/populate model exists
     self._models = ChartDAO.find_by_ids(self._model_ids)
     if not self._models or len(self._models) != len(self._model_ids):
         raise ChartNotFoundError()
     # Check ownership
     for model in self._models:
         try:
             check_ownership(model)
         except SupersetSecurityException:
             raise ChartForbiddenError()
Example #13
0
def test_slice_find_by_id_skip_base_filter(session_with_data: Session) -> None:
    from superset.charts.dao import ChartDAO
    from superset.models.slice import Slice

    result = ChartDAO.find_by_id(1,
                                 session=session_with_data,
                                 skip_base_filter=True)

    assert result
    assert 1 == result.id
    assert "slice_name" == result.slice_name
    assert isinstance(result, Slice)
Example #14
0
 def favorite_status(self, **kwargs: Any) -> Response:
     """Favorite stars for Charts
     ---
     get:
       description: >-
         Check favorited dashboards for current user
       parameters:
       - in: query
         name: q
         content:
           application/json:
             schema:
               $ref: '#/components/schemas/get_fav_star_ids_schema'
       responses:
         200:
           description:
           content:
             application/json:
               schema:
                 $ref: "#/components/schemas/GetFavStarIdsSchema"
         400:
           $ref: '#/components/responses/400'
         401:
           $ref: '#/components/responses/401'
         404:
           $ref: '#/components/responses/404'
         500:
           $ref: '#/components/responses/500'
     """
     requested_ids = kwargs["rison"]
     charts = ChartDAO.find_by_ids(requested_ids)
     if not charts:
         return self.response_404()
     favorited_chart_ids = ChartDAO.favorited_ids(charts, g.user.id)
     res = [{
         "id": request_id,
         "value": request_id in favorited_chart_ids
     } for request_id in requested_ids]
     return self.response(200, result=res)
Example #15
0
    def datasources(self) -> Response:
        """Get available datasources
        ---
        get:
          description: Get available datasources.
          responses:
            200:
              description: charts unique datasource data
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      count:
                        type: integer
                      result:
                        type: object
                        properties:
                          label:
                            type: string
                          value:
                            type: object
                            properties:
                              database_id:
                                type: integer
                              database_type:
                                type: string
            400:
              $ref: '#/components/responses/400'
            401:
              $ref: '#/components/responses/401'
            404:
              $ref: '#/components/responses/404'
            422:
              $ref: '#/components/responses/422'
            500:
              $ref: '#/components/responses/500'
        """
        datasources = ChartDAO.fetch_all_datasources()
        if not datasources:
            return self.response(200, count=0, result=[])

        result = [{
            "label": str(ds),
            "value": {
                "datasource_id": ds.id,
                "datasource_type": ds.type
            },
        } for ds in datasources]
        return self.response(200, count=len(result), result=result)
Example #16
0
    def validate(self) -> None:
        exceptions: List[ValidationError] = []
        dashboard_ids = self._properties.get("dashboards")
        owner_ids: Optional[List[int]] = self._properties.get("owners")

        # Validate if datasource_id is provided datasource_type is required
        datasource_id = self._properties.get("datasource_id")
        if datasource_id is not None:
            datasource_type = self._properties.get("datasource_type", "")
            if not datasource_type:
                exceptions.append(
                    DatasourceTypeUpdateRequiredValidationError())

        # Validate/populate model exists
        self._model = ChartDAO.find_by_id(self._model_id)
        if not self._model:
            raise ChartNotFoundError()

        # Check and update ownership; when only updating query context we ignore
        # ownership so the update can be performed by report workers
        if not is_query_context_update(self._properties):
            try:
                check_ownership(self._model)
                owners = self.populate_owners(self._actor, owner_ids)
                self._properties["owners"] = owners
            except SupersetSecurityException as ex:
                raise ChartForbiddenError() from ex
            except ValidationError as ex:
                exceptions.append(ex)

        # Validate/Populate datasource
        if datasource_id is not None:
            try:
                datasource = get_datasource_by_id(datasource_id,
                                                  datasource_type)
                self._properties["datasource_name"] = datasource.name
            except ValidationError as ex:
                exceptions.append(ex)

        # Validate/Populate dashboards only if it's a list
        if dashboard_ids is not None:
            dashboards = DashboardDAO.find_by_ids(dashboard_ids)
            if len(dashboards) != len(dashboard_ids):
                exceptions.append(DashboardsNotFoundValidationError())
            self._properties["dashboards"] = dashboards

        if exceptions:
            exception = ChartInvalidError()
            exception.add_list(exceptions)
            raise exception
Example #17
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()
Example #18
0
    def validate(self) -> None:
        exceptions: List[ValidationError] = list()
        dashboard_ids = self._properties.get("dashboards")
        owner_ids: Optional[List[int]] = self._properties.get("owners")

        # Validate if datasource_id is provided datasource_type is required
        datasource_id = self._properties.get("datasource_id")
        if datasource_id is not None:
            datasource_type = self._properties.get("datasource_type", "")
            if not datasource_type:
                exceptions.append(
                    DatasourceTypeUpdateRequiredValidationError())

        # Validate/populate model exists
        self._model = ChartDAO.find_by_id(self._model_id)
        if not self._model:
            raise ChartNotFoundError()
        # Check ownership
        try:
            check_ownership(self._model)
        except SupersetSecurityException:
            raise ChartForbiddenError()

        # Validate/Populate datasource
        if datasource_id is not None:
            try:
                datasource = get_datasource_by_id(datasource_id,
                                                  datasource_type)
                self._properties["datasource_name"] = datasource.name
            except ValidationError as ex:
                exceptions.append(ex)

        # Validate/Populate dashboards only if it's a list
        if dashboard_ids is not None:
            dashboards = DashboardDAO.find_by_ids(dashboard_ids)
            if len(dashboards) != len(dashboard_ids):
                exceptions.append(DashboardsNotFoundValidationError())
            self._properties["dashboards"] = dashboards

        # Validate/Populate owner
        try:
            owners = populate_owners(self._actor, owner_ids)
            self._properties["owners"] = owners
        except ValidationError as ex:
            exceptions.append(ex)
        if exceptions:
            exception = ChartInvalidError()
            exception.add_list(exceptions)
            raise exception
Example #19
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()
Example #20
0
 def get_viz_annotation_data(annotation_layer: Dict[str, Any],
                             force: bool) -> Dict[str, Any]:
     chart = ChartDAO.find_by_id(annotation_layer["value"])
     form_data = chart.form_data.copy()
     if not chart:
         raise QueryObjectValidationError(_("The chart does not exist"))
     try:
         viz_obj = get_viz(
             datasource_type=chart.datasource.type,
             datasource_id=chart.datasource.id,
             form_data=form_data,
             force=force,
         )
         payload = viz_obj.get_payload()
         return payload["data"]
     except SupersetException as ex:
         raise QueryObjectValidationError(error_msg_from_exception(ex))
Example #21
0
 def validate(self) -> None:
     # Validate/populate model exists
     self._model = ChartDAO.find_by_id(self._model_id)
     if not self._model:
         raise ChartNotFoundError()
     # Check there are no associated ReportSchedules
     reports = ReportScheduleDAO.find_by_chart_id(self._model_id)
     if reports:
         report_names = [report.name for report in reports]
         raise ChartDeleteFailedReportsExistError(
             _("There are associated alerts or reports: %s" %
               ",".join(report_names)))
     # Check ownership
     try:
         check_ownership(self._model)
     except SupersetSecurityException:
         raise ChartForbiddenError()
Example #22
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()
Example #23
0
 def validate(self) -> None:
     # Validate/populate model exists
     self._models = ChartDAO.find_by_ids(self._model_ids)
     if not self._models or len(self._models) != len(self._model_ids):
         raise ChartNotFoundError()
     # Check there are no associated ReportSchedules
     reports = ReportScheduleDAO.find_by_chart_ids(self._model_ids)
     if reports:
         report_names = [report.name for report in reports]
         raise ChartBulkDeleteFailedReportsExistError(
             _("There are associated alerts or reports: %s" %
               ",".join(report_names)))
     # Check ownership
     for model in self._models:
         try:
             security_manager.raise_for_ownership(model)
         except SupersetSecurityException as ex:
             raise ChartForbiddenError() from ex
Example #24
0
 def validate_chart_dashboard(self,
                              exceptions: List[ValidationError],
                              update: bool = False) -> None:
     """ Validate chart or dashboard relation """
     chart_id = self._properties.get("chart")
     dashboard_id = self._properties.get("dashboard")
     if chart_id and dashboard_id:
         exceptions.append(ReportScheduleChartOrDashboardValidationError())
     if chart_id:
         chart = ChartDAO.find_by_id(chart_id)
         if not chart:
             exceptions.append(ChartNotFoundValidationError())
         self._properties["chart"] = chart
     elif dashboard_id:
         dashboard = DashboardDAO.find_by_id(dashboard_id)
         if not dashboard:
             exceptions.append(DashboardNotFoundValidationError())
         self._properties["dashboard"] = dashboard
     elif not update:
         exceptions.append(ReportScheduleChartOrDashboardValidationError())
Example #25
0
 def validate(self) -> None:
     self._models = ChartDAO.find_by_ids(self.chart_ids)
     if len(self._models) != len(self.chart_ids):
         raise ChartNotFoundError()