Add support in ReferenceProperty for hybrid object type
constraints (i.e. both generic type categories and specific types). Also: - more expansion/refinement of reference property unit tests - bugfix: SROs are in OBJ_MAP too, it's not just SDOs! Oops... - pre-commit stylistic fixespull/1/head
parent
986404b7b7
commit
414694d8fa
|
@ -8,10 +8,7 @@ import re
|
|||
import uuid
|
||||
|
||||
from .base import _STIXBase
|
||||
from .exceptions import (
|
||||
CustomContentError, DictionaryKeyError, MissingPropertiesError,
|
||||
MutuallyExclusivePropertiesError, STIXError,
|
||||
)
|
||||
from .exceptions import CustomContentError, DictionaryKeyError, STIXError
|
||||
from .parsing import parse, parse_observable
|
||||
from .registry import STIX2_OBJ_MAPS
|
||||
from .utils import _get_dict, get_class_hierarchy_names, parse_into_datetime
|
||||
|
@ -503,7 +500,7 @@ class ReferenceProperty(Property):
|
|||
(valid_types is None and invalid_types is None):
|
||||
raise ValueError(
|
||||
"Exactly one of 'valid_types' and 'invalid_types' must be "
|
||||
"given"
|
||||
"given",
|
||||
)
|
||||
|
||||
if valid_types and not isinstance(valid_types, list):
|
||||
|
@ -517,21 +514,6 @@ class ReferenceProperty(Property):
|
|||
self.types = set(valid_types or invalid_types)
|
||||
self.auth_type = self._WHITELIST if valid_types else self._BLACKLIST
|
||||
|
||||
# Handling both generic and non-generic types in the same constraint
|
||||
# complicates life... let's keep it simple unless we really need the
|
||||
# complexity.
|
||||
self.generic_constraint = any(
|
||||
t in self._OBJECT_CATEGORIES for t in self.types
|
||||
)
|
||||
|
||||
if self.generic_constraint and any(
|
||||
t not in self._OBJECT_CATEGORIES for t in self.types
|
||||
):
|
||||
raise ValueError(
|
||||
"Generic type categories and specific types may not both be "
|
||||
"given"
|
||||
)
|
||||
|
||||
super(ReferenceProperty, self).__init__(**kwargs)
|
||||
|
||||
def clean(self, value, allow_custom):
|
||||
|
@ -543,10 +525,19 @@ class ReferenceProperty(Property):
|
|||
|
||||
obj_type = value[:value.index('--')]
|
||||
|
||||
types = self.types
|
||||
# Only comes into play when inverting a hybrid whitelist.
|
||||
# E.g. if the possible generic categories are A, B, C, then the
|
||||
# inversion of whitelist constraint "A or x" (where x is a specific
|
||||
# type) is something like "[not (B or C)] or x". In other words, we
|
||||
# invert the generic categories to produce a blacklist, but leave the
|
||||
# specific categories alone; they essentially become exceptions to our
|
||||
# blacklist.
|
||||
blacklist_exceptions = set()
|
||||
|
||||
generics = self.types & self._OBJECT_CATEGORIES
|
||||
specifics = self.types - generics
|
||||
auth_type = self.auth_type
|
||||
if allow_custom and auth_type == self._WHITELIST and \
|
||||
self.generic_constraint:
|
||||
if allow_custom and auth_type == self._WHITELIST and generics:
|
||||
# If allowing customization and using a whitelist, and if generic
|
||||
# "category" types were given, we need to allow custom object types
|
||||
# of those categories. Unless registered, it's impossible to know
|
||||
|
@ -554,60 +545,40 @@ class ReferenceProperty(Property):
|
|||
# permissive approach and allow any type which is not known to be
|
||||
# in the wrong category. I.e. flip the whitelist set to a
|
||||
# blacklist of a complementary set.
|
||||
types = self._OBJECT_CATEGORIES - types
|
||||
auth_type = self._BLACKLIST
|
||||
generics = self._OBJECT_CATEGORIES - generics
|
||||
blacklist_exceptions, specifics = specifics, blacklist_exceptions
|
||||
|
||||
if auth_type == self._WHITELIST:
|
||||
# allow_custom is not applicable to "whitelist" style object type
|
||||
# constraints, so we ignore it.
|
||||
has_custom = False
|
||||
|
||||
if self.generic_constraint:
|
||||
type_ok = _type_in_generic_set(
|
||||
obj_type, types, self.spec_version
|
||||
)
|
||||
else:
|
||||
type_ok = obj_type in types
|
||||
|
||||
if not type_ok:
|
||||
raise ValueError(
|
||||
"The type-specifying prefix '%s' for this property is not "
|
||||
"valid" % obj_type
|
||||
)
|
||||
type_ok = _type_in_generic_set(
|
||||
obj_type, generics, self.spec_version
|
||||
) or obj_type in specifics
|
||||
|
||||
else:
|
||||
# A type "blacklist" was used to describe legal object types. We
|
||||
# must enforce the type blacklist regardless of allow_custom.
|
||||
if self.generic_constraint:
|
||||
type_ok = not _type_in_generic_set(
|
||||
obj_type, types, self.spec_version
|
||||
type_ok = (
|
||||
not _type_in_generic_set(
|
||||
obj_type, generics, self.spec_version,
|
||||
)
|
||||
else:
|
||||
type_ok = obj_type not in types
|
||||
and obj_type not in specifics
|
||||
) or obj_type in blacklist_exceptions
|
||||
|
||||
if not type_ok:
|
||||
raise ValueError(
|
||||
"The type-specifying prefix '%s' for this property is not "
|
||||
"valid" % obj_type
|
||||
)
|
||||
if not type_ok:
|
||||
raise ValueError(
|
||||
"The type-specifying prefix '%s' for this property is not "
|
||||
"valid" % obj_type,
|
||||
)
|
||||
|
||||
# allow_custom=True only allows references to custom objects which
|
||||
# are not otherwise blacklisted. We need to figure out whether
|
||||
# the referenced object is custom or not. No good way to do that
|
||||
# at present... just check if unregistered and for the "x-" type
|
||||
# prefix, for now?
|
||||
type_maps = STIX2_OBJ_MAPS[self.spec_version]
|
||||
# We need to figure out whether the referenced object is custom or
|
||||
# not. No good way to do that at present... just check if
|
||||
# unregistered and for the "x-" type prefix, for now?
|
||||
has_custom = not _type_in_generic_set(
|
||||
obj_type, self._OBJECT_CATEGORIES, self.spec_version,
|
||||
) or obj_type.startswith("x-")
|
||||
|
||||
has_custom = obj_type not in type_maps["objects"] \
|
||||
and obj_type not in type_maps["observables"] \
|
||||
and obj_type not in ["relationship", "sighting"]
|
||||
|
||||
has_custom = has_custom or obj_type.startswith("x-")
|
||||
|
||||
if not allow_custom and has_custom:
|
||||
raise CustomContentError(
|
||||
"reference to custom object type: " + obj_type,
|
||||
)
|
||||
if not allow_custom and has_custom:
|
||||
raise CustomContentError(
|
||||
"reference to custom object type: " + obj_type,
|
||||
)
|
||||
|
||||
return value, has_custom
|
||||
|
||||
|
@ -624,7 +595,9 @@ def _type_in_generic_set(type_, type_set, spec_version):
|
|||
result = False
|
||||
for type_id in type_set:
|
||||
if type_id == "SDO":
|
||||
result = type_ in type_maps["objects"]
|
||||
result = type_ in type_maps["objects"] and type_ not in [
|
||||
"relationship", "sighting",
|
||||
] # sigh
|
||||
elif type_id == "SCO":
|
||||
result = type_ in type_maps["observables"]
|
||||
elif type_id == "SRO":
|
||||
|
|
|
@ -84,19 +84,21 @@ def test_id_property_default():
|
|||
assert ID_PROP.clean(default) == (default, False)
|
||||
|
||||
|
||||
def test_reference_property():
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.0")
|
||||
def test_reference_property_whitelist_standard_type():
|
||||
ref_prop = ReferenceProperty(valid_types="identity", spec_version="2.0")
|
||||
result = ref_prop.clean(
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
assert result == ("identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
assert ref_prop.clean("my-type--00000000-0000-4000-8000-000000000000", False)
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("foo", False)
|
||||
ref_prop.clean("foo--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
# This is not a valid V4 UUID
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("my-type--00000000-0000-0000-0000-000000000000", False)
|
||||
ref_prop.clean("foo--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
|
||||
def test_reference_property_whitelist_type():
|
||||
def test_reference_property_whitelist_custom_type():
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.0")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -105,16 +107,18 @@ def test_reference_property_whitelist_type():
|
|||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("not-my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
result = ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
with pytest.raises(CustomContentError):
|
||||
# This is the whitelisted type, but it's still custom, and
|
||||
# customization is disallowed here.
|
||||
ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
assert result == ("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
result = ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_whitelist_generic_type():
|
||||
ref_prop = ReferenceProperty(
|
||||
valid_types=["SCO", "SRO"], spec_version="2.0"
|
||||
valid_types=["SCO", "SRO"], spec_version="2.0",
|
||||
)
|
||||
|
||||
result = ref_prop.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
@ -124,12 +128,19 @@ def test_reference_property_whitelist_generic_type():
|
|||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False
|
||||
"sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
assert result == ("sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True
|
||||
"sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
assert result == ("sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
# The prop assumes some-type is a custom type of one of the generic
|
||||
# type categories.
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
assert result == ("some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
@ -143,7 +154,7 @@ def test_reference_property_whitelist_generic_type():
|
|||
ref_prop.clean("identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_blacklist_type():
|
||||
def test_reference_property_blacklist_standard_type():
|
||||
ref_prop = ReferenceProperty(invalid_types="identity", spec_version="2.0")
|
||||
result = ref_prop.clean(
|
||||
"malware--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
|
@ -155,6 +166,11 @@ def test_reference_property_blacklist_type():
|
|||
)
|
||||
assert result == ("malware--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
@ -170,15 +186,10 @@ def test_reference_property_blacklist_type():
|
|||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
|
||||
def test_reference_property_blacklist_generic_type():
|
||||
ref_prop = ReferenceProperty(
|
||||
invalid_types=["SDO", "SRO"], spec_version="2.0"
|
||||
invalid_types=["SDO", "SRO"], spec_version="2.0",
|
||||
)
|
||||
|
||||
result = ref_prop.clean(
|
||||
|
@ -191,16 +202,16 @@ def test_reference_property_blacklist_generic_type():
|
|||
)
|
||||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
assert result == ("some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
|
@ -208,7 +219,7 @@ def test_reference_property_blacklist_generic_type():
|
|||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"relationship--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -216,18 +227,57 @@ def test_reference_property_blacklist_generic_type():
|
|||
"relationship--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
"relationship--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
|
||||
def test_reference_property_hybrid_constraint_type():
|
||||
with pytest.raises(ValueError):
|
||||
ReferenceProperty(valid_types=["a", "SCO"], spec_version="2.0")
|
||||
def test_reference_property_whitelist_hybrid_type():
|
||||
p = ReferenceProperty(valid_types=["a", "SCO"], spec_version="2.0")
|
||||
|
||||
result = p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
# although whitelisted, "a" is a custom type
|
||||
p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ReferenceProperty(invalid_types=["a", "SCO"], spec_version="2.0")
|
||||
p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
# should just assume "b" is a custom SCO type.
|
||||
result = p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_blacklist_hybrid_type():
|
||||
p = ReferenceProperty(invalid_types=["a", "SCO"], spec_version="2.0")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
# should just assume "b" is a custom type which is not an SCO
|
||||
result = p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_impossible_constraint():
|
||||
|
|
|
@ -144,8 +144,8 @@ def test_report_on_custom():
|
|||
published="2016-01-20T17:00:00Z",
|
||||
object_refs=[
|
||||
"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7",
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7"
|
||||
]
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7",
|
||||
],
|
||||
)
|
||||
|
||||
report = stix2.v20.Report(
|
||||
|
@ -154,10 +154,10 @@ def test_report_on_custom():
|
|||
published="2016-01-20T17:00:00Z",
|
||||
object_refs=[
|
||||
"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7",
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7"
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7",
|
||||
],
|
||||
allow_custom=True,
|
||||
)
|
||||
|
||||
assert "some-type--2672975a-ce1e-4473-a1c6-0d79868930c7" \
|
||||
in report.object_refs
|
||||
in report.object_refs
|
||||
|
|
|
@ -91,7 +91,7 @@ def test_malware_analysis_custom_sco_refs():
|
|||
product="super scanner",
|
||||
analysis_sco_refs=[
|
||||
"file--6e8c78cf-4bcc-4729-9265-86a97bfc91ba",
|
||||
"some-object--f6bfc147-e844-4578-ae01-847979890239"
|
||||
"some-object--f6bfc147-e844-4578-ae01-847979890239",
|
||||
],
|
||||
allow_custom=True,
|
||||
)
|
||||
|
@ -105,8 +105,8 @@ def test_malware_analysis_custom_sco_refs():
|
|||
product="super scanner",
|
||||
analysis_sco_refs=[
|
||||
"file--6e8c78cf-4bcc-4729-9265-86a97bfc91ba",
|
||||
"some-object--f6bfc147-e844-4578-ae01-847979890239"
|
||||
]
|
||||
"some-object--f6bfc147-e844-4578-ae01-847979890239",
|
||||
],
|
||||
)
|
||||
|
||||
with pytest.raises(stix2.exceptions.InvalidValueError):
|
||||
|
@ -115,7 +115,7 @@ def test_malware_analysis_custom_sco_refs():
|
|||
analysis_sco_refs=[
|
||||
"file--6e8c78cf-4bcc-4729-9265-86a97bfc91ba",
|
||||
# standard object type; wrong category (not SCO)
|
||||
"identity--56977a19-49ef-49d7-b259-f733fa4b7bbc"
|
||||
"identity--56977a19-49ef-49d7-b259-f733fa4b7bbc",
|
||||
],
|
||||
allow_custom=True,
|
||||
)
|
||||
|
|
|
@ -8,7 +8,7 @@ from stix2.exceptions import (
|
|||
from stix2.properties import (
|
||||
DictionaryProperty, EmbeddedObjectProperty, ExtensionsProperty,
|
||||
HashesProperty, IDProperty, ListProperty, ObservableProperty,
|
||||
ReferenceProperty, STIXObjectProperty, StringProperty, TypeProperty,
|
||||
ReferenceProperty, STIXObjectProperty, StringProperty,
|
||||
)
|
||||
from stix2.v21.common import MarkingProperty
|
||||
|
||||
|
@ -87,19 +87,21 @@ def test_id_property_default():
|
|||
assert ID_PROP.clean(default) == (default, False)
|
||||
|
||||
|
||||
def test_reference_property():
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.1")
|
||||
def test_reference_property_whitelist_standard_type():
|
||||
ref_prop = ReferenceProperty(valid_types="identity", spec_version="2.1")
|
||||
result = ref_prop.clean(
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
assert result == ("identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
assert ref_prop.clean("my-type--00000000-0000-4000-8000-000000000000", False)
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("foo", False)
|
||||
ref_prop.clean("foo--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
# This is not a valid RFC 4122 UUID
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("my-type--00000000-0000-0000-0000-000000000000", False)
|
||||
ref_prop.clean("foo--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
|
||||
def test_reference_property_whitelist_type():
|
||||
def test_reference_property_whitelist_custom_type():
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.1")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -108,16 +110,18 @@ def test_reference_property_whitelist_type():
|
|||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("not-my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
result = ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
with pytest.raises(CustomContentError):
|
||||
# This is the whitelisted type, but it's still custom, and
|
||||
# customization is disallowed here.
|
||||
ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
assert result == ("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
result = ref_prop.clean("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_whitelist_generic_type():
|
||||
ref_prop = ReferenceProperty(
|
||||
valid_types=["SCO", "SRO"], spec_version="2.1"
|
||||
valid_types=["SCO", "SRO"], spec_version="2.1",
|
||||
)
|
||||
|
||||
result = ref_prop.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
@ -127,12 +131,19 @@ def test_reference_property_whitelist_generic_type():
|
|||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False
|
||||
"sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
assert result == ("sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True
|
||||
"sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
assert result == ("sighting--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
# The prop assumes some-type is a custom type of one of the generic
|
||||
# type categories.
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
assert result == ("some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
@ -146,7 +157,7 @@ def test_reference_property_whitelist_generic_type():
|
|||
ref_prop.clean("identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_blacklist_type():
|
||||
def test_reference_property_blacklist_standard_type():
|
||||
ref_prop = ReferenceProperty(invalid_types="identity", spec_version="2.1")
|
||||
result = ref_prop.clean(
|
||||
"location--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
|
@ -158,6 +169,11 @@ def test_reference_property_blacklist_type():
|
|||
)
|
||||
assert result == ("location--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
@ -173,15 +189,10 @@ def test_reference_property_blacklist_type():
|
|||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
|
||||
def test_reference_property_blacklist_generic_type():
|
||||
ref_prop = ReferenceProperty(
|
||||
invalid_types=["SDO", "SRO"], spec_version="2.1"
|
||||
invalid_types=["SDO", "SRO"], spec_version="2.1",
|
||||
)
|
||||
|
||||
result = ref_prop.clean(
|
||||
|
@ -194,16 +205,16 @@ def test_reference_property_blacklist_generic_type():
|
|||
)
|
||||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
result = ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
assert result == ("some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
|
@ -211,7 +222,7 @@ def test_reference_property_blacklist_generic_type():
|
|||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"relationship--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
"identity--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -219,18 +230,57 @@ def test_reference_property_blacklist_generic_type():
|
|||
"relationship--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean(
|
||||
"some-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False,
|
||||
"relationship--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True,
|
||||
)
|
||||
|
||||
|
||||
def test_reference_property_hybrid_constraint_type():
|
||||
with pytest.raises(ValueError):
|
||||
ReferenceProperty(valid_types=["a", "SCO"], spec_version="2.1")
|
||||
def test_reference_property_whitelist_hybrid_type():
|
||||
p = ReferenceProperty(valid_types=["a", "SCO"], spec_version="2.1")
|
||||
|
||||
result = p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
# although whitelisted, "a" is a custom type
|
||||
p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
result = p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ReferenceProperty(invalid_types=["a", "SCO"], spec_version="2.1")
|
||||
p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
# should just assume "b" is a custom SCO type.
|
||||
result = p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_blacklist_hybrid_type():
|
||||
p = ReferenceProperty(invalid_types=["a", "SCO"], spec_version="2.1")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("file--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
p.clean("a--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
with pytest.raises(CustomContentError):
|
||||
p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", False)
|
||||
|
||||
# should just assume "b" is a custom type which is not an SCO
|
||||
result = p.clean("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
assert result == ("b--8a8e8758-f92c-4058-ba38-f061cd42a0cf", True)
|
||||
|
||||
|
||||
def test_reference_property_impossible_constraint():
|
||||
|
|
|
@ -4,12 +4,12 @@ import pytest
|
|||
import pytz
|
||||
|
||||
import stix2
|
||||
from stix2.exceptions import InvalidValueError
|
||||
|
||||
from .constants import (
|
||||
CAMPAIGN_ID, IDENTITY_ID, INDICATOR_ID, INDICATOR_KWARGS, RELATIONSHIP_ID,
|
||||
REPORT_ID,
|
||||
)
|
||||
from stix2.exceptions import InvalidValueError
|
||||
|
||||
EXPECTED = """{
|
||||
"type": "report",
|
||||
|
@ -144,8 +144,8 @@ def test_report_on_custom():
|
|||
published="2016-01-20T17:00:00Z",
|
||||
object_refs=[
|
||||
"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7",
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7"
|
||||
]
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7",
|
||||
],
|
||||
)
|
||||
|
||||
report = stix2.v21.Report(
|
||||
|
@ -153,10 +153,10 @@ def test_report_on_custom():
|
|||
published="2016-01-20T17:00:00Z",
|
||||
object_refs=[
|
||||
"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7",
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7"
|
||||
"some-type--2672975a-ce1e-4473-a1c6-0d79868930c7",
|
||||
],
|
||||
allow_custom=True,
|
||||
)
|
||||
|
||||
assert "some-type--2672975a-ce1e-4473-a1c6-0d79868930c7" \
|
||||
in report.object_refs
|
||||
in report.object_refs
|
||||
|
|
Loading…
Reference in New Issue