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 create_stix2_bundle(objects): ''' Creates a STIX2 Bundle object from a list of objects. Args: objects: list of ``stix2`` SDO objects. Returns: A ``stix2.Bundle`` instance. ''' if objects: return v20.Bundle(objects=objects) else: return v20.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)