Esempio n. 1
0
    def get_urls(self):
        urls = []
        session = db.create_scoped_session()

        records = (
            session
            .query(Log.dashboard_id, func.count(Log.dashboard_id))
            .filter(and_(
                Log.dashboard_id.isnot(None),
                Log.dttm >= self.since,
            ))
            .group_by(Log.dashboard_id)
            .order_by(func.count(Log.dashboard_id).desc())
            .limit(self.top_n)
            .all()
        )
        dash_ids = [record.dashboard_id for record in records]
        dashboards = (
            session
            .query(Dashboard)
            .filter(Dashboard.id.in_(dash_ids))
            .all()
        )
        for dashboard in dashboards:
            for chart in dashboard.slices:
                urls.append(
                    get_url({'form_data': get_form_data(chart.id, dashboard)}))

        return urls
def schedule_alert_query(  # pylint: disable=unused-argument
    task: Task,
    report_type: ScheduleType,
    schedule_id: int,
    recipients: Optional[str] = None,
    is_test_alert: Optional[bool] = False,
) -> None:
    model_cls = get_scheduler_model(report_type)
    dbsession = db.create_scoped_session()
    schedule = dbsession.query(model_cls).get(schedule_id)

    # The user may have disabled the schedule. If so, ignore this
    if not schedule or not schedule.active:
        logger.info("Ignoring deactivated alert")
        return

    if report_type == ScheduleType.alert:
        if is_test_alert and recipients:
            deliver_alert(schedule.id, recipients)
            return

        if run_alert_query(schedule.id, dbsession):
            # deliver_dashboard OR deliver_slice
            return
    else:
        raise RuntimeError("Unknown report type")
Esempio n. 3
0
def schedule_email_report(  # pylint: disable=unused-argument
    task: Task,
    report_type: ScheduleType,
    schedule_id: int,
    recipients: Optional[str] = None,
) -> None:
    model_cls = get_scheduler_model(report_type)
    schedule = db.create_scoped_session().query(model_cls).get(schedule_id)

    # The user may have disabled the schedule. If so, ignore this
    if not schedule or not schedule.active:
        logger.info("Ignoring deactivated schedule")
        return

    # TODO: Detach the schedule object from the db session
    if recipients is not None:
        schedule.id = schedule_id
        schedule.recipients = recipients

    if report_type == ScheduleType.dashboard:
        deliver_dashboard(schedule)
    elif report_type == ScheduleType.slice:
        deliver_slice(schedule)
    else:
        raise RuntimeError("Unknown report type")
Esempio n. 4
0
    def get_urls(self):
        session = db.create_scoped_session()
        charts = session.query(Slice).all()

        return [
            get_url({"form_data": get_form_data(chart.id)}) for chart in charts
        ]
Esempio n. 5
0
def schedule_window(report_type: str, start_at: datetime, stop_at: datetime,
                    resolution: int) -> None:
    """
    Find all active schedules and schedule celery tasks for
    each of them with a specific ETA (determined by parsing
    the cron schedule for the schedule)
    """
    model_cls = get_scheduler_model(report_type)

    if not model_cls:
        return None

    dbsession = db.create_scoped_session()
    schedules = dbsession.query(model_cls).filter(model_cls.active.is_(True))

    for schedule in schedules:
        logging.info("Processing schedule %s", schedule)
        args = (report_type, schedule.id)

        if (hasattr(schedule, "last_eval_dttm") and schedule.last_eval_dttm
                and schedule.last_eval_dttm > start_at):
            # start_at = schedule.last_eval_dttm + timedelta(seconds=1)
            pass
        # Schedule the job for the specified time window
        for eta in next_schedules(schedule.crontab,
                                  start_at,
                                  stop_at,
                                  resolution=resolution):
            get_scheduler_action(report_type).apply_async(
                args, eta=eta)  # type: ignore
            break

    return None
Esempio n. 6
0
def schedule_window(report_type: ScheduleType, start_at: datetime,
                    stop_at: datetime, resolution: int) -> None:
    """
    Find all active schedules and schedule celery tasks for
    each of them with a specific ETA (determined by parsing
    the cron schedule for the schedule)
    """
    model_cls = get_scheduler_model(report_type)

    if not model_cls:
        return None

    dbsession = db.create_scoped_session()
    schedules = dbsession.query(model_cls).filter(model_cls.active.is_(True))

    for schedule in schedules:
        args = (report_type, schedule.id)

        # Schedule the job for the specified time window
        for eta in next_schedules(schedule.crontab,
                                  start_at,
                                  stop_at,
                                  resolution=resolution):
            schedule_email_report.apply_async(args, eta=eta)

    return None
Esempio n. 7
0
 def get_latest_query(self, sql):
     session = db.create_scoped_session()
     query = (
         session.query(models.Query)
             .order_by(models.Query.id.desc())
             .first()
     )
     session.close()
     return query
Esempio n. 8
0
 def get_latest_query(self, sql):
     session = db.create_scoped_session()
     query = (
         session.query(models.Query)
             .order_by(models.Query.id.desc())
             .first()
     )
     session.close()
     return query
Esempio n. 9
0
    def get_urls(self):
        urls = []
        session = db.create_scoped_session()

        tags = (
            session
            .query(Tag)
            .filter(Tag.name.in_(self.tags))
            .all()
        )
        tag_ids = [tag.id for tag in tags]

        # add dashboards that are tagged
        tagged_objects = (
            session
            .query(TaggedObject)
            .filter(and_(
                TaggedObject.object_type == 'dashboard',
                TaggedObject.tag_id.in_(tag_ids),
            ))
            .all()
        )
        dash_ids = [tagged_object.object_id for tagged_object in tagged_objects]
        tagged_dashboards = (
            session
            .query(Dashboard)
            .filter(Dashboard.id.in_(dash_ids))
        )
        for dashboard in tagged_dashboards:
            for chart in dashboard.slices:
                urls.append(
                    get_url({'form_data': get_form_data(chart.id, dashboard)}))

        # add charts that are tagged
        tagged_objects = (
            session
            .query(TaggedObject)
            .filter(and_(
                TaggedObject.object_type == 'chart',
                TaggedObject.tag_id.in_(tag_ids),
            ))
            .all()
        )
        chart_ids = [tagged_object.object_id for tagged_object in tagged_objects]
        tagged_charts = (
            session
            .query(Slice)
            .filter(Slice.id.in_(chart_ids))
        )
        for chart in tagged_charts:
            urls.append(get_url({'form_data': get_form_data(chart.id)}))

        return urls
Esempio n. 10
0
def schedule_email_report(task, report_type, schedule_id):
    model_cls = get_scheduler_model(report_type)
    dbsession = db.create_scoped_session()
    schedule = dbsession.query(model_cls).get(schedule_id)

    # The user may have disabled the schedule. If so, ignore this
    if not schedule.active:
        logging.info('Ignoring deactivated schedule')
        return

    if report_type == ScheduleType.dashboard.value:
        deliver_dashboard(schedule)
    elif report_type == ScheduleType.slice.value:
        deliver_slice(schedule)
    else:
        raise RuntimeError('Unknown report type')
Esempio n. 11
0
def check_ownership(obj: Any, raise_if_false: bool = True) -> bool:
    """Meant to be used in `pre_update` hooks on models to enforce ownership

    Admin have all access, and other users need to be referenced on either
    the created_by field that comes with the ``AuditMixin``, or in a field
    named ``owners`` which is expected to be a one-to-many with the User
    model. It is meant to be used in the ModelView's pre_update hook in
    which raising will abort the update.
    """
    if not obj:
        return False

    security_exception = SupersetSecurityException(
        SupersetError(
            error_type=SupersetErrorType.MISSING_OWNERSHIP_ERROR,
            message="You don't have the rights to alter [{}]".format(obj),
            level=ErrorLevel.ERROR,
        ))

    if g.user.is_anonymous:
        if raise_if_false:
            raise security_exception
        return False
    roles = [r.name for r in get_user_roles()]
    if "Admin" in roles:
        return True
    scoped_session = db.create_scoped_session()
    orig_obj = scoped_session.query(obj.__class__).filter_by(id=obj.id).first()

    # Making a list of owners that works across ORM models
    owners: List[User] = []
    if hasattr(orig_obj, "owners"):
        owners += orig_obj.owners
    if hasattr(orig_obj, "owner"):
        owners += [orig_obj.owner]
    if hasattr(orig_obj, "created_by"):
        owners += [orig_obj.created_by]

    owner_names = [o.username for o in owners if o]

    if g.user and hasattr(g.user,
                          "username") and g.user.username in owner_names:
        return True
    if raise_if_false:
        raise security_exception
    else:
        return False
Esempio n. 12
0
def check_ownership(obj, raise_if_false=True):
    """Meant to be used in `pre_update` hooks on models to enforce ownership

    Admin have all access, and other users need to be referenced on either
    the created_by field that comes with the ``AuditMixin``, or in a field
    named ``owners`` which is expected to be a one-to-many with the User
    model. It is meant to be used in the ModelView's pre_update hook in
    which raising will abort the update.
    """
    if not obj:
        return False

    security_exception = SupersetSecurityException(
        "You don't have the rights to alter [{}]".format(obj))

    if g.user.is_anonymous:
        if raise_if_false:
            raise security_exception
        return False
    roles = [r.name for r in get_user_roles()]
    if 'Admin' in roles:
        return True
    session = db.create_scoped_session()
    orig_obj = session.query(obj.__class__).filter_by(id=obj.id).first()

    # Making a list of owners that works across ORM models
    owners = []
    if hasattr(orig_obj, 'owners'):
        owners += orig_obj.owners
    if hasattr(orig_obj, 'owner'):
        owners += [orig_obj.owner]
    if hasattr(orig_obj, 'created_by'):
        owners += [orig_obj.created_by]

    owner_names = [o.username for o in owners if o]

    if (
            g.user and hasattr(g.user, 'username') and
            g.user.username in owner_names):
        return True
    if raise_if_false:
        raise security_exception
    else:
        return False
Esempio n. 13
0
def check_ownership(obj, raise_if_false=True):
    """Meant to be used in `pre_update` hooks on models to enforce ownership

    Admin have all access, and other users need to be referenced on either
    the created_by field that comes with the ``AuditMixin``, or in a field
    named ``owners`` which is expected to be a one-to-many with the User
    model. It is meant to be used in the ModelView's pre_update hook in
    which raising will abort the update.
    """
    if not obj:
        return False

    security_exception = SupersetSecurityException(
        "You don't have the rights to alter [{}]".format(obj))

    if g.user.is_anonymous:
        if raise_if_false:
            raise security_exception
        return False
    roles = [r.name for r in get_user_roles()]
    if 'Admin' in roles:
        return True
    session = db.create_scoped_session()
    orig_obj = session.query(obj.__class__).filter_by(id=obj.id).first()

    # Making a list of owners that works across ORM models
    owners = []
    if hasattr(orig_obj, 'owners'):
        owners += orig_obj.owners
    if hasattr(orig_obj, 'owner'):
        owners += [orig_obj.owner]
    if hasattr(orig_obj, 'created_by'):
        owners += [orig_obj.created_by]

    owner_names = [o.username for o in owners if o]

    if (
            g.user and hasattr(g.user, 'username') and
            g.user.username in owner_names):
        return True
    if raise_if_false:
        raise security_exception
    else:
        return False
Esempio n. 14
0
def schedule_email_report(task, report_type, schedule_id, recipients=None):
    model_cls = get_scheduler_model(report_type)
    schedule = db.create_scoped_session().query(model_cls).get(schedule_id)

    # The user may have disabled the schedule. If so, ignore this
    if not schedule or not schedule.active:
        logging.info('Ignoring deactivated schedule')
        return

    # TODO: Detach the schedule object from the db session
    if recipients is not None:
        schedule.id = schedule_id
        schedule.recipients = recipients

    if report_type == ScheduleType.dashboard.value:
        deliver_dashboard(schedule)
    elif report_type == ScheduleType.slice.value:
        deliver_slice(schedule)
    else:
        raise RuntimeError('Unknown report type')
Esempio n. 15
0
def schedule_email_report(task, report_type, schedule_id, recipients=None):
    model_cls = get_scheduler_model(report_type)
    schedule = db.create_scoped_session().query(model_cls).get(schedule_id)

    # The user may have disabled the schedule. If so, ignore this
    if not schedule or not schedule.active:
        logging.info('Ignoring deactivated schedule')
        return

    # TODO: Detach the schedule object from the db session
    if recipients is not None:
        schedule.id = schedule_id
        schedule.recipients = recipients

    if report_type == ScheduleType.dashboard.value:
        deliver_dashboard(schedule)
    elif report_type == ScheduleType.slice.value:
        deliver_slice(schedule)
    else:
        raise RuntimeError('Unknown report type')
Esempio n. 16
0
def schedule_email_report(  # pylint: disable=unused-argument
    task: Task,
    report_type: ScheduleType,
    schedule_id: int,
    recipients: Optional[str] = None,
    slack_channel: Optional[str] = None,
) -> None:
    model_cls = get_scheduler_model(report_type)
    schedule = db.create_scoped_session().query(model_cls).get(schedule_id)

    # The user may have disabled the schedule. If so, ignore this
    if not schedule or not schedule.active:
        logger.info("Ignoring deactivated schedule")
        return

    recipients = recipients or schedule.recipients
    slack_channel = slack_channel or schedule.slack_channel
    logger.info(
        "Starting report for slack: %s and recipients: %s.", slack_channel, recipients
    )

    if report_type == ScheduleType.dashboard:
        deliver_dashboard(
            schedule.dashboard_id,
            recipients,
            slack_channel,
            schedule.delivery_type,
            schedule.deliver_as_group,
        )
    elif report_type == ScheduleType.slice:
        deliver_slice(
            schedule.slice_id,
            recipients,
            slack_channel,
            schedule.delivery_type,
            schedule.email_format,
            schedule.deliver_as_group,
        )
    else:
        raise RuntimeError("Unknown report type")
Esempio n. 17
0
def schedule_window(report_type, start_at, stop_at, resolution):
    """
    Find all active schedules and schedule celery tasks for
    each of them with a specific ETA (determined by parsing
    the cron schedule for the schedule)
    """
    model_cls = get_scheduler_model(report_type)
    dbsession = db.create_scoped_session()
    schedules = dbsession.query(model_cls).filter(model_cls.active.is_(True))

    for schedule in schedules:
        args = (
            report_type,
            schedule.id,
        )

        # Schedule the job for the specified time window
        for eta in next_schedules(schedule.crontab,
                                  start_at,
                                  stop_at,
                                  resolution=resolution):
            schedule_email_report.apply_async(args, eta=eta)
Esempio n. 18
0
 def get_query_by_sql(self, sql):
     session = db.create_scoped_session()
     query = session.query(models.Query).filter_by(sql=sql).first()
     session.close()
     return query
Esempio n. 19
0
 def get_query_by_sql(self, sql):
     session = db.create_scoped_session()
     query = session.query(models.Query).filter_by(sql=sql).first()
     session.close()
     return query
Esempio n. 20
0
    def get_urls(self):
        session = db.create_scoped_session()
        charts = session.query(Slice).all()

        return [get_url({'form_data': get_form_data(chart.id)}) for chart in charts]
Esempio n. 21
0
    def get_urls(self):
        session = db.create_scoped_session()
        charts = session.query(Slice).all()

        return [get_url(chart) for chart in charts]