Move TypeProperty format checks to __init__
TypeProperty uses a fixed value, so check() was never called. This way also runs the check at object registration time because the wrapper creates an instance of TypeProperty and doesn't have to wait for the object to be instantiated so clean() can be called. Also fix some tests.master
parent
03cb225932
commit
13cddf9d6d
|
@ -200,6 +200,11 @@ def _register_object(new_type, version=None):
|
|||
version (str): Which STIX2 version to use. (e.g. "2.0", "2.1"). If
|
||||
None, use latest version.
|
||||
|
||||
Raises:
|
||||
ValueError: If the class being registered wasn't created with the
|
||||
@CustomObject decorator.
|
||||
DuplicateRegistrationError: If the class has already been registered.
|
||||
|
||||
"""
|
||||
|
||||
if not issubclass(new_type, _DomainObject):
|
||||
|
@ -208,8 +213,6 @@ def _register_object(new_type, version=None):
|
|||
new_type.__name__,
|
||||
)
|
||||
|
||||
new_type._properties['type'].clean(new_type._type)
|
||||
|
||||
if version:
|
||||
v = 'v' + version.replace('.', '')
|
||||
else:
|
||||
|
@ -232,8 +235,11 @@ def _register_marking(new_marking, version=None):
|
|||
|
||||
"""
|
||||
|
||||
mark_type = new_marking._type
|
||||
properties = new_marking._properties
|
||||
|
||||
stix2.properties._validate_type(mark_type, version)
|
||||
|
||||
if version == "2.1":
|
||||
for prop_name, prop_value in properties.items():
|
||||
if not re.match(PREFIX_21_REGEX, prop_name):
|
||||
|
@ -246,9 +252,9 @@ def _register_marking(new_marking, version=None):
|
|||
v = 'v' + stix2.DEFAULT_VERSION.replace('.', '')
|
||||
|
||||
OBJ_MAP_MARKING = STIX2_OBJ_MAPS[v]['markings']
|
||||
if new_marking._type in OBJ_MAP_MARKING.keys():
|
||||
raise DuplicateRegistrationError("STIX Marking", new_marking._type)
|
||||
OBJ_MAP_MARKING[new_marking._type] = new_marking
|
||||
if mark_type in OBJ_MAP_MARKING.keys():
|
||||
raise DuplicateRegistrationError("STIX Marking", mark_type)
|
||||
OBJ_MAP_MARKING[mark_type] = new_marking
|
||||
|
||||
|
||||
def _register_observable(new_observable, version=None):
|
||||
|
@ -261,8 +267,6 @@ def _register_observable(new_observable, version=None):
|
|||
|
||||
"""
|
||||
|
||||
new_observable._properties['type'].clean(new_observable._type)
|
||||
|
||||
if version:
|
||||
v = 'v' + version.replace('.', '')
|
||||
else:
|
||||
|
@ -296,8 +300,7 @@ def _register_observable_extension(
|
|||
if not issubclass(obs_class, _Observable):
|
||||
raise ValueError("'observable' must be a valid Observable class!")
|
||||
|
||||
temp_prop = stix2.properties.TypeProperty(ext_type, spec_version=version)
|
||||
temp_prop.clean(ext_type)
|
||||
stix2.properties._validate_type(ext_type, version)
|
||||
|
||||
if not new_extension._properties:
|
||||
raise ValueError(
|
||||
|
|
|
@ -84,6 +84,36 @@ def _validate_id(id_, spec_version, required_prefix):
|
|||
raise ValueError(ERROR_INVALID_ID.format(id_))
|
||||
|
||||
|
||||
def _validate_type(type_, spec_version):
|
||||
"""
|
||||
Check the STIX type name for correctness, raise an exception if there are
|
||||
errors.
|
||||
|
||||
:param type_: The STIX type name
|
||||
:param spec_version: The STIX specification version to use
|
||||
:raises ValueError: If there are any errors with the identifier
|
||||
"""
|
||||
if spec_version == "2.0":
|
||||
if not re.match(TYPE_REGEX, type_):
|
||||
raise ValueError(
|
||||
"Invalid type name '%s': must only contain the "
|
||||
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." %
|
||||
type_,
|
||||
)
|
||||
else: # 2.1+
|
||||
if not re.match(TYPE_21_REGEX, type_):
|
||||
raise ValueError(
|
||||
"Invalid type name '%s': must only contain the "
|
||||
"characters a-z (lowercase ASCII), 0-9, and hyphen (-) "
|
||||
"and must begin with an a-z character" % type_,
|
||||
)
|
||||
|
||||
if len(type_) < 3 or len(type_) > 250:
|
||||
raise ValueError(
|
||||
"Invalid type name '%s': must be between 3 and 250 characters." % type_,
|
||||
)
|
||||
|
||||
|
||||
class Property(object):
|
||||
"""Represent a property of STIX data type.
|
||||
|
||||
|
@ -236,32 +266,10 @@ class StringProperty(Property):
|
|||
class TypeProperty(Property):
|
||||
|
||||
def __init__(self, type, spec_version=stix2.DEFAULT_VERSION):
|
||||
_validate_type(type, spec_version)
|
||||
self.spec_version = spec_version
|
||||
super(TypeProperty, self).__init__(fixed=type)
|
||||
|
||||
def clean(self, value):
|
||||
if self.spec_version == "2.0":
|
||||
if not re.match(TYPE_REGEX, type):
|
||||
raise ValueError(
|
||||
"Invalid type name '%s': must only contain the "
|
||||
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." %
|
||||
type,
|
||||
)
|
||||
else: # 2.1+
|
||||
if not re.match(TYPE_21_REGEX, type):
|
||||
raise ValueError(
|
||||
"Invalid type name '%s': must only contain the "
|
||||
"characters a-z (lowercase ASCII), 0-9, and hyphen (-) "
|
||||
"and must begin with an a-z character" % type,
|
||||
)
|
||||
|
||||
if len(type) < 3 or len(type) > 250:
|
||||
raise ValueError(
|
||||
"Invalid type name '%s': must be between 3 and 250 characters." % type,
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class IDProperty(Property):
|
||||
|
||||
|
|
|
@ -483,7 +483,7 @@ def test_custom_observable_object_invalid_type_name():
|
|||
)
|
||||
class NewObs(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid observable type name 'x':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v20.CustomObservable(
|
||||
|
@ -493,7 +493,7 @@ def test_custom_observable_object_invalid_type_name():
|
|||
)
|
||||
class NewObs2(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid observable type name 'x_new_obs':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x_new_obs':" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_custom_observable_object_invalid_ref_property():
|
||||
|
@ -808,7 +808,7 @@ def test_custom_extension_invalid_type_name():
|
|||
)
|
||||
class FooExtension():
|
||||
pass # pragma: no cover
|
||||
assert "Invalid extension type name 'x':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v20.CustomExtension(
|
||||
|
@ -818,7 +818,7 @@ def test_custom_extension_invalid_type_name():
|
|||
)
|
||||
class BlaExtension():
|
||||
pass # pragma: no cover
|
||||
assert "Invalid extension type name 'x_new_ext':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x_new_ext':" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_custom_extension_no_properties():
|
||||
|
@ -968,9 +968,8 @@ def test_register_custom_object():
|
|||
class CustomObject2(object):
|
||||
_type = 'awesome-object'
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
stix2.parsing._register_object(CustomObject2, version="2.0")
|
||||
# Note that we will always check against newest OBJ_MAP.
|
||||
assert (CustomObject2._type, CustomObject2) in stix2.v20.OBJ_MAP.items()
|
||||
|
||||
|
||||
def test_extension_property_location():
|
||||
|
|
|
@ -375,7 +375,7 @@ def test_custom_marking_invalid_type_name():
|
|||
)
|
||||
class NewObj(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid marking type name 'x': " in str(excinfo.value)
|
||||
assert "Invalid type name 'x': " in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v21.CustomMarking(
|
||||
|
@ -385,7 +385,7 @@ def test_custom_marking_invalid_type_name():
|
|||
)
|
||||
class NewObj2(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid marking type name 'x_new_marking':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x_new_marking':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v21.CustomMarking(
|
||||
|
@ -395,7 +395,7 @@ def test_custom_marking_invalid_type_name():
|
|||
)
|
||||
class NewObj3(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid marking type name '7x-new-marking':" in str(excinfo.value)
|
||||
assert "Invalid type name '7x-new-marking':" in str(excinfo.value)
|
||||
|
||||
# Custom Objects
|
||||
|
||||
|
@ -619,7 +619,7 @@ def test_custom_observable_object_invalid_type_name():
|
|||
)
|
||||
class NewObs(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid observable type name 'x':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v21.CustomObservable(
|
||||
|
@ -629,7 +629,7 @@ def test_custom_observable_object_invalid_type_name():
|
|||
)
|
||||
class NewObs2(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid observable type name 'x_new_obs':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x_new_obs':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v21.CustomObservable(
|
||||
|
@ -639,7 +639,7 @@ def test_custom_observable_object_invalid_type_name():
|
|||
)
|
||||
class NewObs3(object):
|
||||
pass # pragma: no cover
|
||||
assert "Invalid observable type name '7x-new-obs':" in str(excinfo.value)
|
||||
assert "Invalid type name '7x-new-obs':" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_custom_observable_object_invalid_ref_property():
|
||||
|
@ -1005,7 +1005,7 @@ def test_custom_extension_invalid_type_name():
|
|||
)
|
||||
class FooExtension():
|
||||
pass # pragma: no cover
|
||||
assert "Invalid extension type name 'x':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v21.CustomExtension(
|
||||
|
@ -1015,7 +1015,7 @@ def test_custom_extension_invalid_type_name():
|
|||
)
|
||||
class BlaExtension():
|
||||
pass # pragma: no cover
|
||||
assert "Invalid extension type name 'x_new_ext':" in str(excinfo.value)
|
||||
assert "Invalid type name 'x_new_ext':" in str(excinfo.value)
|
||||
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
@stix2.v21.CustomExtension(
|
||||
|
@ -1025,7 +1025,7 @@ def test_custom_extension_invalid_type_name():
|
|||
)
|
||||
class Bla2Extension():
|
||||
pass # pragma: no cover
|
||||
assert "Invalid extension type name '7x-new-ext':" in str(excinfo.value)
|
||||
assert "Invalid type name '7x-new-ext':" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_custom_extension_no_properties():
|
||||
|
|
Loading…
Reference in New Issue