Пример #1
0
 def delete_doc_by_query(self, index: str, query: dict):
     try:
         res = self.client.delete_by_query(index=index, body=query)
         return {"index": index, "result": res}
     except Exception as e:
         log_error(e)
         raise
Пример #2
0
 def get_status(cls, api_root, status_id):
     log_debug(f'Request to Get the status of {status_id} from {api_root}')
     try:
         result = cls.es_client.get_doc(index=f'{api_root}-status',
                                        doc_id=status_id)
         return result['data']
     except Exception as e:
         log_error(e)
         return EXCEPTIONS.get('StatusNotFoundException')
Пример #3
0
 def get_collection(cls, api_root, collection_id):
     log_debug(
         f'Request to Get Collection {collection_id} from Feed: {api_root}')
     try:
         result = cls.es_client.get_doc(index=f'{api_root}-collections',
                                        doc_id=collection_id).get('data')
         return result
     except Exception as e:
         log_error(e)
         return EXCEPTIONS.get('CollectionNotFoundException', {})
Пример #4
0
 def update_doc(self, index: str, data: object, doc_id: str):
     try:
         res = self.client.update(index=index,
                                  id=doc_id,
                                  body={"doc": data},
                                  refresh='wait_for')
         return {"index": res['_index'], "id": res['_id'], "result": res}
     except Exception as e:
         log_error(e)
         raise
Пример #5
0
    def roots_discovery(cls):
        log_debug('Request to Get Discovery Info')

        try:
            result = cls.es_client.get_doc(index='discovery',
                                           doc_id='discovery')
            return result['data']
        except Exception as e:
            log_error(e)
            return EXCEPTIONS.get('DiscoveryException', {})
Пример #6
0
 def delete_doc(self, index: str, doc_id: str):
     try:
         res = self.client.delete(index=index, id=doc_id)
         return {
             "index": res['_index'],
             "id": res['_id'],
             "result": res['result']
         }
     except Exception as e:
         log_error(e)
         raise
Пример #7
0
    def get_collection_objects(cls, api_root, collection_id):
        log_debug(f'Request to Get The objects of Collection: {collection_id} in the Feed Root: {api_root}')

        try:
            result = cls.es_client.get_doc(index=f'{api_root}-collections', doc_id=collection_id)['data']['objects']
            return {
                'objects': result
            }
        except Exception as e:
            log_error(e)
            return EXCEPTIONS.get('CollectionNotFoundException', {})
Пример #8
0
 def get_collections(cls, api_root):
     log_debug(f'Request to Get all Collections under {api_root} Root')
     try:
         result = cls.es_client.get_docs(
             index=f'{api_root}-collections').get('data')
         return {'collections': result}
     except NotFoundError as e:
         log_error(e)
         return EXCEPTIONS.get('APIRootNotFoundException', {})
     except Exception as e:
         log_error(e)
         return EXCEPTIONS.get('CollectionsNotFoundException', {})
Пример #9
0
    def store_docs(self, index: str, data: list):
        try:

            def yield_bulk_data(bulk_data):
                for doc in bulk_data:
                    yield {"_index": index, "_id": doc['id'], "_source": doc}

            res = helpers.bulk(self.client, yield_bulk_data(data))
            return {"result": res}
        except Exception as e:
            log_error(e)
            raise
Пример #10
0
 def get_default_root_information(cls):
     log_debug('Request to Get Default API Root Information')
     try:
         default_api_root_url = cls.es_client.get_doc(
             index='discovery', doc_id='discovery').get('data')['default']
         default_api_root = urlparse(default_api_root_url)[2].partition(
             '/')[2].partition('/')[0]
         result = cls.es_client.get_doc(index='feeds',
                                        doc_id=default_api_root)
         return result['data']['information']
     except Exception as e:
         log_error(e)
         return EXCEPTIONS.get('DefaultAPIRootNotFoundException')
Пример #11
0
 def get_docs(self, index: str):
     try:
         res = self.client.search(index=index, size=10, sort='id')
         results = []
         for result in res['hits']['hits']:
             response = {}
             response.update(result['_source'])
             response.update({'id': result['id']})
             results.append(response)
         return {
             "data": results,
             "total": res['hits']['total']['value'],
         }
     except Exception as e:
         log_error(e)
         raise
Пример #12
0
    def post_objects(cls, cti_objects):
        log_info(f'Request to Post {len(cti_objects)} Objects')

        result = {}
        try:
            entry = cls.es_client.store_docs(
                index="stix21", data=cti_objects.dict().get('objects'))
            result["status"] = 'success'
            result["payload"] = entry
            return result
        except Exception as e:
            log_error(e)
            result["status"] = 'fail'
            result["payload"] = {
                "message": "Error (E:4) while posting the object .."
            }
            return result
Пример #13
0
 def store_doc(self,
               index: str,
               data: object,
               doc_id=int(round(time.time() * 1000))):
     try:
         res = self.client.index(index=index,
                                 id=doc_id,
                                 body=data,
                                 refresh='wait_for')
         return {
             "index": res['_index'],
             "id": res['_id'],
             "result": res['result']
         }
     except Exception as e:
         log_error(e)
         raise
Пример #14
0
    def get_collection_manifest(cls, api_root, **query_parameters):
        objects_query = None
        manifest_query = None
        version_range = None
        added_after_range = None
        size = int(query_parameters.get('limit'))
        max_page_size = PAGE_SIZE
        added_after = query_parameters.get('added_after')
        sort_by = {'date_added': {'order': 'asc'}}
        types = query_parameters.get('types')
        ids = query_parameters.get('ids')
        versions = query_parameters.get('versions')
        spec_versions = query_parameters.get('spec_versions')
        base_page = 0
        next_id = 0
        objects_query = None
        manifest_query = None
        version_range = None
        added_after_range = None

        log_debug(
            f"Request to Get The objects Manifest of Collection: {query_parameters.get('collection_id')} "
            f"in the Feed Root: {api_root}")

        if query_parameters is None:
            query_parameters = {}

        try:
            # Create a Query to filter Objects by collection id, types and spec_versions
            objects_query = f"collection : {query_parameters.get('collection_id')}"
            if types:
                types = types.replace(",", " OR ")
                objects_query = objects_query + f" AND type : ('{types}')"
            if spec_versions:
                spec_versions = spec_versions.replace(",", " OR ")
                objects_query = objects_query + f" AND spec_version : ('{spec_versions}')"
            objects_query_string = QueryString(query=objects_query,
                                               default_operator="and")

            # Create a Query to filter Manifest by collection id, object id's, versions and added after dates
            manifest_query = f"collection : {query_parameters.get('collection_id')}"
            if ids:
                ids = ids.replace(",", " OR ")
                manifest_query = manifest_query + f" AND id : ('{ids}')"
            if added_after:
                added_after_range = Range(
                    **{'date_added': {
                        'gt': f'{added_after}'
                    }})
            manifests_query_string = QueryString(query=manifest_query,
                                                 default_operator="and")

            # Get the intersect of both Objects and Manifest Queries
            intersected_results = cls.es_client.manifest_intersect(
                intersect_by='id',
                objects_index=f'{api_root}-objects',
                objects_query_string=objects_query_string,
                manifests_index=f'{api_root}-manifest',
                manifests_query_string=manifests_query_string,
                added_after_range=added_after_range)

            # Version and Paginate The Results
            if intersected_results:
                manifest_ids = ",".join(intersected_results).replace(
                    ',', ' OR ')
                query_string = QueryString(query=f"id:('{manifest_ids}')",
                                           default_operator="AND")
                pre_versioning_results = cls.es_client.scan(
                    index=f'{api_root}-manifest', query_string=query_string)
                pre_pagination_results = Helper.fetch_objects_by_versions(
                    stix_objects=pre_versioning_results, versions=versions)
                if -1 < size < max_page_size:
                    results = cls.es_client.search(
                        index=f'{api_root}-manifest',
                        query_string=query_string,
                        search_from=base_page,
                        size=size,
                        sort_by=sort_by)
                else:
                    results = cls.es_client.search(
                        index=f'{api_root}-manifest',
                        query_string=query_string,
                        search_from=base_page,
                        size=max_page_size,
                        sort_by=sort_by)
                results = {'objects': pre_pagination_results}
            else:
                results = {"objects": []}
            return results

        except Exception as e:
            log_error(e)
            if query_parameters.get('next'):
                return EXCEPTIONS.get('NextNotFoundException', {})
            else:
                return EXCEPTIONS.get('CollectionNotFoundException', {})
Пример #15
0
    def es_prep(self):
        try:
            collections = []
            manifests_data = []
            objects_data = []

            # Prepare Discovery Data
            if not self.discovery_data:
                self.discovery_data = self.TAXII_DEFAULT_DISCOVERY
            if not self.client.indices.exists(
                    self.discovery_data.get('_index')):
                log_info(
                    f"Loading default data in {self.discovery_data.get('_index')} index..."
                )
                # Create The Discovery Index
                self.client.indices.create(
                    index=self.discovery_data.get('_index'))
                # Load The Discovery Data
                helpers.bulk(self.client, [self.discovery_data])

            # Prepare API Roots Data
            if not self.roots_data:
                self.roots_data = self.TAXII_DEFAULT_ROOTS
            for root in self.roots_data:
                if not self.client.indices.exists(root.get('_index')):
                    log_info(
                        f"Loading default data in {root.get('_index')} index..."
                    )
                    # Create The API Roots Index
                    self.client.indices.create(index=root.get('_index'))
                    # Load The API Roots Data
                    helpers.bulk(self.client, self.roots_data)

            # Prepare Status Data
            if not self.status_data:
                self.status_data = self.TAXXI_DEFAULT_STATUS
            for root in self.roots_data:
                if not self.client.indices.exists(f"{root.get('_id')}-status"):
                    log_info(
                        f"Loading default data in status index: {root.get('_id')}-status"
                    )
                    # Create A Status Index Per Root
                    self.client.indices.create(
                        index=f"{root.get('_id')}-status")
                    # Load The Status Data
                    helpers.bulk(self.client, self.status_data)

            # Prepare Collections Data
            if not self.collections_data:
                self.collections_data = self.TAXXI_DEFAULT_COLLECTIONS
            for root in self.roots_data:
                manifests_data = []
                if not self.client.indices.exists(
                        f"{root.get('_id')}-manifest"):
                    log_info(
                        f"Loading default data in manifest index: {root.get('_id')}-manifest"
                    )
                    # Create A Manifest Index Per Root
                    self.client.indices.create(
                        index=f"{root.get('_id')}-manifest")
                    # Load The Manifest Data Per Collection
                    for collection in self.collections_data:
                        if root.get('_id') in collection.get('_index'):
                            manifests = collection['_source'].get('manifest')
                            if manifests:
                                for manifest in manifests:
                                    manifest['collection'] = collection.get(
                                        '_id')
                                    manifest_default = {
                                        "_index":
                                        f"{root.get('_id')}-manifest",
                                        "_source": manifest
                                    }
                                    manifests_data.append(manifest_default)
                    helpers.bulk(self.client, manifests_data)
                if not self.client.indices.exists(
                        f"{root.get('_id')}-objects"):
                    log_info(
                        f"Loading objects data in objects index: {root.get('_id')}-objects"
                    )
                    # Create An Objects Index Per Root
                    self.client.indices.create(
                        index=f"{root.get('_id')}-objects")
                    # Load Objects Data Per Collection
                    for collection in self.collections_data:
                        if root.get('_id') in collection.get('_index'):
                            objects = collection['_source'].get('objects')
                            if objects:
                                for collection_object in objects:
                                    collection_object[
                                        'collection'] = collection.get('_id')
                                    object_default = {
                                        "_index": f"{root.get('_id')}-objects",
                                        "_source": collection_object
                                    }
                                    objects_data.append(object_default)
                    helpers.bulk(self.client, objects_data)
            for root in self.roots_data:
                if not self.client.indices.exists(
                        f"{root.get('_id')}-collections"):
                    log_info(
                        f"Loading collections data in collections index: {root.get('_id')}-collections"
                    )
                    # Create A Collections Index Per Root
                    self.client.indices.create(
                        index=f"{root.get('_id')}-collections")
                    # Load Collections Per Index
                    for collection in self.collections_data:
                        collection['_source'].pop("manifest", None)
                        collection['_source'].pop("responses", None)
                        collection['_source'].pop("objects", None)
                        collections.append(collection)
                    helpers.bulk(self.client, collections)

            # Create Next Index

            if not self.client.indices.exists('next'):
                log_info(f"Creating Next index...")
                # Create The API Roots Index
                self.client.indices.create('next')

        except Exception as error:
            log_error(error)
Пример #16
0
    es_client.es_prep()
    app = FastAPI(middleware=ValidationMiddleware)

    @app.exception_handler(StarletteHTTPException)
    async def http_exception_handler(request, exc):
        return JSONResponse(content={
            "title": str(exc.detail),
            "error_code": str(exc.status_code)
        },
                            status_code=exc.status_code)

    # TODO: Enforce Authorization
    # TODO: Enable Paging
    # TODO: Review Error Codes
    # TODO: Review The Custom Headers

    app.include_router(discovery.router)
    app.include_router(collections.router)
    app.include_router(objects.router)

    log_info('Galaxy is running ..')

else:
    log_error(
        'Galaxy is not ready to start, having a problem connecting to ElasticSearch'
    )

if __name__ == '__main__':

    uvicorn.run(app, port=4000, host='0.0.0.0')