Beispiel #1
0
    def add(self, task):
        app.logger.info("Try to enqueue into {}: task={}".format(
            self.progress, task))

        task["progress"] = TaskProgress.STOPPED.name
        task["ended_at"] = self.now

        # Update task progress
        TaskTable.update(task).where(TaskTable.uuid == task["uuid"]).execute()

        app.logger.info("Enqueued into {} successfully: task={}".format(
            self.progress, task["uuid"]))
        return
Beispiel #2
0
    def poll(self):
        # Get all task entries that progress matches the task queue name, e.g., PENDING.
        task_query = (TaskTable.select(
            TaskTable, ScanTable.uuid.alias("scan_exists")).join(
                ScanTable,
                JOIN.LEFT_OUTER,
                on=(TaskTable.uuid == ScanTable.task_uuid)).where(
                    TaskTable.progress == self.progress).order_by(
                        TaskTable.updated_at.asc()))
        for task in task_query.dicts():
            try:
                # Task UUID changes if the task is cancelled/rescheduled by user.
                # Here we cancel a task that is no longer connected to any scan entries.
                if task.pop("scan_exists") is None:
                    raise Exception(
                        "Cancelled: scan has been cancelled/rescheduled by user"
                    )

                # Cancel the task if that scan period has already elapsed
                scheduled_at = task["scheduled_at"].replace(tzinfo=pytz.utc)
                if self.now > (scheduled_at +
                               timedelta(hours=task["max_duration"])):
                    raise Exception("Cancelled: scheduled period has elapsed")

                # Call task process function prepared by each handler
                app.logger.info("Do process: task={}".format(task["uuid"]))
                self.process(task)
            except Exception as error:
                app.logger.warn("ERROR: task={}, error={}".format(
                    task["uuid"], error))
                self.finish(task, error)
Beispiel #3
0
async def insert_task(request: Request,
                      content: str = Form(...),
                      deadline: str = Form(...),
                      credentials: HTTPBasicCredentials = Depends(security)):
    """
    タスクを追加してJsonで追加したタスク情報を返す
    deadlineは %Y-%m-%d_%H:%M:%S (e.g. 2020-06-18_12:30:00)
    """
    # 認証
    username = basic_auth(credentials)
    # ユーザー情報を取得
    user = db.session.query(UserTable).filter(
        UserTable.username == username).first()

    # タスクを追加
    task = TaskTable(user.id, content,
                     datetime.strptime(deadline, '%Y-%m-%d_%H:%M:%S'))

    db.session.add(task)
    db.session.commit()

    # 新しく追加したタスクを取得
    new_task = db.session.query(TaskTable).all()[-1]
    db.session.close()

    # 新規タスクをJsonで返す
    return {
        'id': new_task.id,
        'content': new_task.content,
        'deadline': new_task.deadline.strftime('%Y-%m-%d_%H:%M:%S'),
        'published': new_task.date.strftime('%Y-%m-%d_%H:%M:%S'),
        'done': new_task.done,
    }
Beispiel #4
0
async def add_task(request: Request,
                   credentials: HTTPBasicCredentials = Depends(security)):
    # 認証
    username = basic_auth(credentials)
    # ユーザー情報を取得
    user = db.session.query(UserTable).filter(
        UserTable.username == username).first()

    # フォームからきたデータ取得
    data = await request.form()
    print(data)
    year = int(data['year'])
    month = int(data['month'])
    day = int(data['day'])
    hour = int(data['hour'])
    minute = int(data['minute'])

    deadline = datetime(year=year,
                        month=month,
                        day=day,
                        hour=hour,
                        minute=minute)

    # 新しくタスクを作成しDBコミット
    task = TaskTable(user.id, data['content'], deadline)
    db.session.add(task)
    db.session.commit()
    db.session.close()

    return RedirectResponse('/admin')
Beispiel #5
0
    def add(self, task):
        app.logger.info("Try to enqueue into {}: task={}".format(
            self.progress, task))
        detector = dtm.load_detector(task["detection_module"], task["session"])
        session = detector.run(task["target"], task["detection_mode"])

        task["session"] = session
        task["progress"] = TaskProgress.RUNNING.name
        task["started_at"] = self.now

        with db.database.atomic():
            # Update task progress
            TaskTable.update(task).where(
                TaskTable.uuid == task["uuid"]).execute()
            # Reflect started time to corresponding scan entry
            ScanTable.update({
                "started_at": self.now
            }).where(ScanTable.task_uuid == task["uuid"]).execute()

        im.send(NotificationType.START, task)
        app.logger.info("Enqueued into {} successfully: task={}".format(
            self.progress, task["uuid"]))
        return
Beispiel #6
0
    def finish(self, task, error_reason=""):
        app.logger.info("Try to delete: task={}, error_reason={}".format(
            task, error_reason))
        if task["session"] is not None:
            detector = dtm.load_detector(task["detection_module"],
                                         task["session"])
            detector.delete()
        with db.database.atomic():
            TaskTable.delete().where(TaskTable.uuid == task["uuid"]).execute()
            # Here we use task uuid for finding corresponding scan entry
            # because task uuid of scan entry is changed by user's re-schedule
            ScanTable.update({
                "scheduled_at": None,
                "task_uuid": None,
                "error_reason": error_reason
            }).where(ScanTable.task_uuid == task["uuid"]).execute()

        if error_reason != "":
            im.send(NotificationType.ERROR, task)

        app.logger.info(
            "Deleted successfully: task={}, error_reason={}".format(
                task["uuid"], error_reason))
Beispiel #7
0
    def add(self, scan):
        app.logger.info("Try to enqueue into {}: scan={}".format(self.progress, scan))
        detector = dtm.load_detector(scan["detection_module"], None)

        if detector.TARGET_TYPE == DetectionTarget.HOST.value:
            validate_host(scan["target"])
        elif detector.TARGET_TYPE == DetectionTarget.URL.value:
            scan["target"] = get_safe_url(scan["target"])

        # Avoid concurrent scanning for the same target
        task_query = TaskTable.select().where(TaskTable.target == scan["target"])
        if task_query.count() > 0:
            app.logger.info(
                "Abandoned to enqueue scan={} because another scan for '{}' is still running".format(
                    scan["id"], scan["target"]
                )
            )
            return None

        session = detector.create()
        task = {
            "audit_id": scan["audit_id"],
            "scan_id": scan["id"],
            "scan_uuid": scan["uuid"],
            "target": scan["target"],
            "scheduled_at": scan["scheduled_at"],
            "max_duration": scan["max_duration"],
            "detection_module": scan["detection_module"],
            "detection_mode": scan["detection_mode"],
            "session": session,
            "progress": TaskProgress.PENDING.name,
        }
        task = TaskTable(**task)
        task.save()
        app.logger.info("Enqueued into {} successfully: scan={}".format(self.progress, scan["id"]))
        return task