Change the stix2 class map structure to be keyed at the top
level with STIX versions in the same format as is used everywhere else in the API: "X.Y", as opposed to the "vXY" format used by the version-specific python packages. This eliminates all of the awkward conversion from public API format to "vXX" format. Also a little bit of code rearranging in the registration module to ensure that some STIX 2.1-specific checks are done whether version 2.1 is given explicitly or is defaulted to. In the same module I also added a missing import of stix2.properties, since my IDE was claiming it could not find a function from that module.pull/1/head
parent
188f704b28
commit
f88fba6751
|
@ -49,8 +49,7 @@ def _detect_spec_version(stix_dict):
|
||||||
|
|
||||||
:param stix_dict: A dict with some STIX content. Must at least have a
|
:param stix_dict: A dict with some STIX content. Must at least have a
|
||||||
"type" property.
|
"type" property.
|
||||||
:return: A string in "vXX" format, where "XX" indicates the spec version,
|
:return: A STIX version in "X.Y" format
|
||||||
e.g. "v20", "v21", etc.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
obj_type = stix_dict["type"]
|
obj_type = stix_dict["type"]
|
||||||
|
@ -58,16 +57,16 @@ def _detect_spec_version(stix_dict):
|
||||||
if 'spec_version' in stix_dict:
|
if 'spec_version' in stix_dict:
|
||||||
# For STIX 2.0, applies to bundles only.
|
# For STIX 2.0, applies to bundles only.
|
||||||
# For STIX 2.1+, applies to SCOs, SDOs, SROs, and markings only.
|
# For STIX 2.1+, applies to SCOs, SDOs, SROs, and markings only.
|
||||||
v = 'v' + stix_dict['spec_version'].replace('.', '')
|
v = stix_dict['spec_version']
|
||||||
elif "id" not in stix_dict:
|
elif "id" not in stix_dict:
|
||||||
# Only 2.0 SCOs don't have ID properties
|
# Only 2.0 SCOs don't have ID properties
|
||||||
v = "v20"
|
v = "2.0"
|
||||||
elif obj_type == 'bundle':
|
elif obj_type == 'bundle':
|
||||||
# Bundle without a spec_version property: must be 2.1. But to
|
# Bundle without a spec_version property: must be 2.1. But to
|
||||||
# future-proof, use max version over all contained SCOs, with 2.1
|
# future-proof, use max version over all contained SCOs, with 2.1
|
||||||
# minimum.
|
# minimum.
|
||||||
v = max(
|
v = max(
|
||||||
"v21",
|
"2.1",
|
||||||
max(
|
max(
|
||||||
_detect_spec_version(obj) for obj in stix_dict["objects"]
|
_detect_spec_version(obj) for obj in stix_dict["objects"]
|
||||||
),
|
),
|
||||||
|
@ -75,10 +74,10 @@ def _detect_spec_version(stix_dict):
|
||||||
elif obj_type in registry.STIX2_OBJ_MAPS["v21"]["observables"]:
|
elif obj_type in registry.STIX2_OBJ_MAPS["v21"]["observables"]:
|
||||||
# Non-bundle object with an ID and without spec_version. Could be a
|
# Non-bundle object with an ID and without spec_version. Could be a
|
||||||
# 2.1 SCO or 2.0 SDO/SRO/marking. Check for 2.1 SCO...
|
# 2.1 SCO or 2.0 SDO/SRO/marking. Check for 2.1 SCO...
|
||||||
v = "v21"
|
v = "2.1"
|
||||||
else:
|
else:
|
||||||
# Not a 2.1 SCO; must be a 2.0 object.
|
# Not a 2.1 SCO; must be a 2.0 object.
|
||||||
v = "v20"
|
v = "2.0"
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
@ -115,15 +114,12 @@ def dict_to_stix2(stix_dict, allow_custom=False, version=None):
|
||||||
if 'type' not in stix_dict:
|
if 'type' not in stix_dict:
|
||||||
raise ParseError("Can't parse object with no 'type' property: %s" % str(stix_dict))
|
raise ParseError("Can't parse object with no 'type' property: %s" % str(stix_dict))
|
||||||
|
|
||||||
if version:
|
if not version:
|
||||||
# If the version argument was passed, override other approaches.
|
version = _detect_spec_version(stix_dict)
|
||||||
v = 'v' + version.replace('.', '')
|
|
||||||
else:
|
|
||||||
v = _detect_spec_version(stix_dict)
|
|
||||||
|
|
||||||
OBJ_MAP = dict(
|
OBJ_MAP = dict(
|
||||||
registry.STIX2_OBJ_MAPS[v]['objects'],
|
registry.STIX2_OBJ_MAPS[version]['objects'],
|
||||||
**registry.STIX2_OBJ_MAPS[v]['observables']
|
**registry.STIX2_OBJ_MAPS[version]['observables']
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -168,14 +164,11 @@ def parse_observable(data, _valid_refs=None, allow_custom=False, version=None):
|
||||||
|
|
||||||
obj['_valid_refs'] = _valid_refs or []
|
obj['_valid_refs'] = _valid_refs or []
|
||||||
|
|
||||||
if version:
|
if not version:
|
||||||
# If the version argument was passed, override other approaches.
|
version = _detect_spec_version(obj)
|
||||||
v = 'v' + version.replace('.', '')
|
|
||||||
else:
|
|
||||||
v = _detect_spec_version(obj)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
OBJ_MAP_OBSERVABLE = registry.STIX2_OBJ_MAPS[v]['observables']
|
OBJ_MAP_OBSERVABLE = registry.STIX2_OBJ_MAPS[version]['observables']
|
||||||
obj_class = OBJ_MAP_OBSERVABLE[obj['type']]
|
obj_class = OBJ_MAP_OBSERVABLE[obj['type']]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if allow_custom:
|
if allow_custom:
|
||||||
|
|
|
@ -503,14 +503,14 @@ class ReferenceProperty(Property):
|
||||||
possible_prefix = value[:value.index('--')]
|
possible_prefix = value[:value.index('--')]
|
||||||
|
|
||||||
if self.valid_types:
|
if self.valid_types:
|
||||||
ref_valid_types = enumerate_types(self.valid_types, 'v' + self.spec_version.replace(".", ""))
|
ref_valid_types = enumerate_types(self.valid_types, self.spec_version)
|
||||||
|
|
||||||
if possible_prefix in ref_valid_types:
|
if possible_prefix in ref_valid_types:
|
||||||
required_prefix = possible_prefix
|
required_prefix = possible_prefix
|
||||||
else:
|
else:
|
||||||
raise ValueError("The type-specifying prefix '%s' for this property is not valid" % (possible_prefix))
|
raise ValueError("The type-specifying prefix '%s' for this property is not valid" % (possible_prefix))
|
||||||
elif self.invalid_types:
|
elif self.invalid_types:
|
||||||
ref_invalid_types = enumerate_types(self.invalid_types, 'v' + self.spec_version.replace(".", ""))
|
ref_invalid_types = enumerate_types(self.invalid_types, self.spec_version)
|
||||||
|
|
||||||
if possible_prefix not in ref_invalid_types:
|
if possible_prefix not in ref_invalid_types:
|
||||||
required_prefix = possible_prefix
|
required_prefix = possible_prefix
|
||||||
|
@ -655,9 +655,7 @@ class ExtensionsProperty(DictionaryProperty):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValueError("The extensions property must contain a dictionary")
|
raise ValueError("The extensions property must contain a dictionary")
|
||||||
|
|
||||||
v = 'v' + self.spec_version.replace('.', '')
|
specific_type_map = STIX2_OBJ_MAPS[self.spec_version]['observable-extensions'].get(self.enclosing_type, {})
|
||||||
|
|
||||||
specific_type_map = STIX2_OBJ_MAPS[v]['observable-extensions'].get(self.enclosing_type, {})
|
|
||||||
for key, subvalue in dictified.items():
|
for key, subvalue in dictified.items():
|
||||||
if key in specific_type_map:
|
if key in specific_type_map:
|
||||||
cls = specific_type_map[key]
|
cls = specific_type_map[key]
|
||||||
|
|
|
@ -31,18 +31,15 @@ def _register_object(new_type, version=DEFAULT_VERSION):
|
||||||
|
|
||||||
properties = new_type._properties
|
properties = new_type._properties
|
||||||
|
|
||||||
|
if not version:
|
||||||
|
version = DEFAULT_VERSION
|
||||||
|
|
||||||
if version == "2.1":
|
if version == "2.1":
|
||||||
for prop_name, prop in properties.items():
|
for prop_name, prop in properties.items():
|
||||||
if not re.match(PREFIX_21_REGEX, prop_name):
|
if not re.match(PREFIX_21_REGEX, prop_name):
|
||||||
raise ValueError("Property name '%s' must begin with an alpha character" % prop_name)
|
raise ValueError("Property name '%s' must begin with an alpha character" % prop_name)
|
||||||
|
|
||||||
if version:
|
OBJ_MAP = registry.STIX2_OBJ_MAPS[version]['objects']
|
||||||
v = 'v' + version.replace('.', '')
|
|
||||||
else:
|
|
||||||
# Use default version (latest) if no version was provided.
|
|
||||||
v = 'v' + DEFAULT_VERSION.replace('.', '')
|
|
||||||
|
|
||||||
OBJ_MAP = registry.STIX2_OBJ_MAPS[v]['objects']
|
|
||||||
if new_type._type in OBJ_MAP.keys():
|
if new_type._type in OBJ_MAP.keys():
|
||||||
raise DuplicateRegistrationError("STIX Object", new_type._type)
|
raise DuplicateRegistrationError("STIX Object", new_type._type)
|
||||||
OBJ_MAP[new_type._type] = new_type
|
OBJ_MAP[new_type._type] = new_type
|
||||||
|
@ -61,6 +58,9 @@ def _register_marking(new_marking, version=DEFAULT_VERSION):
|
||||||
mark_type = new_marking._type
|
mark_type = new_marking._type
|
||||||
properties = new_marking._properties
|
properties = new_marking._properties
|
||||||
|
|
||||||
|
if not version:
|
||||||
|
version = DEFAULT_VERSION
|
||||||
|
|
||||||
_validate_type(mark_type, version)
|
_validate_type(mark_type, version)
|
||||||
|
|
||||||
if version == "2.1":
|
if version == "2.1":
|
||||||
|
@ -68,9 +68,7 @@ def _register_marking(new_marking, version=DEFAULT_VERSION):
|
||||||
if not re.match(PREFIX_21_REGEX, prop_name):
|
if not re.match(PREFIX_21_REGEX, prop_name):
|
||||||
raise ValueError("Property name '%s' must begin with an alpha character." % prop_name)
|
raise ValueError("Property name '%s' must begin with an alpha character." % prop_name)
|
||||||
|
|
||||||
class_maps = registry.get_stix2_class_maps(
|
class_maps = registry.get_stix2_class_maps(version)
|
||||||
version or DEFAULT_VERSION
|
|
||||||
)
|
|
||||||
|
|
||||||
OBJ_MAP_MARKING = class_maps['markings']
|
OBJ_MAP_MARKING = class_maps['markings']
|
||||||
if mark_type in OBJ_MAP_MARKING.keys():
|
if mark_type in OBJ_MAP_MARKING.keys():
|
||||||
|
@ -89,6 +87,9 @@ def _register_observable(new_observable, version=DEFAULT_VERSION):
|
||||||
"""
|
"""
|
||||||
properties = new_observable._properties
|
properties = new_observable._properties
|
||||||
|
|
||||||
|
if not version:
|
||||||
|
version = stix2.DEFAULT_VERSION
|
||||||
|
|
||||||
if version == "2.0":
|
if version == "2.0":
|
||||||
# If using STIX2.0, check properties ending in "_ref/s" are ObjectReferenceProperties
|
# If using STIX2.0, check properties ending in "_ref/s" are ObjectReferenceProperties
|
||||||
for prop_name, prop in properties.items():
|
for prop_name, prop in properties.items():
|
||||||
|
@ -128,9 +129,7 @@ def _register_observable(new_observable, version=DEFAULT_VERSION):
|
||||||
"is not a ListProperty containing ReferenceProperty." % prop_name,
|
"is not a ListProperty containing ReferenceProperty." % prop_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
class_maps = registry.get_stix2_class_maps(
|
class_maps = registry.get_stix2_class_maps(version)
|
||||||
version or DEFAULT_VERSION
|
|
||||||
)
|
|
||||||
|
|
||||||
OBJ_MAP_OBSERVABLE = class_maps['observables']
|
OBJ_MAP_OBSERVABLE = class_maps['observables']
|
||||||
if new_observable._type in OBJ_MAP_OBSERVABLE.keys():
|
if new_observable._type in OBJ_MAP_OBSERVABLE.keys():
|
||||||
|
|
|
@ -7,6 +7,20 @@ import re
|
||||||
STIX2_OBJ_MAPS = {}
|
STIX2_OBJ_MAPS = {}
|
||||||
|
|
||||||
|
|
||||||
|
def _stix_vid_to_version(stix_vid):
|
||||||
|
"""
|
||||||
|
Convert a python package name representing a STIX version in the form "vXX"
|
||||||
|
to the dotted style used in the public APIs of this library, "X.X".
|
||||||
|
|
||||||
|
:param stix_vid: A package name in the form "vXX"
|
||||||
|
:return: A STIX version in dotted style
|
||||||
|
"""
|
||||||
|
assert len(stix_vid) >= 3
|
||||||
|
|
||||||
|
stix_version = stix_vid[1] + "." + stix_vid[2:]
|
||||||
|
return stix_version
|
||||||
|
|
||||||
|
|
||||||
def _collect_stix2_mappings():
|
def _collect_stix2_mappings():
|
||||||
"""Navigate the package once and retrieve all object mapping dicts for each
|
"""Navigate the package once and retrieve all object mapping dicts for each
|
||||||
v2X package. Includes OBJ_MAP, OBJ_MAP_OBSERVABLE, EXT_MAP."""
|
v2X package. Includes OBJ_MAP, OBJ_MAP_OBSERVABLE, EXT_MAP."""
|
||||||
|
@ -16,14 +30,16 @@ def _collect_stix2_mappings():
|
||||||
prefix = str(top_level_module.__name__) + '.'
|
prefix = str(top_level_module.__name__) + '.'
|
||||||
|
|
||||||
for module_loader, name, is_pkg in pkgutil.walk_packages(path=path, prefix=prefix):
|
for module_loader, name, is_pkg in pkgutil.walk_packages(path=path, prefix=prefix):
|
||||||
ver = name.split('.')[1]
|
stix_vid = name.split('.')[1]
|
||||||
if re.match(r'^stix2\.v2[0-9]$', name) and is_pkg:
|
if re.match(r'^stix2\.v2[0-9]$', name) and is_pkg:
|
||||||
|
ver = _stix_vid_to_version(stix_vid)
|
||||||
mod = importlib.import_module(name, str(top_level_module.__name__))
|
mod = importlib.import_module(name, str(top_level_module.__name__))
|
||||||
STIX2_OBJ_MAPS[ver] = {}
|
STIX2_OBJ_MAPS[ver] = {}
|
||||||
STIX2_OBJ_MAPS[ver]['objects'] = mod.OBJ_MAP
|
STIX2_OBJ_MAPS[ver]['objects'] = mod.OBJ_MAP
|
||||||
STIX2_OBJ_MAPS[ver]['observables'] = mod.OBJ_MAP_OBSERVABLE
|
STIX2_OBJ_MAPS[ver]['observables'] = mod.OBJ_MAP_OBSERVABLE
|
||||||
STIX2_OBJ_MAPS[ver]['observable-extensions'] = mod.EXT_MAP
|
STIX2_OBJ_MAPS[ver]['observable-extensions'] = mod.EXT_MAP
|
||||||
elif re.match(r'^stix2\.v2[0-9]\.common$', name) and is_pkg is False:
|
elif re.match(r'^stix2\.v2[0-9]\.common$', name) and is_pkg is False:
|
||||||
|
ver = _stix_vid_to_version(stix_vid)
|
||||||
mod = importlib.import_module(name, str(top_level_module.__name__))
|
mod = importlib.import_module(name, str(top_level_module.__name__))
|
||||||
STIX2_OBJ_MAPS[ver]['markings'] = mod.OBJ_MAP_MARKING
|
STIX2_OBJ_MAPS[ver]['markings'] = mod.OBJ_MAP_MARKING
|
||||||
|
|
||||||
|
@ -37,7 +53,6 @@ def get_stix2_class_maps(stix_version):
|
||||||
category name, e.g. "object" to another mapping from STIX type
|
category name, e.g. "object" to another mapping from STIX type
|
||||||
to a stix2 class.
|
to a stix2 class.
|
||||||
"""
|
"""
|
||||||
stix_vid = "v" + stix_version.replace(".", "")
|
cls_maps = STIX2_OBJ_MAPS[stix_version]
|
||||||
cls_maps = STIX2_OBJ_MAPS[stix_vid]
|
|
||||||
|
|
||||||
return cls_maps
|
return cls_maps
|
||||||
|
|
|
@ -17,7 +17,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
"name": "alice",
|
"name": "alice",
|
||||||
"identity_class": "individual",
|
"identity_class": "individual",
|
||||||
},
|
},
|
||||||
"v20",
|
"2.0",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -29,14 +29,14 @@ from stix2.parsing import _detect_spec_version
|
||||||
"target_ref": "identity--ba18dde2-56d3-4a34-aa0b-fc56f5be568f",
|
"target_ref": "identity--ba18dde2-56d3-4a34-aa0b-fc56f5be568f",
|
||||||
"relationship_type": "targets",
|
"relationship_type": "targets",
|
||||||
},
|
},
|
||||||
"v20",
|
"2.0",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"name": "notes.txt",
|
"name": "notes.txt",
|
||||||
},
|
},
|
||||||
"v20",
|
"2.0",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
"statement": "Copyright (c) ACME Corp.",
|
"statement": "Copyright (c) ACME Corp.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"v20",
|
"2.0",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -75,7 +75,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"v20",
|
"2.0",
|
||||||
),
|
),
|
||||||
# STIX 2.1 examples
|
# STIX 2.1 examples
|
||||||
(
|
(
|
||||||
|
@ -87,7 +87,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
"modified": "2001-07-01T09:33:17.000Z",
|
"modified": "2001-07-01T09:33:17.000Z",
|
||||||
"name": "alice",
|
"name": "alice",
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
"target_ref": "identity--ba18dde2-56d3-4a34-aa0b-fc56f5be568f",
|
"target_ref": "identity--ba18dde2-56d3-4a34-aa0b-fc56f5be568f",
|
||||||
"relationship_type": "targets",
|
"relationship_type": "targets",
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -109,7 +109,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
"spec_version": "2.1",
|
"spec_version": "2.1",
|
||||||
"name": "notes.txt",
|
"name": "notes.txt",
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -117,7 +117,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
"id": "file--5eef3404-6a94-4db3-9a1a-5684cbea0dfe",
|
"id": "file--5eef3404-6a94-4db3-9a1a-5684cbea0dfe",
|
||||||
"name": "notes.txt",
|
"name": "notes.txt",
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
"tlp": "green",
|
"tlp": "green",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -153,7 +153,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
# Mixed spec examples
|
# Mixed spec examples
|
||||||
(
|
(
|
||||||
|
@ -180,7 +180,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -202,7 +202,7 @@ from stix2.parsing import _detect_spec_version
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"v21",
|
"2.1",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
@ -1044,9 +1044,8 @@ def test_register_custom_object_with_version():
|
||||||
}
|
}
|
||||||
|
|
||||||
cust_obj_1 = stix2.parsing.dict_to_stix2(custom_obj_1, version='2.0')
|
cust_obj_1 = stix2.parsing.dict_to_stix2(custom_obj_1, version='2.0')
|
||||||
v = 'v20'
|
|
||||||
|
|
||||||
assert cust_obj_1.type in stix2.registry.STIX2_OBJ_MAPS[v]['objects']
|
assert cust_obj_1.type in stix2.registry.STIX2_OBJ_MAPS['2.0']['objects']
|
||||||
# spec_version is not in STIX 2.0, and is required in 2.1, so this
|
# spec_version is not in STIX 2.0, and is required in 2.1, so this
|
||||||
# suffices as a test for a STIX 2.0 object.
|
# suffices as a test for a STIX 2.0 object.
|
||||||
assert "spec_version" not in cust_obj_1
|
assert "spec_version" not in cust_obj_1
|
||||||
|
@ -1076,9 +1075,8 @@ class NewObservable2(object):
|
||||||
|
|
||||||
def test_register_observable_with_version():
|
def test_register_observable_with_version():
|
||||||
custom_obs = NewObservable2(property1="Test Observable")
|
custom_obs = NewObservable2(property1="Test Observable")
|
||||||
v = 'v20'
|
|
||||||
|
|
||||||
assert custom_obs.type in stix2.registry.STIX2_OBJ_MAPS[v]['observables']
|
assert custom_obs.type in stix2.registry.STIX2_OBJ_MAPS['2.0']['observables']
|
||||||
|
|
||||||
|
|
||||||
def test_register_duplicate_observable_with_version():
|
def test_register_duplicate_observable_with_version():
|
||||||
|
@ -1101,10 +1099,9 @@ def test_register_marking_with_version():
|
||||||
)
|
)
|
||||||
class NewObj2():
|
class NewObj2():
|
||||||
pass
|
pass
|
||||||
v = 'v20'
|
|
||||||
|
|
||||||
no = NewObj2(property1='something')
|
no = NewObj2(property1='something')
|
||||||
assert no._type in stix2.registry.STIX2_OBJ_MAPS[v]['markings']
|
assert no._type in stix2.registry.STIX2_OBJ_MAPS['2.0']['markings']
|
||||||
|
|
||||||
|
|
||||||
def test_register_observable_extension_with_version():
|
def test_register_observable_extension_with_version():
|
||||||
|
@ -1116,10 +1113,9 @@ def test_register_observable_extension_with_version():
|
||||||
class SomeCustomExtension2:
|
class SomeCustomExtension2:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
v = 'v20'
|
|
||||||
example = SomeCustomExtension2(keys='test123')
|
example = SomeCustomExtension2(keys='test123')
|
||||||
|
|
||||||
assert example._type in stix2.registry.STIX2_OBJ_MAPS[v]['observable-extensions']['user-account']
|
assert example._type in stix2.registry.STIX2_OBJ_MAPS['2.0']['observable-extensions']['user-account']
|
||||||
|
|
||||||
|
|
||||||
def test_register_duplicate_observable_extension():
|
def test_register_duplicate_observable_extension():
|
||||||
|
|
|
@ -73,7 +73,6 @@ def test_register_marking_with_version():
|
||||||
_properties = OrderedDict()
|
_properties = OrderedDict()
|
||||||
|
|
||||||
registration._register_marking(NewMarking1, version='2.0')
|
registration._register_marking(NewMarking1, version='2.0')
|
||||||
v = 'v20'
|
|
||||||
|
|
||||||
assert NewMarking1._type in registry.STIX2_OBJ_MAPS[v]['markings']
|
assert NewMarking1._type in registry.STIX2_OBJ_MAPS['2.0']['markings']
|
||||||
assert v in str(registry.STIX2_OBJ_MAPS[v]['markings'][NewMarking1._type])
|
assert 'v20' in str(registry.STIX2_OBJ_MAPS['2.0']['markings'][NewMarking1._type])
|
||||||
|
|
|
@ -1265,9 +1265,8 @@ def test_register_custom_object_with_version():
|
||||||
}
|
}
|
||||||
|
|
||||||
cust_obj_1 = stix2.parsing.dict_to_stix2(custom_obj_1, version='2.1')
|
cust_obj_1 = stix2.parsing.dict_to_stix2(custom_obj_1, version='2.1')
|
||||||
v = 'v21'
|
|
||||||
|
|
||||||
assert cust_obj_1.type in stix2.registry.STIX2_OBJ_MAPS[v]['objects']
|
assert cust_obj_1.type in stix2.registry.STIX2_OBJ_MAPS['2.1']['objects']
|
||||||
assert cust_obj_1.spec_version == "2.1"
|
assert cust_obj_1.spec_version == "2.1"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1295,9 +1294,8 @@ class NewObservable3(object):
|
||||||
|
|
||||||
def test_register_observable():
|
def test_register_observable():
|
||||||
custom_obs = NewObservable3(property1="Test Observable")
|
custom_obs = NewObservable3(property1="Test Observable")
|
||||||
v = 'v21'
|
|
||||||
|
|
||||||
assert custom_obs.type in stix2.registry.STIX2_OBJ_MAPS[v]['observables']
|
assert custom_obs.type in stix2.registry.STIX2_OBJ_MAPS['2.1']['observables']
|
||||||
|
|
||||||
|
|
||||||
def test_register_duplicate_observable():
|
def test_register_duplicate_observable():
|
||||||
|
@ -1323,10 +1321,9 @@ def test_register_observable_custom_extension():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
example = NewExtension2(property1="Hi there")
|
example = NewExtension2(property1="Hi there")
|
||||||
v = 'v21'
|
|
||||||
|
|
||||||
assert 'domain-name' in stix2.registry.STIX2_OBJ_MAPS[v]['observables']
|
assert 'domain-name' in stix2.registry.STIX2_OBJ_MAPS['2.1']['observables']
|
||||||
assert example._type in stix2.registry.STIX2_OBJ_MAPS[v]['observable-extensions']['domain-name']
|
assert example._type in stix2.registry.STIX2_OBJ_MAPS['2.1']['observable-extensions']['domain-name']
|
||||||
|
|
||||||
|
|
||||||
def test_register_duplicate_observable_extension():
|
def test_register_duplicate_observable_extension():
|
||||||
|
|
|
@ -78,10 +78,9 @@ def test_register_marking_with_version():
|
||||||
_properties = OrderedDict()
|
_properties = OrderedDict()
|
||||||
|
|
||||||
registration._register_marking(NewMarking1, version='2.1')
|
registration._register_marking(NewMarking1, version='2.1')
|
||||||
v = 'v21'
|
|
||||||
|
|
||||||
assert NewMarking1._type in registry.STIX2_OBJ_MAPS[v]['markings']
|
assert NewMarking1._type in registry.STIX2_OBJ_MAPS['2.1']['markings']
|
||||||
assert v in str(registry.STIX2_OBJ_MAPS[v]['markings'][NewMarking1._type])
|
assert 'v21' in str(registry.STIX2_OBJ_MAPS['2.1']['markings'][NewMarking1._type])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(reason="The default version is not 2.1", condition=DEFAULT_VERSION != "2.1")
|
@pytest.mark.xfail(reason="The default version is not 2.1", condition=DEFAULT_VERSION != "2.1")
|
||||||
|
@ -92,7 +91,6 @@ def test_register_marking_with_no_version():
|
||||||
_properties = OrderedDict()
|
_properties = OrderedDict()
|
||||||
|
|
||||||
registration._register_marking(NewMarking2)
|
registration._register_marking(NewMarking2)
|
||||||
v = 'v21'
|
|
||||||
|
|
||||||
assert NewMarking2._type in registry.STIX2_OBJ_MAPS[v]['markings']
|
assert NewMarking2._type in registry.STIX2_OBJ_MAPS['2.1']['markings']
|
||||||
assert v in str(registry.STIX2_OBJ_MAPS[v]['markings'][NewMarking2._type])
|
assert 'v21' in str(registry.STIX2_OBJ_MAPS['2.1']['markings'][NewMarking2._type])
|
||||||
|
|
|
@ -75,7 +75,7 @@ def _is_versionable(data):
|
||||||
|
|
||||||
is_versionable = False
|
is_versionable = False
|
||||||
is_21 = False
|
is_21 = False
|
||||||
stix_vid = None
|
stix_version = None
|
||||||
|
|
||||||
if isinstance(data, Mapping):
|
if isinstance(data, Mapping):
|
||||||
|
|
||||||
|
@ -87,8 +87,8 @@ def _is_versionable(data):
|
||||||
# (is_21 means 2.1 or later; try not to be 2.1-specific)
|
# (is_21 means 2.1 or later; try not to be 2.1-specific)
|
||||||
is_21 = True
|
is_21 = True
|
||||||
elif isinstance(data, dict):
|
elif isinstance(data, dict):
|
||||||
stix_vid = stix2.parsing._detect_spec_version(data)
|
stix_version = stix2.parsing._detect_spec_version(data)
|
||||||
is_21 = stix_vid != "v20"
|
is_21 = stix_version != "2.0"
|
||||||
|
|
||||||
# Then, determine versionability.
|
# Then, determine versionability.
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ def _is_versionable(data):
|
||||||
# registered class, and from that get a more complete picture of its
|
# registered class, and from that get a more complete picture of its
|
||||||
# properties.
|
# properties.
|
||||||
elif isinstance(data, dict):
|
elif isinstance(data, dict):
|
||||||
class_maps = stix2.registry.STIX2_OBJ_MAPS[stix_vid]
|
class_maps = stix2.registry.STIX2_OBJ_MAPS[stix_version]
|
||||||
obj_type = data["type"]
|
obj_type = data["type"]
|
||||||
|
|
||||||
if obj_type in class_maps["objects"]:
|
if obj_type in class_maps["objects"]:
|
||||||
|
|
Loading…
Reference in New Issue