Factored out more of the STIX identifier validity checking,
partly inspired by PR #263. This resulted in some error message format changes (an improvement, I think), which caused some unit test breakage. Removed those asserts from the unit tests, since tests shouldn't be testing human-targeted error messages.master
parent
ed106f23ff
commit
da5978d317
|
@ -41,6 +41,38 @@ def _check_uuid(uuid_str, spec_version):
|
|||
return ok
|
||||
|
||||
|
||||
def _validate_id(id_, spec_version, required_prefix):
|
||||
"""
|
||||
Check the STIX identifier for correctness, raise an exception if there are
|
||||
errors.
|
||||
|
||||
:param id_: The STIX identifier
|
||||
:param spec_version: The STIX specification version to use
|
||||
:param required_prefix: The required prefix on the identifier, if any.
|
||||
This function doesn't add a "--" suffix to the prefix, so callers must
|
||||
add it if it is important. Pass None to skip the prefix check.
|
||||
:raises ValueError: If there are any errors with the identifier
|
||||
"""
|
||||
if required_prefix:
|
||||
if not id_.startswith(required_prefix):
|
||||
raise ValueError("must start with '{}'.".format(required_prefix))
|
||||
|
||||
try:
|
||||
if required_prefix:
|
||||
uuid_part = id_[len(required_prefix):]
|
||||
else:
|
||||
idx = id_.index("--")
|
||||
uuid_part = id_[idx+2:]
|
||||
|
||||
result = _check_uuid(uuid_part, spec_version)
|
||||
except ValueError:
|
||||
# replace their ValueError with ours
|
||||
raise ValueError(ERROR_INVALID_ID.format(id_))
|
||||
|
||||
if not result:
|
||||
raise ValueError(ERROR_INVALID_ID.format(id_))
|
||||
|
||||
|
||||
class Property(object):
|
||||
"""Represent a property of STIX data type.
|
||||
|
||||
|
@ -198,19 +230,7 @@ class IDProperty(Property):
|
|||
super(IDProperty, self).__init__()
|
||||
|
||||
def clean(self, value):
|
||||
if not value.startswith(self.required_prefix):
|
||||
raise ValueError("must start with '{}'.".format(self.required_prefix))
|
||||
|
||||
uuid_part = value[len(self.required_prefix):]
|
||||
try:
|
||||
result = _check_uuid(uuid_part, self.spec_version)
|
||||
except ValueError:
|
||||
# replace their ValueError with ours
|
||||
raise ValueError(ERROR_INVALID_ID.format(value))
|
||||
|
||||
if not result:
|
||||
raise ValueError(ERROR_INVALID_ID.format(value))
|
||||
|
||||
_validate_id(value, self.spec_version, self.required_prefix)
|
||||
return value
|
||||
|
||||
def default(self):
|
||||
|
@ -396,26 +416,7 @@ class ReferenceProperty(Property):
|
|||
value = value.id
|
||||
value = str(value)
|
||||
|
||||
if self.required_prefix:
|
||||
if not value.startswith(self.required_prefix):
|
||||
raise ValueError(
|
||||
"must start with '{}'.".format(self.required_prefix),
|
||||
)
|
||||
|
||||
try:
|
||||
if self.required_prefix:
|
||||
uuid_part = value[len(self.required_prefix):]
|
||||
else:
|
||||
idx = value.index("--")
|
||||
uuid_part = value[idx+2:]
|
||||
|
||||
result = _check_uuid(uuid_part, self.spec_version)
|
||||
except ValueError:
|
||||
# replace their ValueError with ours
|
||||
raise ValueError(ERROR_INVALID_ID.format(value))
|
||||
|
||||
if not result:
|
||||
raise ValueError(ERROR_INVALID_ID.format(value))
|
||||
_validate_id(value, self.spec_version, self.required_prefix)
|
||||
|
||||
return value
|
||||
|
||||
|
|
|
@ -112,8 +112,6 @@ def test_indicator_created_ref_invalid_format():
|
|||
|
||||
assert excinfo.value.cls == stix2.v20.Indicator
|
||||
assert excinfo.value.prop_name == "created_by_ref"
|
||||
assert excinfo.value.reason == "must start with 'identity'."
|
||||
assert str(excinfo.value) == "Invalid value for Indicator 'created_by_ref': must start with 'identity'."
|
||||
|
||||
|
||||
def test_indicator_revoked_invalid():
|
||||
|
|
|
@ -87,8 +87,6 @@ def test_report_example_objects_in_object_refs_with_bad_id():
|
|||
|
||||
assert excinfo.value.cls == stix2.v20.Report
|
||||
assert excinfo.value.prop_name == "object_refs"
|
||||
assert excinfo.value.reason == stix2.properties.ERROR_INVALID_ID
|
||||
assert str(excinfo.value) == "Invalid value for Report 'object_refs': " + stix2.properties.ERROR_INVALID_ID
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -59,8 +59,6 @@ def test_sighting_bad_where_sighted_refs():
|
|||
|
||||
assert excinfo.value.cls == stix2.v20.Sighting
|
||||
assert excinfo.value.prop_name == "where_sighted_refs"
|
||||
assert excinfo.value.reason == "must start with 'identity'."
|
||||
assert str(excinfo.value) == "Invalid value for Sighting 'where_sighted_refs': must start with 'identity'."
|
||||
|
||||
|
||||
def test_sighting_type_must_be_sightings():
|
||||
|
@ -69,8 +67,6 @@ def test_sighting_type_must_be_sightings():
|
|||
|
||||
assert excinfo.value.cls == stix2.v20.Sighting
|
||||
assert excinfo.value.prop_name == "type"
|
||||
assert excinfo.value.reason == "must equal 'sighting'."
|
||||
assert str(excinfo.value) == "Invalid value for Sighting 'type': must equal 'sighting'."
|
||||
|
||||
|
||||
def test_invalid_kwarg_to_sighting():
|
||||
|
|
|
@ -116,8 +116,6 @@ def test_indicator_created_ref_invalid_format():
|
|||
|
||||
assert excinfo.value.cls == stix2.v21.Indicator
|
||||
assert excinfo.value.prop_name == "created_by_ref"
|
||||
assert excinfo.value.reason == "must start with 'identity'."
|
||||
assert str(excinfo.value) == "Invalid value for Indicator 'created_by_ref': must start with 'identity'."
|
||||
|
||||
|
||||
def test_indicator_revoked_invalid():
|
||||
|
|
|
@ -88,8 +88,6 @@ def test_report_example_objects_in_object_refs_with_bad_id():
|
|||
|
||||
assert excinfo.value.cls == stix2.v21.Report
|
||||
assert excinfo.value.prop_name == "object_refs"
|
||||
assert excinfo.value.reason == stix2.properties.ERROR_INVALID_ID
|
||||
assert str(excinfo.value) == "Invalid value for Report 'object_refs': " + stix2.properties.ERROR_INVALID_ID
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
@ -61,8 +61,6 @@ def test_sighting_bad_where_sighted_refs():
|
|||
|
||||
assert excinfo.value.cls == stix2.v21.Sighting
|
||||
assert excinfo.value.prop_name == "where_sighted_refs"
|
||||
assert excinfo.value.reason == "must start with 'identity'."
|
||||
assert str(excinfo.value) == "Invalid value for Sighting 'where_sighted_refs': must start with 'identity'."
|
||||
|
||||
|
||||
def test_sighting_type_must_be_sightings():
|
||||
|
|
Loading…
Reference in New Issue