chg: Added parameter to accept UUIDs not v4
- This parameter is not used at the creation of STIX objects, only while converting json format into STIX objects.1master
parent
522e9cedd0
commit
067d76bb90
|
@ -14,8 +14,9 @@ from .utils import _get_dict, get_class_hierarchy_names
|
||||||
|
|
||||||
class STIXObjectProperty(Property):
|
class STIXObjectProperty(Property):
|
||||||
|
|
||||||
def __init__(self, allow_custom=False, *args, **kwargs):
|
def __init__(self, allow_custom=False, interoperability=False, *args, **kwargs):
|
||||||
self.allow_custom = allow_custom
|
self.allow_custom = allow_custom
|
||||||
|
self.interoperability = interoperability
|
||||||
super(STIXObjectProperty, self).__init__(*args, **kwargs)
|
super(STIXObjectProperty, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
|
@ -33,11 +34,7 @@ class STIXObjectProperty(Property):
|
||||||
if 'type' in dictified and dictified['type'] == 'bundle':
|
if 'type' in dictified and dictified['type'] == 'bundle':
|
||||||
raise ValueError('This property may not contain a Bundle object')
|
raise ValueError('This property may not contain a Bundle object')
|
||||||
|
|
||||||
if self.allow_custom:
|
return parse(dictified, self.allow_custom, self.interoperability)
|
||||||
parsed_obj = parse(dictified, allow_custom=True)
|
|
||||||
else:
|
|
||||||
parsed_obj = parse(dictified)
|
|
||||||
return parsed_obj
|
|
||||||
|
|
||||||
|
|
||||||
class Bundle(_STIXBase):
|
class Bundle(_STIXBase):
|
||||||
|
@ -62,8 +59,13 @@ class Bundle(_STIXBase):
|
||||||
else:
|
else:
|
||||||
kwargs['objects'] = list(args) + kwargs.get('objects', [])
|
kwargs['objects'] = list(args) + kwargs.get('objects', [])
|
||||||
|
|
||||||
self.__allow_custom = kwargs.get('allow_custom', False)
|
allow_custom = kwargs.get('allow_custom', False)
|
||||||
self._properties['objects'].contained.allow_custom = kwargs.get('allow_custom', False)
|
self.__allow_custom = allow_custom
|
||||||
|
self._properties['objects'].contained.allow_custom = allow_custom
|
||||||
|
interoperability = kwargs.get('interoperability', False)
|
||||||
|
self.__interoperability = interoperability
|
||||||
|
self._properties['id'].interoperability = interoperability
|
||||||
|
self._properties['objects'].contained.interoperability = interoperability
|
||||||
|
|
||||||
super(Bundle, self).__init__(**kwargs)
|
super(Bundle, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
@ -71,7 +73,7 @@ class Bundle(_STIXBase):
|
||||||
STIX2_OBJ_MAPS = {}
|
STIX2_OBJ_MAPS = {}
|
||||||
|
|
||||||
|
|
||||||
def parse(data, allow_custom=False, version=None):
|
def parse(data, allow_custom=False, interoperability=False, version=None):
|
||||||
"""Convert a string, dict or file-like object into a STIX object.
|
"""Convert a string, dict or file-like object into a STIX object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -97,12 +99,12 @@ def parse(data, allow_custom=False, version=None):
|
||||||
obj = _get_dict(data)
|
obj = _get_dict(data)
|
||||||
|
|
||||||
# convert dict to full python-stix2 obj
|
# convert dict to full python-stix2 obj
|
||||||
obj = dict_to_stix2(obj, allow_custom, version)
|
obj = dict_to_stix2(obj, allow_custom, interoperability, version)
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def dict_to_stix2(stix_dict, allow_custom=False, version=None):
|
def dict_to_stix2(stix_dict, allow_custom=False, interoperability=False, version=None):
|
||||||
"""convert dictionary to full python-stix2 object
|
"""convert dictionary to full python-stix2 object
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -144,7 +146,7 @@ def dict_to_stix2(stix_dict, allow_custom=False, version=None):
|
||||||
return stix_dict
|
return stix_dict
|
||||||
raise exceptions.ParseError("Can't parse unknown object type '%s'! For custom types, use the CustomObject decorator." % stix_dict['type'])
|
raise exceptions.ParseError("Can't parse unknown object type '%s'! For custom types, use the CustomObject decorator." % stix_dict['type'])
|
||||||
|
|
||||||
return obj_class(allow_custom=allow_custom, **stix_dict)
|
return obj_class(allow_custom=allow_custom, interoperability=interoperability, **stix_dict)
|
||||||
|
|
||||||
|
|
||||||
def _register_type(new_type, version=None):
|
def _register_type(new_type, version=None):
|
||||||
|
|
|
@ -25,6 +25,13 @@ ID_REGEX = re.compile("^[a-z0-9][a-z0-9-]+[a-z0-9]--" # object type
|
||||||
"[89abAB][0-9a-fA-F]{3}-"
|
"[89abAB][0-9a-fA-F]{3}-"
|
||||||
"[0-9a-fA-F]{12}$")
|
"[0-9a-fA-F]{12}$")
|
||||||
|
|
||||||
|
ID_REGEX_interoperability = re.compile("^[a-z0-9][a-z0-9-]+[a-z0-9]--" # object type
|
||||||
|
"[0-9a-fA-F]{8}-"
|
||||||
|
"[0-9a-fA-F]{4}-"
|
||||||
|
"[0-9a-fA-F]{4}-"
|
||||||
|
"[0-9a-fA-F]{4}-"
|
||||||
|
"[0-9a-fA-F]{12}$")
|
||||||
|
|
||||||
ERROR_INVALID_ID = (
|
ERROR_INVALID_ID = (
|
||||||
"not a valid STIX identifier, must match <object-type>--<UUIDv4>"
|
"not a valid STIX identifier, must match <object-type>--<UUIDv4>"
|
||||||
)
|
)
|
||||||
|
@ -185,8 +192,12 @@ class IDProperty(Property):
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
if not value.startswith(self.required_prefix):
|
if not value.startswith(self.required_prefix):
|
||||||
raise ValueError("must start with '{0}'.".format(self.required_prefix))
|
raise ValueError("must start with '{0}'.".format(self.required_prefix))
|
||||||
if not ID_REGEX.match(value):
|
if hasattr(self, 'interoperability') and self.interoperability:
|
||||||
raise ValueError(ERROR_INVALID_ID)
|
if not ID_REGEX_interoperability.match(value):
|
||||||
|
raise ValueError(ERROR_INVALID_ID)
|
||||||
|
else:
|
||||||
|
if not ID_REGEX.match(value):
|
||||||
|
raise ValueError(ERROR_INVALID_ID)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def default(self):
|
def default(self):
|
||||||
|
|
|
@ -135,6 +135,7 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
|
||||||
if not isinstance(kwargs['definition'], marking_type):
|
if not isinstance(kwargs['definition'], marking_type):
|
||||||
defn = _get_dict(kwargs['definition'])
|
defn = _get_dict(kwargs['definition'])
|
||||||
kwargs['definition'] = marking_type(**defn)
|
kwargs['definition'] = marking_type(**defn)
|
||||||
|
self._properties['id'].interoperability = kwargs.get('interoperability', False)
|
||||||
|
|
||||||
super(MarkingDefinition, self).__init__(**kwargs)
|
super(MarkingDefinition, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,13 @@ from .observables import ObservableProperty
|
||||||
|
|
||||||
|
|
||||||
class STIXDomainObject(_STIXBase, _MarkingsMixin):
|
class STIXDomainObject(_STIXBase, _MarkingsMixin):
|
||||||
pass
|
def __init__(self, *args, **kwargs):
|
||||||
|
interoperability = kwargs.get('interoperability', False)
|
||||||
|
self.__interoperability = interoperability
|
||||||
|
self._properties['id'].interoperability = interoperability
|
||||||
|
self._properties['created_by_ref'].interoperability = interoperability
|
||||||
|
|
||||||
|
super(STIXDomainObject, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class AttackPattern(STIXDomainObject):
|
class AttackPattern(STIXDomainObject):
|
||||||
|
|
Loading…
Reference in New Issue