Exemplo n.º 1
0
    def post(self, sketch_id):
        """Handles POST request to the resource.

        Returns:
            A sketch in JSON (instance of flask.wrappers.Response)
        """
        sketch = Sketch.query.get_with_acl(sketch_id)
        if not sketch:
            abort(
                HTTP_STATUS_CODE_NOT_FOUND, 'No sketch found with this ID.')

        if not sketch.has_permission(current_user, 'write'):
            abort(HTTP_STATUS_CODE_FORBIDDEN,
                  'User does not have write access controls on sketch.')

        form = request.json
        if not form:
            form = request.data

        metadata = {'created': True}

        searchindex_id = form.get('timeline', 0)
        if isinstance(searchindex_id, str) and searchindex_id.isdigit():
            searchindex_id = int(searchindex_id)

        if not isinstance(searchindex_id, int):
            abort(
                HTTP_STATUS_CODE_BAD_REQUEST,
                'The timeline (searchindex id) needs to be an integer.')

        searchindex = SearchIndex.query.get_with_acl(searchindex_id)
        if searchindex.get_status.status == 'deleted':
            abort(
                HTTP_STATUS_CODE_BAD_REQUEST,
                'Unable to create a timeline using a deleted search index')

        timeline_id = [
            t.searchindex.id for t in sketch.timelines
            if t.searchindex.id == searchindex_id
        ]

        if not timeline_id:
            return_code = HTTP_STATUS_CODE_CREATED
            timeline_name = form.get('timeline_name', searchindex.name)
            timeline = Timeline(
                name=timeline_name,
                description=searchindex.description,
                sketch=sketch,
                user=current_user,
                searchindex=searchindex)
            sketch.timelines.append(timeline)
            labels_to_prevent_deletion = current_app.config.get(
                'LABELS_TO_PREVENT_DELETION', [])

            for label in sketch.get_labels:
                if label not in labels_to_prevent_deletion:
                    continue
                timeline.add_label(label)
                searchindex.add_label(label)

            # Set status to ready so the timeline can be queried.
            timeline.set_status('ready')

            db_session.add(timeline)
            db_session.commit()
        else:
            metadata['created'] = False
            return_code = HTTP_STATUS_CODE_OK
            timeline = Timeline.query.get(timeline_id)

        # Run sketch analyzers when timeline is added. Import here to avoid
        # circular imports.
        # pylint: disable=import-outside-toplevel
        if current_app.config.get('AUTO_SKETCH_ANALYZERS'):
            # pylint: disable=import-outside-toplevel
            from timesketch.lib import tasks
            sketch_analyzer_group, _ = tasks.build_sketch_analysis_pipeline(
                sketch_id, searchindex_id, current_user.id,
                timeline_id=timeline_id)
            if sketch_analyzer_group:
                pipeline = (tasks.run_sketch_init.s(
                    [searchindex.index_name]) | sketch_analyzer_group)
                pipeline.apply_async()

        # Update the last activity of a sketch.
        utils.update_sketch_last_activity(sketch)

        return self.to_json(
            timeline, meta=metadata, status_code=return_code)
Exemplo n.º 2
0
    def _upload_and_index(self,
                          file_extension,
                          timeline_name,
                          index_name,
                          sketch,
                          enable_stream,
                          file_path='',
                          events='',
                          meta=None):
        """Creates a full pipeline for an uploaded file and returns the results.

        Args:
            file_extension: the extension of the uploaded file.
            timeline_name: name the timeline will be stored under in the
                           datastore.
            index_name: the Elastic index name for the timeline.
            sketch: Instance of timesketch.models.sketch.Sketch
            enable_stream: boolean indicating whether this is file is part of a
                           stream or not.
            file_path: the path to the file to be uploaded (optional).
            events: a string with events to upload (optional).
            meta: optional dict with additional meta fields that will be
                  included in the return.

        Returns:
            A timeline if created otherwise a search index in JSON (instance
            of flask.wrappers.Response)
        """
        # Check if search index already exists.
        searchindex = SearchIndex.query.filter_by(
            name=timeline_name,
            description=timeline_name,
            user=current_user,
            index_name=index_name).first()

        timeline = None

        if searchindex:
            searchindex.set_status('processing')
            timeline = Timeline.query.filter_by(
                name=searchindex.name,
                description=searchindex.description,
                sketch=sketch,
                user=current_user,
                searchindex=searchindex).first()
        else:
            # Create the search index in the Timesketch database
            searchindex = SearchIndex.get_or_create(name=timeline_name,
                                                    description='',
                                                    user=current_user,
                                                    index_name=index_name)
            searchindex.grant_permission(permission='read', user=current_user)
            searchindex.grant_permission(permission='write', user=current_user)
            searchindex.grant_permission(permission='delete',
                                         user=current_user)
            searchindex.set_status('processing')
            db_session.add(searchindex)
            db_session.commit()

            if sketch and sketch.has_permission(current_user, 'write'):
                labels_to_prevent_deletion = current_app.config.get(
                    'LABELS_TO_PREVENT_DELETION', [])
                timeline = Timeline(name=searchindex.name,
                                    description=searchindex.description,
                                    sketch=sketch,
                                    user=current_user,
                                    searchindex=searchindex)
                timeline.set_status('processing')
                sketch.timelines.append(timeline)
                for label in sketch.get_labels:
                    if label not in labels_to_prevent_deletion:
                        continue
                    timeline.add_label(label)
                    searchindex.add_label(label)
                db_session.add(timeline)
                db_session.commit()

        # Start Celery pipeline for indexing and analysis.
        # Import here to avoid circular imports.
        # pylint: disable=import-outside-toplevel
        from timesketch.lib import tasks
        pipeline = tasks.build_index_pipeline(file_path=file_path,
                                              events=events,
                                              timeline_name=timeline_name,
                                              index_name=index_name,
                                              file_extension=file_extension,
                                              sketch_id=sketch.id,
                                              only_index=enable_stream)
        pipeline.apply_async()

        # Return Timeline if it was created.
        # pylint: disable=no-else-return
        if timeline:
            return self.to_json(timeline,
                                status_code=HTTP_STATUS_CODE_CREATED,
                                meta=meta)

        return self.to_json(searchindex,
                            status_code=HTTP_STATUS_CODE_CREATED,
                            meta=meta)