Exemple #1
0
def do_cli(manager, options):
    if not options.url:
        # Determine if first positional argument is a URL or a title
        if '://' in options.title:
            options.url = options.title
            options.title = None

    if options.url and not options.title:
        # Attempt to get a title from the URL response's headers
        try:
            value, params = cgi.parse_header(requests.head(options.url).headers['Content-Disposition'])
            options.title = params['filename']
        except KeyError:
            console('No title given, and couldn\'t get one from the URL\'s HTTP response. Aborting.')
            return

    entry = Entry(title=options.title)
    if options.url:
        entry['url'] = options.url
    else:
        entry['url'] = 'http://localhost/inject/%s' % ''.join(random.sample(string.letters + string.digits, 30))
    if options.force:
        entry['immortal'] = True
    if options.accept:
        entry.accept(reason='accepted by CLI inject')
    if options.fields:
        for key, value in options.fields:
            entry[key] = value
    options.inject = [entry]
    manager.execute_command(options)
Exemple #2
0
def do_cli(manager, options):
    if not options.url:
        # Determine if first positional argument is a URL or a title
        if '://' in options.title:
            options.url = options.title
            options.title = None

    if options.url and not options.title:
        # Attempt to get a title from the URL response's headers
        try:
            value, params = cgi.parse_header(
                requests.head(options.url).headers['Content-Disposition'])
            options.title = params['filename']
        except KeyError:
            console(
                'No title given, and couldn\'t get one from the URL\'s HTTP response. Aborting.'
            )
            return

    entry = Entry(title=options.title)
    if options.url:
        entry['url'] = options.url
    else:
        entry['url'] = 'http://localhost/inject/%s' % ''.join(
            random.sample(string.letters + string.digits, 30))
    if options.force:
        entry['immortal'] = True
    if options.accept:
        entry.accept(reason='accepted by CLI inject')
    if options.fields:
        for key, value in options.fields:
            entry[key] = value
    options.inject = [entry]
    manager.execute_command(options)
Exemple #3
0
    def post(self, session: Session = None) -> Response:
        """ Execute task and stream results """
        data = request.json
        for task in data.get('tasks'):
            if task.lower() not in [
                    t.lower()
                    for t in self.manager.user_config.get('tasks', {}).keys()
            ]:
                raise NotFoundError(f'task {task} does not exist')

        queue = ExecuteLog()
        output = queue if data.get('loglevel') else None
        stream = (True if any(
            arg[0] in ['progress', 'summary', 'loglevel', 'entry_dump']
            for arg in data.items() if arg[1]) else False)
        loglevel = data.pop('loglevel', None)

        if loglevel:
            loglevel = loglevel.upper()

        # This emulates the CLI command of using `--now` and `no-cache`
        options = {
            'interval_ignore': data.pop('now', None),
            'nocache': data.pop('no_cache', None),
            'allow_manual': True,
        }

        for option, value in data.items():
            options[option] = value

        if data.get('inject'):
            entries = []
            for item in data.get('inject'):
                entry = Entry()
                entry['url'] = item['url']
                if not item.get('title'):
                    try:
                        value, params = cgi.parse_header(
                            requests.head(
                                item['url']).headers['Content-Disposition'])
                        entry['title'] = params['filename']
                    except KeyError:
                        raise BadRequest(
                            'No title given, and couldn\'t get one from the URL\'s HTTP response'
                        )

                else:
                    entry['title'] = item.get('title')
                if item.get('force'):
                    entry['immortal'] = True
                if item.get('accept'):
                    entry.accept(reason='accepted by API inject')
                if item.get('fields'):
                    for key, value in item.get('fields').items():
                        entry[key] = value
                entries.append(entry)
            options['inject'] = entries

        if output:
            with capture_console(output), capture_logs(output, level=loglevel):
                executed_tasks = self.manager.execute(options=options)
        else:
            executed_tasks = self.manager.execute(options=options)

        tasks_queued = []

        for task_id, task_name, task_event in executed_tasks:
            tasks_queued.append({
                'id': task_id,
                'name': task_name,
                'event': task_event
            })
            _streams[task_id] = {
                'queue': queue,
                'last_update': datetime.now(),
                'args': data
            }

        if not stream:
            return jsonify({
                'tasks': [{
                    'id': task['id'],
                    'name': task['name']
                } for task in tasks_queued]
            })

        def stream_response():
            # First return the tasks to execute
            yield '{"stream": ['
            yield json.dumps({
                'tasks': [{
                    'id': task['id'],
                    'name': task['name']
                } for task in tasks_queued]
            }) + ',\n'

            while True:
                try:
                    yield queue.get(timeout=1) + ',\n'
                    continue
                except Empty:
                    pass

                if queue.empty() and all(
                    [task['event'].is_set() for task in tasks_queued]):
                    for task in tasks_queued:
                        del _streams[task['id']]
                    break
            yield '{}]}'

        return Response(stream_response(), mimetype='text/event-stream')
Exemple #4
0
    def post(self, session=None):
        """ Execute task and stream results """
        data = request.json
        for task in data.get('tasks'):
            if task.lower() not in [t.lower() for t in self.manager.user_config.get('tasks', {}).keys()]:
                return {'error': 'task %s does not exist' % task}, 404

        queue = ExecuteLog()
        output = queue if data.get('loglevel') else None
        stream = True if any(
            arg[0] in ['progress', 'summary', 'loglevel', 'entry_dump'] for arg in data.items() if arg[1]) else False
        loglevel = data.get('loglevel')
        options = {'tasks': data.get('tasks')}

        if data.get('inject'):
            entries = []
            for item in data.get('inject'):
                entry = Entry()
                entry['url'] = item['url']
                if not item.get('title'):
                    try:
                        value, params = cgi.parse_header(requests.head(item['url']).headers['Content-Disposition'])
                        entry['title'] = params['filename']
                    except KeyError:
                        return {'status': 'error',
                                'message': 'No title given, and couldn\'t get one from the URL\'s HTTP response'}, 500
                else:
                    entry['title'] = item.get('title')
                if item.get('force'):
                    entry['immortal'] = True
                if item.get('accept'):
                    entry.accept(reason='accepted by API inject')
                if item.get('fields'):
                    for key, value in item.get('fields').items():
                        entry[key] = value
                entries.append(entry)
            options['inject'] = entries

        executed_tasks = self.manager.execute(options=options, output=output, loglevel=loglevel)

        tasks_queued = []

        for task_id, task_name, task_event in executed_tasks:
            tasks_queued.append({'id': task_id, 'name': task_name, 'event': task_event})
            _streams[task_id] = {
                'queue': queue,
                'last_update': datetime.now(),
                'args': data
            }

        if not stream:
            return jsonify({'tasks': [{'id': task['id'], 'name': task['name']} for task in tasks_queued]})

        def stream_response():
            # First return the tasks to execute
            yield '{"stream": ['
            yield json.dumps({'tasks': [{'id': task['id'], 'name': task['name']} for task in tasks_queued]}) + ',\n'

            while True:
                try:
                    yield queue.get(timeout=1) + ',\n'
                    continue
                except Empty:
                    pass

                if queue.empty() and all([task['event'].is_set() for task in tasks_queued]):
                    for task in tasks_queued:
                        del _streams[task['id']]
                    break
            yield '{}]}'

        return Response(stream_response(), mimetype='text/event-stream')
Exemple #5
0
    def post(self, session=None):
        """ Execute task and stream results """
        data = request.json
        for task in data.get('tasks'):
            if task.lower() not in [
                    t.lower()
                    for t in self.manager.user_config.get('tasks', {}).keys()
            ]:
                return {'error': 'task %s does not exist' % task}, 404

        queue = ExecuteLog()
        output = queue if data.get('loglevel') else None
        stream = True if any(
            arg[0] in ['progress', 'summary', 'loglevel', 'entry_dump']
            for arg in data.items() if arg[1]) else False
        loglevel = data.get('loglevel')
        options = {'tasks': data.get('tasks')}

        if data.get('inject'):
            entries = []
            for item in data.get('inject'):
                entry = Entry()
                entry['url'] = item['url']
                if not item.get('title'):
                    try:
                        value, params = cgi.parse_header(
                            requests.head(
                                item['url']).headers['Content-Disposition'])
                        entry['title'] = params['filename']
                    except KeyError:
                        return {
                            'status':
                            'error',
                            'message':
                            'No title given, and couldn\'t get one from the URL\'s HTTP response'
                        }, 500
                else:
                    entry['title'] = item.get('title')
                if item.get('force'):
                    entry['immortal'] = True
                if item.get('accept'):
                    entry.accept(reason='accepted by API inject')
                if item.get('fields'):
                    for key, value in item.get('fields').items():
                        entry[key] = value
                entries.append(entry)
            options['inject'] = entries

        executed_tasks = self.manager.execute(options=options,
                                              output=output,
                                              loglevel=loglevel)

        tasks_queued = []

        for task_id, task_name, task_event in executed_tasks:
            tasks_queued.append({
                'id': task_id,
                'name': task_name,
                'event': task_event
            })
            _streams[task_id] = {
                'queue': queue,
                'last_update': datetime.now(),
                'args': data
            }

        if not stream:
            return jsonify({
                'tasks': [{
                    'id': task['id'],
                    'name': task['name']
                } for task in tasks_queued]
            })

        def stream_response():
            # First return the tasks to execute
            yield '{"stream": ['
            yield json.dumps({
                'tasks': [{
                    'id': task['id'],
                    'name': task['name']
                } for task in tasks_queued]
            }) + ',\n'

            while True:
                try:
                    yield queue.get(timeout=1) + ',\n'
                    continue
                except Empty:
                    pass

                if queue.empty() and all(
                    [task['event'].is_set() for task in tasks_queued]):
                    for task in tasks_queued:
                        del _streams[task['id']]
                    break
            yield '{}]}'

        return Response(stream_response(), mimetype='text/event-stream')
Exemple #6
0
    def post(self, task, session=None):
        """ Execute task and stream results """
        data = request.json

        if task.lower() not in [t.lower() for t in self.manager.user_config.get('tasks', {}).keys()]:
            return {'error': 'task does not exist'}, 404

        queue = ExecuteLog()
        output = queue if data.get('log') else None
        stream = True if any(
            arg[0] in ['progress', 'summary', 'log', 'entry_dump'] for arg in data.items() if arg[1]) else False
        loglevel = data.get('loglevel')
        options = {'tasks': [task]}

        if data.get('inject'):
            entries = []
            for item in data.get('inject'):
                entry = Entry()
                entry['url'] = item['url']
                if not item.get('title'):
                    try:
                        value, params = cgi.parse_header(requests.head(item['url']).headers['Content-Disposition'])
                        entry['title'] = params['filename']
                    except KeyError:
                        return {'status': 'error',
                                'message': 'No title given, and couldn\'t get one from the URL\'s HTTP response'}, 500
                else:
                    entry['title'] = item.get('title')
                if item.get('force'):
                    entry['immortal'] = True
                if item.get('accept'):
                    entry.accept(reason='accepted by API inject')
                if item.get('fields'):
                    for key, value in item.get('fields').items():
                        entry[key] = value
                entries.append(entry)
            options['inject'] = entries

        task_id, __, task_event = self.manager.execute(options=options, output=output, loglevel=loglevel)[0]

        if not stream:
            return {'task': {'id': task_id, 'name': task}}

        _streams[task_id] = {
            'queue': queue,
            'last_update': datetime.now(),
            'args': data
        }

        def stream_response():
            yield '{"task": {"id": "%s", "name": "%s", "stream": [' % (task_id, task)

            while True:
                # If the server is shutting down then end the stream nicely
                if cherrypy.engine.state != cherrypy.engine.states.STARTED:
                    break

                try:
                    yield queue.get(timeout=1) + ',\n'
                    continue
                except Empty:
                    pass

                if queue.empty() and task_event.is_set():
                    del _streams[task_id]
                    break
            yield '{}]}}'

        return Response(stream_response(), mimetype='text/event-stream')
Exemple #7
0
    def post(self, session=None):
        """ Execute task and stream results """
        data = request.json
        for task in data.get("tasks"):
            if task.lower() not in [t.lower() for t in self.manager.user_config.get("tasks", {}).keys()]:
                return {"error": "task %s does not exist" % task}, 404

        queue = ExecuteLog()
        output = queue if data.get("loglevel") else None
        stream = (
            True
            if any(arg[0] in ["progress", "summary", "loglevel", "entry_dump"] for arg in data.items() if arg[1])
            else False
        )
        loglevel = data.pop("loglevel", None)

        # This emulates the CLI command of using `--now`
        options = {"interval_ignore": data.pop("now", None)}

        for option, value in data.items():
            options[option] = value

        if data.get("inject"):
            entries = []
            for item in data.get("inject"):
                entry = Entry()
                entry["url"] = item["url"]
                if not item.get("title"):
                    try:
                        value, params = cgi.parse_header(requests.head(item["url"]).headers["Content-Disposition"])
                        entry["title"] = params["filename"]
                    except KeyError:
                        return (
                            {
                                "status": "error",
                                "message": "No title given, and couldn't get one from the URL's HTTP response",
                            },
                            500,
                        )
                else:
                    entry["title"] = item.get("title")
                if item.get("force"):
                    entry["immortal"] = True
                if item.get("accept"):
                    entry.accept(reason="accepted by API inject")
                if item.get("fields"):
                    for key, value in item.get("fields").items():
                        entry[key] = value
                entries.append(entry)
            options["inject"] = entries

        executed_tasks = self.manager.execute(options=options, output=output, loglevel=loglevel)

        tasks_queued = []

        for task_id, task_name, task_event in executed_tasks:
            tasks_queued.append({"id": task_id, "name": task_name, "event": task_event})
            _streams[task_id] = {"queue": queue, "last_update": datetime.now(), "args": data}

        if not stream:
            return jsonify({"tasks": [{"id": task["id"], "name": task["name"]} for task in tasks_queued]})

        def stream_response():
            # First return the tasks to execute
            yield '{"stream": ['
            yield json.dumps({"tasks": [{"id": task["id"], "name": task["name"]} for task in tasks_queued]}) + ",\n"

            while True:
                try:
                    yield queue.get(timeout=1) + ",\n"
                    continue
                except Empty:
                    pass

                if queue.empty() and all([task["event"].is_set() for task in tasks_queued]):
                    for task in tasks_queued:
                        del _streams[task["id"]]
                    break
            yield "{}]}"

        return Response(stream_response(), mimetype="text/event-stream")