def add(self, stix_data, version=None): """Add/push STIX content to TAXII Collection endpoint Args: stix_data (STIX object OR dict OR str OR list): valid STIX2 content in a STIX object (or Bundle), STIX object dict (or Bundle dict), or a STIX2 json encoded string, or list of any of the following. version (str): If present, it forces the parser to use the version provided. Otherwise, the library will make the best effort based on checking the "spec_version" property. """ if isinstance(stix_data, _STIXBase): # adding python STIX object if stix_data['type'] == 'bundle': bundle = stix_data.serialize(encoding='utf-8', ensure_ascii=False) elif 'spec_version' in stix_data: # If the spec_version is present, use new Bundle object... bundle = v21.Bundle(stix_data, allow_custom=self.allow_custom).serialize(encoding='utf-8', ensure_ascii=False) else: bundle = v20.Bundle(stix_data, allow_custom=self.allow_custom).serialize(encoding='utf-8', ensure_ascii=False) elif isinstance(stix_data, dict): # adding python dict (of either Bundle or STIX obj) if stix_data['type'] == 'bundle': bundle = parse(stix_data, allow_custom=self.allow_custom, version=version).serialize(encoding='utf-8', ensure_ascii=False) elif 'spec_version' in stix_data: # If the spec_version is present, use new Bundle object... bundle = v21.Bundle(stix_data, allow_custom=self.allow_custom).serialize(encoding='utf-8', ensure_ascii=False) else: bundle = v20.Bundle(stix_data, allow_custom=self.allow_custom).serialize(encoding='utf-8', ensure_ascii=False) elif isinstance(stix_data, list): # adding list of something - recurse on each for obj in stix_data: self.add(obj, version=version) return elif isinstance(stix_data, str): # adding json encoded string of STIX content stix_data = parse(stix_data, allow_custom=self.allow_custom, version=version) if stix_data['type'] == 'bundle': bundle = stix_data.serialize(encoding='utf-8', ensure_ascii=False) elif 'spec_version' in stix_data: # If the spec_version is present, use new Bundle object... bundle = v21.Bundle(stix_data, allow_custom=self.allow_custom).serialize(encoding='utf-8', ensure_ascii=False) else: bundle = v20.Bundle(stix_data, allow_custom=self.allow_custom).serialize(encoding='utf-8', ensure_ascii=False) else: raise TypeError("stix_data must be as STIX object(or list of),json formatted STIX (or list of), or a json formatted STIX bundle") self.collection.add_objects(bundle)
def save_to_file(self, path, encoding="utf-8"): path = os.path.abspath(path) all_objs = list( itertools.chain.from_iterable(value.all_versions.values( ) if isinstance(value, _ObjectFamily) else [value] for value in self._data.values())) if any("spec_version" in x for x in all_objs): bundle = v21.Bundle(all_objs, allow_custom=self.allow_custom) else: bundle = v20.Bundle(all_objs, allow_custom=self.allow_custom) if path.endswith(".json"): if not os.path.exists(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) else: if not os.path.exists(path): os.makedirs(path) # if the user only provided a directory, use the bundle id for filename path = os.path.join(path, bundle["id"] + ".json") with io.open(path, "w", encoding=encoding) as f: bundle = bundle.serialize(pretty=True, encoding=encoding, ensure_ascii=False) f.write(bundle) return path
def _check_path_and_write(self, stix_obj, encoding='utf-8'): """Write the given STIX object to a file in the STIX file directory. """ type_dir = os.path.join(self._stix_dir, stix_obj["type"]) if is_marking(stix_obj): filename = stix_obj["id"] obj_dir = type_dir else: filename = _timestamp2filename(stix_obj["modified"]) obj_dir = os.path.join(type_dir, stix_obj["id"]) file_path = os.path.join(obj_dir, filename + ".json") if not os.path.exists(obj_dir): os.makedirs(obj_dir) if self.bundlify: if 'spec_version' in stix_obj: # Assuming future specs will allow multiple SDO/SROs # versions in a single bundle we won't need to check this # and just use the latest supported Bundle version. stix_obj = v21.Bundle(stix_obj, allow_custom=self.allow_custom) else: stix_obj = v20.Bundle(stix_obj, allow_custom=self.allow_custom) if os.path.isfile(file_path): raise DataSourceError( "Attempted to overwrite file (!) at: {}".format(file_path)) else: with io.open(file_path, 'w', encoding=encoding) as f: stix_obj = stix_obj.serialize(pretty=True, encoding=encoding, ensure_ascii=False) f.write(stix_obj)
def write_object(obj, stix_dir, unique_info, id_map) -> None: subdirectory_name = stix_dir / obj.type if not subdirectory_name.exists(): subdirectory_name.mkdir() file_name = subdirectory_name / (obj.id + ".json") id_map[(obj.type, unique_info)] = obj.id print(f"Adding {obj.id}") with file_name.open("w", encoding="utf-8") as output_file: bundle_str = v21.Bundle(objects=[obj]).serialize(pretty=True, encoding="utf-8", ensure_ascii=False) output_file.write(bundle_str)