Merge remote-tracking branch 'emmanvg/marking-support' into markings
commit
14b922ba92
|
@ -11,6 +11,7 @@ from .exceptions import (AtLeastOnePropertyError, DependentPropertiesError,
|
|||
MissingPropertiesError,
|
||||
MutuallyExclusivePropertiesError, RevokeError,
|
||||
UnmodifiablePropertyError)
|
||||
from .markings.utils import validate
|
||||
from .utils import NOW, format_datetime, get_timestamp, parse_into_datetime
|
||||
|
||||
__all__ = ['STIXJSONEncoder', '_STIXBase']
|
||||
|
@ -80,8 +81,7 @@ class _STIXBase(collections.Mapping):
|
|||
|
||||
def _check_object_constraints(self):
|
||||
for m in self.get("granular_markings", []):
|
||||
# TODO: check selectors
|
||||
pass
|
||||
validate(self, m.get("selectors"), m.get("marking_ref"))
|
||||
|
||||
def __init__(self, allow_custom=False, **kwargs):
|
||||
cls = self.__class__
|
||||
|
|
|
@ -157,3 +157,29 @@ class ParseError(STIXError, ValueError):
|
|||
|
||||
def __init__(self, msg):
|
||||
super(ParseError, self).__init__(msg)
|
||||
|
||||
|
||||
class InvalidSelectorError(STIXError, ValueError):
|
||||
"""Granular Marking selector violation. The selector must resolve into an existing STIX object property."""
|
||||
|
||||
def __init__(self, cls, key):
|
||||
super(InvalidSelectorError, self).__init__()
|
||||
self.cls = cls
|
||||
self.key = key
|
||||
|
||||
def __str__(self):
|
||||
msg = "Selector '{0}' in '{1}' is not valid!"
|
||||
return msg.format(self.key, self.__class__.__name__)
|
||||
|
||||
|
||||
class DuplicateMarkingError(STIXError, ValueError):
|
||||
"""Marking violation. The marking reference must be a valid identifier."""
|
||||
|
||||
def __init__(self, cls, key):
|
||||
super(DuplicateMarkingError, self).__init__()
|
||||
self.cls = cls
|
||||
self.key = key
|
||||
|
||||
def __str__(self):
|
||||
msg = "Marking '{0}' in '{1}' is not a valid marking reference."
|
||||
return msg.format(self.key, self.__class__.__name__)
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
"""
|
||||
Python STIX 2.0 Data Markings API.
|
||||
|
||||
These high level functions will operate on both object level markings and
|
||||
granular markings unless otherwise noted in each of the functions.
|
||||
"""
|
||||
|
||||
from stix2.markings import utils
|
||||
from stix2.markings import granular_markings
|
||||
from stix2.markings import object_markings
|
||||
|
||||
|
||||
def get_markings(obj, selectors, inherited=False, descendants=False):
|
||||
"""
|
||||
Get all markings associated to the field(s).
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
inherited: If True, include object level markings and granular markings
|
||||
inherited relative to the field(s).
|
||||
descendants: If True, include granular markings applied to any children
|
||||
relative to the field(s).
|
||||
|
||||
Returns:
|
||||
list: Marking IDs that matched the selectors expression.
|
||||
|
||||
Note:
|
||||
If ``selectors`` is None, operation will be performed only on object
|
||||
level markings.
|
||||
|
||||
"""
|
||||
if selectors is None:
|
||||
return object_markings.get_markings(obj)
|
||||
|
||||
results = granular_markings.get_markings(
|
||||
obj,
|
||||
selectors,
|
||||
inherited,
|
||||
descendants
|
||||
)
|
||||
|
||||
if inherited:
|
||||
results.extend(object_markings.get_markings(obj))
|
||||
|
||||
return list(set(results))
|
||||
|
||||
|
||||
def set_markings(obj, selectors, marking):
|
||||
"""
|
||||
Removes all markings associated with selectors and appends a new granular
|
||||
marking. Refer to `clear_markings` and `add_markings` for details.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
|
||||
Note:
|
||||
If ``selectors`` is None, operations will be performed on object level
|
||||
markings. Otherwise on granular markings.
|
||||
|
||||
"""
|
||||
if selectors is None:
|
||||
object_markings.set_markings(obj, marking)
|
||||
else:
|
||||
granular_markings.set_markings(obj, selectors, marking)
|
||||
|
||||
|
||||
def remove_markings(obj, selectors, marking):
|
||||
"""
|
||||
Removes granular_marking from the granular_markings collection.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
|
||||
Raises:
|
||||
AssertionError: If `selectors` or `marking` fail data validation. Also
|
||||
if markings to remove are not found on the provided TLO.
|
||||
|
||||
Note:
|
||||
If ``selectors`` is None, operations will be performed on object level
|
||||
markings. Otherwise on granular markings.
|
||||
|
||||
"""
|
||||
if selectors is None:
|
||||
object_markings.remove_markings(obj, marking)
|
||||
else:
|
||||
granular_markings.remove_markings(obj, selectors, marking)
|
||||
|
||||
|
||||
def add_markings(obj, selectors, marking):
|
||||
"""
|
||||
Appends a granular_marking to the granular_markings collection.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
|
||||
Raises:
|
||||
AssertionError: If `selectors` or `marking` fail data validation.
|
||||
|
||||
Note:
|
||||
If ``selectors`` is None, operations will be performed on object level
|
||||
markings. Otherwise on granular markings.
|
||||
|
||||
"""
|
||||
if selectors is None:
|
||||
return object_markings.add_markings(obj, marking)
|
||||
else:
|
||||
return granular_markings.add_markings(obj, selectors, marking)
|
||||
|
||||
|
||||
def clear_markings(obj, selectors):
|
||||
"""
|
||||
Removes all granular_marking associated with the selectors.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
|
||||
Note:
|
||||
If ``selectors`` is None, operations will be performed on object level
|
||||
markings. Otherwise on granular markings.
|
||||
|
||||
"""
|
||||
if selectors is None:
|
||||
object_markings.clear_markings(obj)
|
||||
else:
|
||||
granular_markings.clear_markings(obj, selectors)
|
||||
|
||||
|
||||
def is_marked(obj, selectors, marking=None, inherited=False, descendants=False):
|
||||
"""
|
||||
Checks if field(s) is marked by any marking or by specific marking(s).
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
inherited: If True, include object level markings and granular markings
|
||||
inherited to determine if the field(s) is/are marked.
|
||||
descendants: If True, include granular markings applied to any children
|
||||
of the given selector to determine if the field(s) is/are marked.
|
||||
|
||||
Returns:
|
||||
bool: True if ``selectors`` is found on internal TLO collection.
|
||||
False otherwise.
|
||||
|
||||
Note:
|
||||
When a list of marking IDs is provided, if ANY of the provided marking
|
||||
IDs matches, True is returned.
|
||||
|
||||
If ``selectors`` is None, operation will be performed only on object
|
||||
level markings.
|
||||
|
||||
"""
|
||||
if selectors is None:
|
||||
return object_markings.is_marked(obj, marking)
|
||||
|
||||
result = granular_markings.is_marked(
|
||||
obj,
|
||||
selectors,
|
||||
marking,
|
||||
inherited,
|
||||
descendants
|
||||
)
|
||||
|
||||
if inherited:
|
||||
granular_marks = granular_markings.get_markings(obj, selectors)
|
||||
object_marks = object_markings.get_markings(obj)
|
||||
|
||||
if granular_marks:
|
||||
result = granular_markings.is_marked(
|
||||
obj,
|
||||
selectors,
|
||||
granular_marks,
|
||||
inherited,
|
||||
descendants
|
||||
)
|
||||
|
||||
result = result or object_markings.is_marked(obj, object_marks)
|
||||
|
||||
return result
|
|
@ -0,0 +1,237 @@
|
|||
|
||||
from stix2.markings import utils
|
||||
|
||||
|
||||
def get_markings(obj, selectors, inherited=False, descendants=False):
|
||||
"""
|
||||
Get all markings associated to the field(s).
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
inherited: If True, include markings inherited relative to the field(s).
|
||||
descendants: If True, include granular markings applied to any children
|
||||
relative to the field(s).
|
||||
|
||||
Returns:
|
||||
list: Marking IDs that matched the selectors expression.
|
||||
|
||||
"""
|
||||
selectors = utils.fix_value(selectors)
|
||||
utils.validate(obj, selectors)
|
||||
|
||||
granular_markings = obj.get("granular_markings", [])
|
||||
|
||||
if not granular_markings:
|
||||
return []
|
||||
|
||||
results = set()
|
||||
|
||||
for marking in granular_markings:
|
||||
for user_selector in selectors:
|
||||
for marking_selector in marking.get("selectors", []):
|
||||
if any([(user_selector == marking_selector), # Catch explicit selectors.
|
||||
(user_selector.startswith(marking_selector) and inherited), # Catch inherited selectors.
|
||||
(marking_selector.startswith(user_selector) and descendants)]): # Catch descendants selectors
|
||||
refs = marking.get("marking_ref", [])
|
||||
results.update([refs])
|
||||
|
||||
return list(results)
|
||||
|
||||
|
||||
def set_markings(obj, selectors, marking):
|
||||
"""
|
||||
Removes all markings associated with selectors and appends a new granular
|
||||
marking. Refer to `clear_markings` and `add_markings` for details.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
|
||||
"""
|
||||
clear_markings(obj, selectors)
|
||||
add_markings(obj, selectors, marking)
|
||||
|
||||
|
||||
def remove_markings(obj, selectors, marking):
|
||||
"""
|
||||
Removes granular_marking from the granular_markings collection.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
|
||||
Raises:
|
||||
AssertionError: If `selectors` or `marking` fail data validation. Also
|
||||
if markings to remove are not found on the provided TLO.
|
||||
|
||||
"""
|
||||
selectors = utils.fix_value(selectors)
|
||||
utils.validate(obj, selectors, marking)
|
||||
|
||||
utils.expand_markings(obj)
|
||||
|
||||
granular_markings = obj.get("granular_markings")
|
||||
|
||||
if not granular_markings:
|
||||
return
|
||||
|
||||
tlo = utils.build_granular_marking(
|
||||
{"selectors": selectors, "marking_ref": marking}
|
||||
)
|
||||
|
||||
remove = tlo.get("granular_markings", [])
|
||||
|
||||
if not any(marking in granular_markings for marking in remove):
|
||||
raise AssertionError("Unable to remove Granular Marking(s) from"
|
||||
" internal collection. Marking(s) not found...")
|
||||
|
||||
obj["granular_markings"] = [
|
||||
m for m in granular_markings if m not in remove
|
||||
]
|
||||
|
||||
utils.compress_markings(obj)
|
||||
|
||||
if not obj.get("granular_markings"):
|
||||
obj.pop("granular_markings")
|
||||
|
||||
|
||||
def add_markings(obj, selectors, marking):
|
||||
"""
|
||||
Appends a granular_marking to the granular_markings collection.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
|
||||
Raises:
|
||||
AssertionError: If `selectors` or `marking` fail data validation.
|
||||
|
||||
"""
|
||||
selectors = utils.fix_value(selectors)
|
||||
utils.validate(obj, selectors, marking)
|
||||
|
||||
granular_marking = {"selectors": sorted(selectors), "marking_ref": marking}
|
||||
|
||||
if not obj.get("granular_markings"):
|
||||
obj["granular_markings"] = list()
|
||||
|
||||
obj["granular_markings"].append(granular_marking)
|
||||
|
||||
utils.expand_markings(obj)
|
||||
utils.compress_markings(obj)
|
||||
|
||||
|
||||
def clear_markings(obj, selectors):
|
||||
"""
|
||||
Removes all granular_marking associated with the selectors.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
|
||||
Raises:
|
||||
AssertionError: If `selectors` or `marking` fail data validation. Also
|
||||
if markings to remove are not found on the provided TLO.
|
||||
|
||||
"""
|
||||
selectors = utils.fix_value(selectors)
|
||||
utils.validate(obj, selectors)
|
||||
|
||||
utils.expand_markings(obj)
|
||||
|
||||
granular_markings = obj.get("granular_markings")
|
||||
|
||||
if not granular_markings:
|
||||
return
|
||||
|
||||
tlo = utils.build_granular_marking(
|
||||
{"selectors": selectors, "marking_ref": ["N/A"]}
|
||||
)
|
||||
|
||||
clear = tlo.get("granular_markings", [])
|
||||
|
||||
if not any(clear_selector in tlo_selectors.get("selectors", [])
|
||||
for tlo_selectors in granular_markings
|
||||
for clear_marking in clear
|
||||
for clear_selector in clear_marking.get("selectors", [])
|
||||
):
|
||||
raise AssertionError("Unable to clear Granular Marking(s) from"
|
||||
" internal collection. Selector(s) not found...")
|
||||
|
||||
for granular_marking in granular_markings:
|
||||
for s in selectors:
|
||||
if s in granular_marking.get("selectors", []):
|
||||
marking_refs = granular_marking.get("marking_ref")
|
||||
|
||||
if marking_refs:
|
||||
granular_marking["marking_ref"] = list()
|
||||
|
||||
utils.compress_markings(obj)
|
||||
|
||||
if not obj.get("granular_markings"):
|
||||
obj.pop("granular_markings")
|
||||
|
||||
|
||||
def is_marked(obj, selectors, marking=None, inherited=False, descendants=False):
|
||||
"""
|
||||
Checks if field is marked by any marking or by specific marking(s).
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
selectors: string or list of selectors strings relative to the TLO in
|
||||
which the field(s) appear(s).
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
field(s) selected by `selectors`.
|
||||
inherited: If True, return markings inherited from the given selector.
|
||||
descendants: If True, return granular markings applied to any children
|
||||
of the given selector.
|
||||
|
||||
Returns:
|
||||
bool: True if ``selectors`` is found on internal TLO collection.
|
||||
False otherwise.
|
||||
|
||||
Note:
|
||||
When a list of marking IDs is provided, if ANY of the provided marking
|
||||
IDs matches, True is returned.
|
||||
|
||||
"""
|
||||
selectors = utils.fix_value(selectors)
|
||||
marking = utils.fix_value(marking)
|
||||
utils.validate(obj, selectors, marking)
|
||||
|
||||
granular_markings = obj.get("granular_markings", [])
|
||||
|
||||
marked = False
|
||||
markings = set()
|
||||
|
||||
for granular_marking in granular_markings:
|
||||
for user_selector in selectors:
|
||||
for marking_selector in granular_marking.get("selectors", []):
|
||||
|
||||
if any([(user_selector == marking_selector), # Catch explicit selectors.
|
||||
(user_selector.startswith(marking_selector) and inherited), # Catch inherited selectors.
|
||||
(marking_selector.startswith(user_selector) and descendants)]): # Catch descendants selectors
|
||||
marking_ref = granular_marking.get("marking_ref", "")
|
||||
|
||||
if marking and any(x == marking_ref for x in marking):
|
||||
markings.update([marking_ref])
|
||||
|
||||
marked = True
|
||||
|
||||
if marking:
|
||||
# All user-provided markings must be found.
|
||||
return markings.issuperset(set(marking))
|
||||
|
||||
return marked
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
from stix2.markings import utils
|
||||
|
||||
|
||||
def get_markings(obj):
|
||||
"""
|
||||
Get all object level markings from the given SDO or SRO object.
|
||||
|
||||
Args:
|
||||
obj: A SDO or SRO object.
|
||||
|
||||
Returns:
|
||||
list: Marking IDs contained in the SDO or SRO. Empty list if no
|
||||
markings are present in `object_marking_refs`.
|
||||
|
||||
"""
|
||||
return obj.get("object_marking_refs", [])
|
||||
|
||||
|
||||
def add_markings(obj, marking):
|
||||
"""
|
||||
Appends an object level marking to the object_marking_refs collection.
|
||||
|
||||
Args:
|
||||
obj: A SDO or SRO object.
|
||||
marking: identifier or list of identifiers to apply SDO or SRO object.
|
||||
|
||||
Raises:
|
||||
AssertionError: If `marking` fail data validation.
|
||||
|
||||
"""
|
||||
marking = utils.convert_to_list(marking)
|
||||
|
||||
# TODO: Remove set for comparison and raise DuplicateMarkingException.
|
||||
object_markings = set(obj.get("object_marking_refs", []) + marking)
|
||||
|
||||
return obj.new_version(object_marking_refs=list(object_markings))
|
||||
|
||||
|
||||
def remove_markings(obj, marking):
|
||||
"""
|
||||
Removes object level marking from the object_marking_refs collection.
|
||||
|
||||
Args:
|
||||
obj: A SDO or SRO object.
|
||||
marking: identifier or list of identifiers that apply to the
|
||||
SDO or SRO object.
|
||||
|
||||
Raises:
|
||||
AssertionError: If markings to remove are not found on the provided
|
||||
SDO or SRO.
|
||||
|
||||
"""
|
||||
marking = utils.convert_to_list(marking)
|
||||
utils.validate(obj, marking=marking)
|
||||
|
||||
object_markings = obj.get("object_marking_refs", [])
|
||||
|
||||
if not object_markings:
|
||||
return obj
|
||||
|
||||
if any(x not in obj["object_marking_refs"] for x in marking):
|
||||
raise AssertionError("Unable to remove Object Level Marking(s) from "
|
||||
"internal collection. Marking(s) not found...")
|
||||
|
||||
return obj.new_version(object_marking_refs=[x for x in object_markings
|
||||
if x not in marking])
|
||||
|
||||
|
||||
def set_markings(obj, marking):
|
||||
"""
|
||||
Removes all object level markings and appends new object level markings to
|
||||
the collection. Refer to `clear_markings` and `add_markings` for details.
|
||||
|
||||
Args:
|
||||
obj: A SDO or SRO object.
|
||||
marking: identifier or list of identifiers to apply in the
|
||||
SDO or SRO object.
|
||||
|
||||
"""
|
||||
return add_markings(clear_markings(obj), marking)
|
||||
|
||||
|
||||
def clear_markings(obj):
|
||||
"""
|
||||
Removes all object level markings from the object_marking_refs collection.
|
||||
|
||||
Args:
|
||||
obj: A SDO or SRO object.
|
||||
|
||||
"""
|
||||
return obj.new_version(object_marking_refs=None)
|
||||
|
||||
|
||||
def is_marked(obj, marking=None):
|
||||
"""
|
||||
Checks if SDO or SRO is marked by any marking or by specific marking(s).
|
||||
|
||||
Args:
|
||||
obj: A SDO or SRO object.
|
||||
marking: identifier or list of marking identifiers that apply to the
|
||||
SDO or SRO object.
|
||||
|
||||
Returns:
|
||||
bool: True if SDO or SRO has object level markings. False otherwise.
|
||||
|
||||
Note:
|
||||
When an identifier or list of identifiers is provided, if ANY of the
|
||||
provided marking refs match, True is returned.
|
||||
|
||||
"""
|
||||
marking = utils.convert_to_list(marking)
|
||||
object_markings = obj.get("object_marking_refs", [])
|
||||
|
||||
if marking:
|
||||
return any(x in object_markings for x in marking)
|
||||
else:
|
||||
return bool(object_markings)
|
|
@ -0,0 +1,228 @@
|
|||
|
||||
import collections
|
||||
|
||||
import six
|
||||
|
||||
|
||||
def evaluate_expression(obj, selector):
|
||||
|
||||
for items, value in iterpath(obj):
|
||||
path = ".".join(items)
|
||||
|
||||
if path == selector and value:
|
||||
return [value]
|
||||
|
||||
return []
|
||||
|
||||
|
||||
def validate_selector(obj, selector):
|
||||
results = list(evaluate_expression(obj, selector))
|
||||
|
||||
if len(results) >= 1:
|
||||
return True
|
||||
|
||||
|
||||
def validate_markings(marking):
|
||||
if isinstance(marking, six.string_types):
|
||||
if not marking:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
elif isinstance(marking, list) and len(marking) >= 1:
|
||||
for m in marking:
|
||||
if not m:
|
||||
return False
|
||||
elif not isinstance(m, six.string_types):
|
||||
return False
|
||||
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def validate(obj, selectors=None, marking=None):
|
||||
|
||||
if selectors is not None:
|
||||
assert selectors
|
||||
|
||||
for s in selectors:
|
||||
assert validate_selector(obj, s)
|
||||
|
||||
if marking is not None:
|
||||
assert validate_markings(marking)
|
||||
|
||||
|
||||
def convert_to_list(data):
|
||||
if data is not None:
|
||||
if isinstance(data, list):
|
||||
return data
|
||||
else:
|
||||
return [data]
|
||||
|
||||
|
||||
def fix_value(data):
|
||||
data = convert_to_list(data)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def _fix_markings(markings):
|
||||
|
||||
for granular_marking in markings:
|
||||
refs = granular_marking.get("marking_ref", [])
|
||||
selectors = granular_marking.get("selectors", [])
|
||||
|
||||
if not isinstance(refs, list):
|
||||
granular_marking["marking_ref"] = [refs]
|
||||
|
||||
if not isinstance(selectors, list):
|
||||
granular_marking["selectors"] = [selectors]
|
||||
|
||||
|
||||
def _group_by(markings):
|
||||
|
||||
key = "marking_ref"
|
||||
retrieve = "selectors"
|
||||
|
||||
map_ = collections.defaultdict(set)
|
||||
|
||||
for granular_marking in markings:
|
||||
for data in granular_marking.get(key, []):
|
||||
map_[data].update(granular_marking.get(retrieve))
|
||||
|
||||
granular_markings = \
|
||||
[
|
||||
{"selectors": sorted(selectors), "marking_ref": ref}
|
||||
for ref, selectors in six.iteritems(map_)
|
||||
]
|
||||
|
||||
return granular_markings
|
||||
|
||||
|
||||
def compress_markings(tlo):
|
||||
|
||||
if not tlo.get("granular_markings"):
|
||||
return
|
||||
|
||||
granular_markings = tlo.get("granular_markings")
|
||||
|
||||
_fix_markings(granular_markings)
|
||||
|
||||
tlo["granular_markings"] = _group_by(granular_markings)
|
||||
|
||||
|
||||
def expand_markings(tlo):
|
||||
|
||||
if not tlo.get("granular_markings"):
|
||||
return
|
||||
|
||||
granular_markings = tlo.get("granular_markings")
|
||||
|
||||
_fix_markings(granular_markings)
|
||||
|
||||
expanded = list()
|
||||
|
||||
for marking in granular_markings:
|
||||
selectors = marking.get("selectors", [])
|
||||
marking_ref = marking.get("marking_ref", [])
|
||||
|
||||
expanded.extend(
|
||||
[
|
||||
{"selectors": [sel], "marking_ref": ref}
|
||||
for sel in selectors
|
||||
for ref in marking_ref
|
||||
]
|
||||
)
|
||||
|
||||
tlo["granular_markings"] = expanded
|
||||
|
||||
|
||||
def build_granular_marking(granular_marking):
|
||||
tlo = {"granular_markings": [granular_marking]}
|
||||
|
||||
expand_markings(tlo)
|
||||
|
||||
return tlo
|
||||
|
||||
|
||||
def iterpath(obj, path=None):
|
||||
"""
|
||||
Generator which walks the input ``obj`` model. Each iteration yields a
|
||||
tuple containing a list of ancestors and the property value.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
path: None, used recursively to store ancestors.
|
||||
|
||||
Example:
|
||||
>>> for item in iterpath(tlo):
|
||||
>>> print(item)
|
||||
(['type'], 'campaign')
|
||||
...
|
||||
(['cybox', 'objects', '[0]', 'hashes', 'sha1'], 'cac35ec206d868b7d7cb0b55f31d9425b075082b')
|
||||
|
||||
Returns:
|
||||
tuple: Containing two items: a list of ancestors and the property value.
|
||||
|
||||
"""
|
||||
if path is None:
|
||||
path = []
|
||||
|
||||
for varname, varobj in iter(sorted(six.iteritems(obj))):
|
||||
path.append(varname)
|
||||
yield (path, varobj)
|
||||
|
||||
if isinstance(varobj, dict):
|
||||
|
||||
for item in iterpath(varobj, path):
|
||||
yield item
|
||||
|
||||
elif isinstance(varobj, list):
|
||||
|
||||
for item in varobj:
|
||||
index = "[{0}]".format(varobj.index(item))
|
||||
path.append(index)
|
||||
|
||||
yield (path, item)
|
||||
|
||||
if isinstance(item, dict):
|
||||
for descendant in iterpath(item, path):
|
||||
yield descendant
|
||||
|
||||
path.pop()
|
||||
|
||||
path.pop()
|
||||
|
||||
|
||||
def get_selector(obj, prop):
|
||||
"""
|
||||
Function that creates a selector based on ``prop``.
|
||||
|
||||
Args:
|
||||
obj: A TLO object.
|
||||
prop: A property of the TLO object.
|
||||
|
||||
Note:
|
||||
Must supply the actual value inside the structure. Since some
|
||||
limitations exist with Python interning methods, checking for object
|
||||
location is for now the option to assert the data.
|
||||
|
||||
Example:
|
||||
>>> selector = get_selector(tlo, tlo["cybox"]["objects"][0]["file_name"])
|
||||
>>> print(selector)
|
||||
["cybox.objects.[0].file_name"]
|
||||
|
||||
Returns:
|
||||
list: A list with one selector that asserts the supplied property.
|
||||
Empty list if it was unable to find the property.
|
||||
|
||||
"""
|
||||
selector = []
|
||||
|
||||
for ancestors, value in iterpath(obj):
|
||||
if value is prop:
|
||||
path = ".".join(ancestors)
|
||||
selector.append(path)
|
||||
|
||||
return selector
|
|
@ -0,0 +1,968 @@
|
|||
|
||||
from stix2 import markings
|
||||
|
||||
import pytest
|
||||
|
||||
"""Tests for the Data Markings API."""
|
||||
|
||||
|
||||
def test_add_marking_mark_one_selector_multiple_refs():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.add_markings(before, ["description"], ["marking-definition--1", "marking-definition--2"])
|
||||
|
||||
for m in before["granular_markings"]:
|
||||
assert m in after["granular_markings"]
|
||||
|
||||
|
||||
def test_add_marking_mark_multiple_selector_one_refs():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.add_markings(before, ["description", "title"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_add_marking_mark_multiple_selector_multiple_refs():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.add_markings(before, ["description", "title"], ["marking-definition--1", "marking-definition--2"])
|
||||
|
||||
for m in before["granular_markings"]:
|
||||
assert m in after["granular_markings"]
|
||||
|
||||
|
||||
def test_add_marking_mark_another_property_same_marking():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.add_markings(before, ["title"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_add_marking_mark_same_property_same_marking():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
markings.add_markings(before, ["description"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data,marking", [
|
||||
({"description": "test description"},
|
||||
[["title"], ["marking-definition--1", "marking-definition--2"],
|
||||
"", ["marking-definition--1", "marking-definition--2"],
|
||||
[], ["marking-definition--1", "marking-definition--2"],
|
||||
[""], ["marking-definition--1", "marking-definition--2"],
|
||||
["description"], [""],
|
||||
["description"], [],
|
||||
["description"], ["marking-definition--1", 456]
|
||||
])
|
||||
])
|
||||
def test_add_marking_bad_selector(data, marking):
|
||||
with pytest.raises(AssertionError):
|
||||
markings.add_markings(data, marking[0], marking[1])
|
||||
|
||||
|
||||
GET_MARKINGS_TEST_DATA = \
|
||||
{
|
||||
"a": 333,
|
||||
"b": "value",
|
||||
"c": [
|
||||
17,
|
||||
"list value",
|
||||
{
|
||||
"g": "nested",
|
||||
"h": 45
|
||||
}
|
||||
],
|
||||
"x": {
|
||||
"y": [
|
||||
"hello",
|
||||
88
|
||||
],
|
||||
"z": {
|
||||
"foo1": "bar",
|
||||
"foo2": 65
|
||||
}
|
||||
},
|
||||
"granular_markings": [
|
||||
{
|
||||
"marking_ref": "1",
|
||||
"selectors": ["a"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "2",
|
||||
"selectors": ["c"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "3",
|
||||
"selectors": ["c.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "4",
|
||||
"selectors": ["c.[2]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "5",
|
||||
"selectors": ["c.[2].g"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "6",
|
||||
"selectors": ["x"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "7",
|
||||
"selectors": ["x.y"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "8",
|
||||
"selectors": ["x.y.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "9",
|
||||
"selectors": ["x.z"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "10",
|
||||
"selectors": ["x.z.foo2"]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA])
|
||||
def test_get_markings_smoke(data):
|
||||
"""Test get_markings does not fail."""
|
||||
assert len(markings.get_markings(data, "a")) >= 1
|
||||
assert markings.get_markings(data, "a") == ["1"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA])
|
||||
def test_get_markings_not_marked(data):
|
||||
"""Test selector that is not marked returns empty list."""
|
||||
results = markings.get_markings(data, "b")
|
||||
assert len(results) == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA])
|
||||
def test_get_markings_multiple_selectors(data):
|
||||
"""Test multiple selectors return combination of markings."""
|
||||
total = markings.get_markings(data, ["x.y", "x.z"])
|
||||
xy_markings = markings.get_markings(data, ["x.y"])
|
||||
xz_markings = markings.get_markings(data, ["x.z"])
|
||||
|
||||
assert set(xy_markings).issubset(total)
|
||||
assert set(xz_markings).issubset(total)
|
||||
assert set(xy_markings).union(xz_markings).issuperset(total)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data,selector", [
|
||||
(GET_MARKINGS_TEST_DATA, "foo"),
|
||||
(GET_MARKINGS_TEST_DATA, ""),
|
||||
(GET_MARKINGS_TEST_DATA, []),
|
||||
(GET_MARKINGS_TEST_DATA, [""]),
|
||||
(GET_MARKINGS_TEST_DATA, "x.z.[-2]"),
|
||||
(GET_MARKINGS_TEST_DATA, "c.f"),
|
||||
(GET_MARKINGS_TEST_DATA, "c.[2].i"),
|
||||
(GET_MARKINGS_TEST_DATA, "c.[3]"),
|
||||
(GET_MARKINGS_TEST_DATA, "d"),
|
||||
(GET_MARKINGS_TEST_DATA, "x.[0]"),
|
||||
(GET_MARKINGS_TEST_DATA, "z.y.w"),
|
||||
(GET_MARKINGS_TEST_DATA, "x.z.[1]"),
|
||||
(GET_MARKINGS_TEST_DATA, "x.z.foo3")
|
||||
])
|
||||
def test_get_markings_bad_selector(data, selector):
|
||||
"""Test bad selectors raise exception"""
|
||||
with pytest.raises(AssertionError):
|
||||
markings.get_markings(data, selector)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA])
|
||||
def test_get_markings_positional_arguments_combinations(data):
|
||||
"""Test multiple combinations for inherited and descendant markings."""
|
||||
assert set(markings.get_markings(data, "a", False, False)) == set(["1"])
|
||||
assert set(markings.get_markings(data, "a", True, False)) == set(["1"])
|
||||
assert set(markings.get_markings(data, "a", True, True)) == set(["1"])
|
||||
assert set(markings.get_markings(data, "a", False, True)) == set(["1"])
|
||||
|
||||
assert set(markings.get_markings(data, "b", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "b", True, False)) == set([])
|
||||
assert set(markings.get_markings(data, "b", True, True)) == set([])
|
||||
assert set(markings.get_markings(data, "b", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "c", False, False)) == set(["2"])
|
||||
assert set(markings.get_markings(data, "c", True, False)) == set(["2"])
|
||||
assert set(markings.get_markings(data, "c", True, True)) == set(["2", "3", "4", "5"])
|
||||
assert set(markings.get_markings(data, "c", False, True)) == set(["2", "3", "4", "5"])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[0]", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "c.[0]", True, False)) == set(["2"])
|
||||
assert set(markings.get_markings(data, "c.[0]", True, True)) == set(["2"])
|
||||
assert set(markings.get_markings(data, "c.[0]", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[1]", False, False)) == set(["3"])
|
||||
assert set(markings.get_markings(data, "c.[1]", True, False)) == set(["2", "3"])
|
||||
assert set(markings.get_markings(data, "c.[1]", True, True)) == set(["2", "3"])
|
||||
assert set(markings.get_markings(data, "c.[1]", False, True)) == set(["3"])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[2]", False, False)) == set(["4"])
|
||||
assert set(markings.get_markings(data, "c.[2]", True, False)) == set(["2", "4"])
|
||||
assert set(markings.get_markings(data, "c.[2]", True, True)) == set(["2", "4", "5"])
|
||||
assert set(markings.get_markings(data, "c.[2]", False, True)) == set(["4", "5"])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[2].g", False, False)) == set(["5"])
|
||||
assert set(markings.get_markings(data, "c.[2].g", True, False)) == set(["2", "4", "5"])
|
||||
assert set(markings.get_markings(data, "c.[2].g", True, True)) == set(["2", "4", "5"])
|
||||
assert set(markings.get_markings(data, "c.[2].g", False, True)) == set(["5"])
|
||||
|
||||
assert set(markings.get_markings(data, "x", False, False)) == set(["6"])
|
||||
assert set(markings.get_markings(data, "x", True, False)) == set(["6"])
|
||||
assert set(markings.get_markings(data, "x", True, True)) == set(["6", "7", "8", "9", "10"])
|
||||
assert set(markings.get_markings(data, "x", False, True)) == set(["6", "7", "8", "9", "10"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.y", False, False)) == set(["7"])
|
||||
assert set(markings.get_markings(data, "x.y", True, False)) == set(["6", "7"])
|
||||
assert set(markings.get_markings(data, "x.y", True, True)) == set(["6", "7", "8"])
|
||||
assert set(markings.get_markings(data, "x.y", False, True)) == set(["7", "8"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.y.[0]", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "x.y.[0]", True, False)) == set(["6", "7"])
|
||||
assert set(markings.get_markings(data, "x.y.[0]", True, True)) == set(["6", "7"])
|
||||
assert set(markings.get_markings(data, "x.y.[0]", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "x.y.[1]", False, False)) == set(["8"])
|
||||
assert set(markings.get_markings(data, "x.y.[1]", True, False)) == set(["6", "7", "8"])
|
||||
assert set(markings.get_markings(data, "x.y.[1]", True, True)) == set(["6", "7", "8"])
|
||||
assert set(markings.get_markings(data, "x.y.[1]", False, True)) == set(["8"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.z", False, False)) == set(["9"])
|
||||
assert set(markings.get_markings(data, "x.z", True, False)) == set(["6", "9"])
|
||||
assert set(markings.get_markings(data, "x.z", True, True)) == set(["6", "9", "10"])
|
||||
assert set(markings.get_markings(data, "x.z", False, True)) == set(["9", "10"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.z.foo1", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "x.z.foo1", True, False)) == set(["6", "9"])
|
||||
assert set(markings.get_markings(data, "x.z.foo1", True, True)) == set(["6", "9"])
|
||||
assert set(markings.get_markings(data, "x.z.foo1", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "x.z.foo2", False, False)) == set(["10"])
|
||||
assert set(markings.get_markings(data, "x.z.foo2", True, False)) == set(["6", "9", "10"])
|
||||
assert set(markings.get_markings(data, "x.z.foo2", True, True)) == set(["6", "9", "10"])
|
||||
assert set(markings.get_markings(data, "x.z.foo2", False, True)) == set(["10"])
|
||||
|
||||
|
||||
def test_remove_marking_remove_one_selector_with_multiple_refs():
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.remove_markings(before, ["description"], ["marking-definition--1", "marking-definition--2"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_marking_remove_multiple_selector_one_ref():
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.remove_markings(before, ["description", "title"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_marking_mark_one_selector_from_multiple_ones():
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.remove_markings(before, ["title"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_marking_mark_one_selector_markings_from_multiple_ones():
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.remove_markings(before, ["title"], ["marking-definition--1"])
|
||||
|
||||
for m in before["granular_markings"]:
|
||||
assert m in after["granular_markings"]
|
||||
|
||||
|
||||
def test_remove_marking_mark_mutilple_selector_multiple_refs():
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.remove_markings(before, ["description", "title"], ["marking-definition--1", "marking-definition--2"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_marking_mark_another_property_same_marking():
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
markings.remove_markings(before, ["title"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_marking_mark_same_property_same_marking():
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
markings.remove_markings(before, ["description"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_marking_bad_selector():
|
||||
before = {
|
||||
"description": "test description",
|
||||
}
|
||||
with pytest.raises(AssertionError):
|
||||
markings.remove_markings(before, ["title"], ["marking-definition--1", "marking-definition--2"])
|
||||
|
||||
|
||||
IS_MARKED_TEST_DATA = \
|
||||
{
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"revision": 2,
|
||||
"type": "test",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["revision", "description"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
{
|
||||
"selectors": ["revision", "description"],
|
||||
"marking_ref": "marking-definition--3"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [IS_MARKED_TEST_DATA])
|
||||
def test_is_marked_smoke(data):
|
||||
"""Smoke test is_marked call does not fail."""
|
||||
assert markings.is_marked(data, ["description"])
|
||||
assert markings.is_marked(data, ["title"]) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data,selector", [
|
||||
(IS_MARKED_TEST_DATA, "foo"),
|
||||
(IS_MARKED_TEST_DATA, ""),
|
||||
(IS_MARKED_TEST_DATA, []),
|
||||
(IS_MARKED_TEST_DATA, [""]),
|
||||
(IS_MARKED_TEST_DATA, "x.z.[-2]"),
|
||||
(IS_MARKED_TEST_DATA, "c.f"),
|
||||
(IS_MARKED_TEST_DATA, "c.[2].i"),
|
||||
(IS_MARKED_TEST_DATA, "c.[3]"),
|
||||
(IS_MARKED_TEST_DATA, "d"),
|
||||
(IS_MARKED_TEST_DATA, "x.[0]"),
|
||||
(IS_MARKED_TEST_DATA, "z.y.w"),
|
||||
(IS_MARKED_TEST_DATA, "x.z.[1]"),
|
||||
(IS_MARKED_TEST_DATA, "x.z.foo3")
|
||||
])
|
||||
def test_is_marked_invalid_selector(data, selector):
|
||||
"""Test invalid selector raises an error."""
|
||||
with pytest.raises(AssertionError):
|
||||
markings.is_marked(data, selector)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [IS_MARKED_TEST_DATA])
|
||||
def test_is_marked_mix_selector(data):
|
||||
"""Test valid selector, one marked and one not marked returns True."""
|
||||
assert markings.is_marked(data, ["description", "revision"])
|
||||
assert markings.is_marked(data, ["description"])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [IS_MARKED_TEST_DATA])
|
||||
def test_is_marked_valid_selector_no_refs(data):
|
||||
"""Test that a valid selector return True when it has marking refs and False when not."""
|
||||
assert markings.is_marked(data, ["description"])
|
||||
assert markings.is_marked(data, ["description"], ["marking-definition--2", "marking-definition--3"])
|
||||
assert markings.is_marked(data, ["description"], ["marking-definition--2"])
|
||||
assert markings.is_marked(data, ["description"], ["marking-definition--2", "marking-definition--8"]) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [IS_MARKED_TEST_DATA])
|
||||
def test_is_marked_valid_selector_and_refs(data):
|
||||
"""Test that a valid selector returns True when marking_refs match."""
|
||||
assert markings.is_marked(data, ["description"], ["marking-definition--1"])
|
||||
assert markings.is_marked(data, ["title"], ["marking-definition--1"]) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [IS_MARKED_TEST_DATA])
|
||||
def test_is_marked_valid_selector_multiple_refs(data):
|
||||
"""Test that a valid selector returns True if aall marking_refs match.
|
||||
Otherwise False."""
|
||||
assert markings.is_marked(data, ["revision"], ["marking-definition--2", "marking-definition--3"])
|
||||
assert markings.is_marked(data, ["revision"], ["marking-definition--2", "marking-definition--1"]) is False
|
||||
assert markings.is_marked(data, ["revision"], "marking-definition--2")
|
||||
assert markings.is_marked(data, ["revision"], ["marking-definition--1234"]) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [IS_MARKED_TEST_DATA])
|
||||
def test_is_marked_no_marking_refs(data):
|
||||
"""Test that a valid content selector with no marking_refs returns True
|
||||
if there is a granular_marking that asserts that field, False
|
||||
otherwise."""
|
||||
assert markings.is_marked(data, ["type"]) is False
|
||||
assert markings.is_marked(data, ["revision"])
|
||||
|
||||
|
||||
def test_is_marked_positional_arguments_combinations():
|
||||
"""Test multiple combinations for inherited and descendant markings."""
|
||||
test_tlo = \
|
||||
{
|
||||
"a": 333,
|
||||
"b": "value",
|
||||
"c": [
|
||||
17,
|
||||
"list value",
|
||||
{
|
||||
"g": "nested",
|
||||
"h": 45
|
||||
}
|
||||
],
|
||||
"x": {
|
||||
"y": [
|
||||
"hello",
|
||||
88
|
||||
],
|
||||
"z": {
|
||||
"foo1": "bar",
|
||||
"foo2": 65
|
||||
}
|
||||
},
|
||||
"granular_markings": [
|
||||
{
|
||||
"marking_ref": "1",
|
||||
"selectors": ["a"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "2",
|
||||
"selectors": ["c"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "3",
|
||||
"selectors": ["c.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "4",
|
||||
"selectors": ["c.[2]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "5",
|
||||
"selectors": ["c.[2].g"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "6",
|
||||
"selectors": ["x"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "7",
|
||||
"selectors": ["x.y"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "8",
|
||||
"selectors": ["x.y.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "9",
|
||||
"selectors": ["x.z"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "10",
|
||||
"selectors": ["x.z.foo2"]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
assert markings.is_marked(test_tlo, "a", ["1"], False, False)
|
||||
assert markings.is_marked(test_tlo, "a", ["1"], True, False)
|
||||
assert markings.is_marked(test_tlo, "a", ["1"], True, True)
|
||||
assert markings.is_marked(test_tlo, "a", ["1"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "b", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "b", inherited=True, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "b", inherited=True, descendants=True) is False
|
||||
assert markings.is_marked(test_tlo, "b", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "c", ["2"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c", ["2"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c", ["2", "3", "4", "5"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c", ["2", "3", "4", "5"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[0]", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "c.[0]", ["2"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[0]", ["2"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[0]", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["3"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["2", "3"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["2", "3"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["3"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["4"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["2", "4"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["2", "4", "5"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["4", "5"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["5"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["2", "4", "5"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["2", "4", "5"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["5"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x", ["6"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x", ["6"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x", ["6", "7", "8", "9", "10"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x", ["6", "7", "8", "9", "10"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.y", ["7"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.y", ["6", "7"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.y", ["6", "7", "8"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.y", ["7", "8"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", ["6", "7"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", ["6", "7"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["8"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["6", "7", "8"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["6", "7", "8"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["8"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.z", ["9"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.z", ["6", "9"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.z", ["6", "9", "10"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.z", ["9", "10"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", ["6", "9"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", ["6", "9"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["10"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["6", "9", "10"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["6", "9", "10"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["10"], False, True)
|
||||
|
||||
|
||||
def test_set_marking_mark_one_selector_multiple_refs():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.set_markings(before, ["description"], ["marking-definition--1", "marking-definition--2"])
|
||||
for m in before["granular_markings"]:
|
||||
assert m in after["granular_markings"]
|
||||
|
||||
|
||||
def test_set_marking_mark_multiple_selector_one_refs():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--3"
|
||||
},
|
||||
]
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.set_markings(before, ["description", "title"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_set_marking_mark_multiple_selector_multiple_refs_from_none():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["description", "title"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.set_markings(before, ["description", "title"], ["marking-definition--1", "marking-definition--2"])
|
||||
for m in before["granular_markings"]:
|
||||
assert m in after["granular_markings"]
|
||||
|
||||
|
||||
def test_set_marking_mark_another_property_same_marking():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--7"
|
||||
},
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--8"
|
||||
},
|
||||
]
|
||||
}
|
||||
markings.set_markings(before, ["description"], ["marking-definition--7", "marking-definition--8"])
|
||||
|
||||
for m in before["granular_markings"]:
|
||||
assert m in after["granular_markings"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("marking", [
|
||||
(["foo"], ["marking-definition--7", "marking-definition--8"]),
|
||||
("", ["marking-definition--7", "marking-definition--8"]),
|
||||
([], ["marking-definition--7", "marking-definition--8"]),
|
||||
([""], ["marking-definition--7", "marking-definition--8"])
|
||||
])
|
||||
def test_set_marking_bad_selector(marking):
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
markings.set_markings(before, marking[0], marking[1])
|
||||
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_set_marking_mark_same_property_same_marking():
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
}
|
||||
]
|
||||
}
|
||||
markings.set_markings(before, ["description"], ["marking-definition--1"])
|
||||
assert before == after
|
||||
|
||||
|
||||
CLEAR_MARKINGS_TEST_DATA = \
|
||||
{
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"revision": 2,
|
||||
"type": "test",
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--1"
|
||||
},
|
||||
{
|
||||
"selectors": ["revision", "description"],
|
||||
"marking_ref": "marking-definition--2"
|
||||
},
|
||||
{
|
||||
"selectors": ["revision", "description", "type"],
|
||||
"marking_ref": "marking-definition--3"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [CLEAR_MARKINGS_TEST_DATA])
|
||||
def test_clear_marking_smoke(data):
|
||||
"""Test clear_marking call does not fail."""
|
||||
markings.clear_markings(data, "revision")
|
||||
assert markings.is_marked(data, "revision") is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [CLEAR_MARKINGS_TEST_DATA])
|
||||
def test_clear_marking_multiple_selectors(data):
|
||||
"""Test clearing markings for multiple selectors effectively removes associated markings."""
|
||||
markings.clear_markings(data, ["type", "description"])
|
||||
assert markings.is_marked(data, ["type", "description"]) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [CLEAR_MARKINGS_TEST_DATA])
|
||||
def test_clear_marking_one_selector(data):
|
||||
"""Test markings associated with one selector were removed."""
|
||||
markings.clear_markings(data, "description")
|
||||
assert markings.is_marked(data, "description") is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [CLEAR_MARKINGS_TEST_DATA])
|
||||
def test_clear_marking_all_selectors(data):
|
||||
markings.clear_markings(data, ["description", "type", "revision"])
|
||||
assert markings.is_marked(data, "description") is False
|
||||
assert "granular_markings" not in data
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data,selector", [
|
||||
(CLEAR_MARKINGS_TEST_DATA, "foo"),
|
||||
(CLEAR_MARKINGS_TEST_DATA, ""),
|
||||
(CLEAR_MARKINGS_TEST_DATA, []),
|
||||
(CLEAR_MARKINGS_TEST_DATA, [""]),
|
||||
])
|
||||
def test_clear_marking_bad_selector(data, selector):
|
||||
"""Test bad selector raises exception."""
|
||||
with pytest.raises(AssertionError):
|
||||
markings.clear_markings(data, selector)
|
|
@ -4,7 +4,7 @@ import pytest
|
|||
import pytz
|
||||
|
||||
import stix2
|
||||
from stix2 import TLP_WHITE
|
||||
from stix2 import TLP_WHITE, markings
|
||||
|
||||
from .constants import MARKING_DEFINITION_ID
|
||||
|
||||
|
@ -155,6 +155,8 @@ def test_campaign_with_granular_markings_example():
|
|||
marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
|
||||
selectors=["description"])
|
||||
])
|
||||
print (markings.get_markings(campaign, None))
|
||||
print (markings.add_markings(campaign, None, "marking-definition--00000000-0000-0000-0000-000000000000"))
|
||||
assert str(campaign) == EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,487 @@
|
|||
|
||||
from stix2 import markings
|
||||
|
||||
import pytest
|
||||
|
||||
"""Tests for the Data Markings API."""
|
||||
|
||||
|
||||
def test_add_markings_one_marking():
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description"
|
||||
}
|
||||
|
||||
after = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1"]
|
||||
}
|
||||
|
||||
markings.add_markings(before, None, "marking-definition--1")
|
||||
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_add_markings_multiple_marking():
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description"
|
||||
}
|
||||
|
||||
after = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1", "marking-definition--2"]
|
||||
}
|
||||
|
||||
markings.add_markings(before, None, ["marking-definition--1", "marking-definition--2"])
|
||||
|
||||
for m in before["object_marking_refs"]:
|
||||
assert m in after["object_marking_refs"]
|
||||
|
||||
|
||||
def test_add_markings_combination():
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description"
|
||||
}
|
||||
|
||||
after = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1", "marking-definition--2"],
|
||||
"granular_markings": [
|
||||
{
|
||||
"selectors": ["title"],
|
||||
"marking_ref": "marking-definition--3"
|
||||
},
|
||||
{
|
||||
"selectors": ["description"],
|
||||
"marking_ref": "marking-definition--4"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
markings.add_markings(before, None, "marking-definition--1")
|
||||
markings.add_markings(before, None, "marking-definition--2")
|
||||
markings.add_markings(before, "title", "marking-definition--3")
|
||||
markings.add_markings(before, "description", "marking-definition--4")
|
||||
|
||||
for m in before["granular_markings"]:
|
||||
assert m in after["granular_markings"]
|
||||
|
||||
for m in before["object_marking_refs"]:
|
||||
assert m in after["object_marking_refs"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [
|
||||
([""]),
|
||||
(""),
|
||||
([]),
|
||||
(["marking-definition--1", 456])
|
||||
])
|
||||
def test_add_markings_bad_markings(data):
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description"
|
||||
}
|
||||
with pytest.raises(AssertionError):
|
||||
markings.add_markings(before, None, data)
|
||||
|
||||
assert "object_marking_refs" not in before
|
||||
|
||||
|
||||
GET_MARKINGS_TEST_DATA = \
|
||||
{
|
||||
"a": 333,
|
||||
"b": "value",
|
||||
"c": [
|
||||
17,
|
||||
"list value",
|
||||
{
|
||||
"g": "nested",
|
||||
"h": 45
|
||||
}
|
||||
],
|
||||
"x": {
|
||||
"y": [
|
||||
"hello",
|
||||
88
|
||||
],
|
||||
"z": {
|
||||
"foo1": "bar",
|
||||
"foo2": 65
|
||||
}
|
||||
},
|
||||
"object_marking_refs": ["11"],
|
||||
"granular_markings": [
|
||||
{
|
||||
"marking_ref": "1",
|
||||
"selectors": ["a"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "2",
|
||||
"selectors": ["c"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "3",
|
||||
"selectors": ["c.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "4",
|
||||
"selectors": ["c.[2]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "5",
|
||||
"selectors": ["c.[2].g"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "6",
|
||||
"selectors": ["x"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "7",
|
||||
"selectors": ["x.y"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "8",
|
||||
"selectors": ["x.y.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "9",
|
||||
"selectors": ["x.z"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "10",
|
||||
"selectors": ["x.z.foo2"]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA])
|
||||
def test_get_markings_object_marking(data):
|
||||
assert set(markings.get_markings(data, None)) == set(["11"])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA])
|
||||
def test_get_markings_object_and_granular_combinations(data):
|
||||
"""Test multiple combinations for inherited and descendant markings."""
|
||||
assert set(markings.get_markings(data, "a", False, False)) == set(["1"])
|
||||
assert set(markings.get_markings(data, "a", True, False)) == set(["1", "11"])
|
||||
assert set(markings.get_markings(data, "a", True, True)) == set(["1", "11"])
|
||||
assert set(markings.get_markings(data, "a", False, True)) == set(["1"])
|
||||
|
||||
assert set(markings.get_markings(data, "b", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "b", True, False)) == set(["11"])
|
||||
assert set(markings.get_markings(data, "b", True, True)) == set(["11"])
|
||||
assert set(markings.get_markings(data, "b", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "c", False, False)) == set(["2"])
|
||||
assert set(markings.get_markings(data, "c", True, False)) == set(["2", "11"])
|
||||
assert set(markings.get_markings(data, "c", True, True)) == set(["2", "3", "4", "5", "11"])
|
||||
assert set(markings.get_markings(data, "c", False, True)) == set(["2", "3", "4", "5"])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[0]", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "c.[0]", True, False)) == set(["2", "11"])
|
||||
assert set(markings.get_markings(data, "c.[0]", True, True)) == set(["2", "11"])
|
||||
assert set(markings.get_markings(data, "c.[0]", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[1]", False, False)) == set(["3"])
|
||||
assert set(markings.get_markings(data, "c.[1]", True, False)) == set(["2", "3", "11"])
|
||||
assert set(markings.get_markings(data, "c.[1]", True, True)) == set(["2", "3", "11"])
|
||||
assert set(markings.get_markings(data, "c.[1]", False, True)) == set(["3"])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[2]", False, False)) == set(["4"])
|
||||
assert set(markings.get_markings(data, "c.[2]", True, False)) == set(["2", "4", "11"])
|
||||
assert set(markings.get_markings(data, "c.[2]", True, True)) == set(["2", "4", "5", "11"])
|
||||
assert set(markings.get_markings(data, "c.[2]", False, True)) == set(["4", "5"])
|
||||
|
||||
assert set(markings.get_markings(data, "c.[2].g", False, False)) == set(["5"])
|
||||
assert set(markings.get_markings(data, "c.[2].g", True, False)) == set(["2", "4", "5", "11"])
|
||||
assert set(markings.get_markings(data, "c.[2].g", True, True)) == set(["2", "4", "5", "11"])
|
||||
assert set(markings.get_markings(data, "c.[2].g", False, True)) == set(["5"])
|
||||
|
||||
assert set(markings.get_markings(data, "x", False, False)) == set(["6"])
|
||||
assert set(markings.get_markings(data, "x", True, False)) == set(["6", "11"])
|
||||
assert set(markings.get_markings(data, "x", True, True)) == set(["6", "7", "8", "9", "10", "11"])
|
||||
assert set(markings.get_markings(data, "x", False, True)) == set(["6", "7", "8", "9", "10"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.y", False, False)) == set(["7"])
|
||||
assert set(markings.get_markings(data, "x.y", True, False)) == set(["6", "7", "11"])
|
||||
assert set(markings.get_markings(data, "x.y", True, True)) == set(["6", "7", "8", "11"])
|
||||
assert set(markings.get_markings(data, "x.y", False, True)) == set(["7", "8"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.y.[0]", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "x.y.[0]", True, False)) == set(["6", "7", "11"])
|
||||
assert set(markings.get_markings(data, "x.y.[0]", True, True)) == set(["6", "7", "11"])
|
||||
assert set(markings.get_markings(data, "x.y.[0]", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "x.y.[1]", False, False)) == set(["8"])
|
||||
assert set(markings.get_markings(data, "x.y.[1]", True, False)) == set(["6", "7", "8", "11"])
|
||||
assert set(markings.get_markings(data, "x.y.[1]", True, True)) == set(["6", "7", "8", "11"])
|
||||
assert set(markings.get_markings(data, "x.y.[1]", False, True)) == set(["8"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.z", False, False)) == set(["9"])
|
||||
assert set(markings.get_markings(data, "x.z", True, False)) == set(["6", "9", "11"])
|
||||
assert set(markings.get_markings(data, "x.z", True, True)) == set(["6", "9", "10", "11"])
|
||||
assert set(markings.get_markings(data, "x.z", False, True)) == set(["9", "10"])
|
||||
|
||||
assert set(markings.get_markings(data, "x.z.foo1", False, False)) == set([])
|
||||
assert set(markings.get_markings(data, "x.z.foo1", True, False)) == set(["6", "9", "11"])
|
||||
assert set(markings.get_markings(data, "x.z.foo1", True, True)) == set(["6", "9", "11"])
|
||||
assert set(markings.get_markings(data, "x.z.foo1", False, True)) == set([])
|
||||
|
||||
assert set(markings.get_markings(data, "x.z.foo2", False, False)) == set(["10"])
|
||||
assert set(markings.get_markings(data, "x.z.foo2", True, False)) == set(["6", "9", "10", "11"])
|
||||
assert set(markings.get_markings(data, "x.z.foo2", True, True)) == set(["6", "9", "10", "11"])
|
||||
assert set(markings.get_markings(data, "x.z.foo2", False, True)) == set(["10"])
|
||||
|
||||
|
||||
def test_remove_markings_object_level():
|
||||
after = {
|
||||
"title": "test title",
|
||||
"description": "test description"
|
||||
}
|
||||
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1"]
|
||||
}
|
||||
|
||||
markings.remove_markings(before, None, "marking-definition--1")
|
||||
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_markings_multiple():
|
||||
after = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--2"]
|
||||
}
|
||||
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1", "marking-definition--2", "marking-definition--3"]
|
||||
}
|
||||
|
||||
markings.remove_markings(before, None, ["marking-definition--1", "marking-definition--3"])
|
||||
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_remove_markings_bad_markings():
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1", "marking-definition--2", "marking-definition--3"]
|
||||
}
|
||||
with pytest.raises(AssertionError):
|
||||
markings.remove_markings(before, None, ["marking-definition--5"])
|
||||
|
||||
|
||||
def test_clear_markings():
|
||||
after = {
|
||||
"title": "test title",
|
||||
"description": "test description"
|
||||
}
|
||||
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1", "marking-definition--2", "marking-definition--3"]
|
||||
}
|
||||
|
||||
markings.clear_markings(before, None)
|
||||
|
||||
assert before == after
|
||||
|
||||
|
||||
def test_is_marked_object_and_granular_combinations():
|
||||
"""Test multiple combinations for inherited and descendant markings."""
|
||||
test_tlo = \
|
||||
{
|
||||
"a": 333,
|
||||
"b": "value",
|
||||
"c": [
|
||||
17,
|
||||
"list value",
|
||||
{
|
||||
"g": "nested",
|
||||
"h": 45
|
||||
}
|
||||
],
|
||||
"x": {
|
||||
"y": [
|
||||
"hello",
|
||||
88
|
||||
],
|
||||
"z": {
|
||||
"foo1": "bar",
|
||||
"foo2": 65
|
||||
}
|
||||
},
|
||||
"object_marking_refs": "11",
|
||||
"granular_markings": [
|
||||
{
|
||||
"marking_ref": "1",
|
||||
"selectors": ["a"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "2",
|
||||
"selectors": ["c"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "3",
|
||||
"selectors": ["c.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "4",
|
||||
"selectors": ["c.[2]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "5",
|
||||
"selectors": ["c.[2].g"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "6",
|
||||
"selectors": ["x"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "7",
|
||||
"selectors": ["x.y"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "8",
|
||||
"selectors": ["x.y.[1]"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "9",
|
||||
"selectors": ["x.z"]
|
||||
},
|
||||
{
|
||||
"marking_ref": "10",
|
||||
"selectors": ["x.z.foo2"]
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
assert markings.is_marked(test_tlo, "a", ["1"], False, False)
|
||||
assert markings.is_marked(test_tlo, "a", ["1", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "a", ["1", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "a", ["1"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "b", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "b", ["11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "b", ["11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "b", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "c", ["2"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c", ["2", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c", ["2", "3", "4", "5", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c", ["2", "3", "4", "5"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[0]", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "c.[0]", ["2", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[0]", ["2", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[0]", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["3"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["2", "3", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["2", "3", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[1]", ["3"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["4"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["2", "4", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["2", "4", "5", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[2]", ["4", "5"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["5"], False, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["2", "4", "5", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["2", "4", "5", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "c.[2].g", ["5"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x", ["6"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x", ["6", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x", ["6", "7", "8", "9", "10", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x", ["6", "7", "8", "9", "10"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.y", ["7"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.y", ["6", "7", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.y", ["6", "7", "8", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.y", ["7", "8"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", ["6", "7", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", ["6", "7", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.y.[0]", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["8"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["6", "7", "8", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["6", "7", "8", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.y.[1]", ["8"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.z", ["9"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.z", ["6", "9", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.z", ["6", "9", "10", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.z", ["9", "10"], False, True)
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", inherited=False, descendants=False) is False
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", ["6", "9", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", ["6", "9", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo1", inherited=False, descendants=True) is False
|
||||
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["10"], False, False)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["6", "9", "10", "11"], True, False)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["6", "9", "10", "11"], True, True)
|
||||
assert markings.is_marked(test_tlo, "x.z.foo2", ["10"], False, True)
|
||||
|
||||
|
||||
def test_set_marking():
|
||||
before = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--1", "marking-definition--2", "marking-definition--3"]
|
||||
}
|
||||
after = {
|
||||
"title": "test title",
|
||||
"description": "test description",
|
||||
"object_marking_refs": ["marking-definition--7", "marking-definition--9"]
|
||||
}
|
||||
|
||||
markings.set_markings(before, None, ["marking-definition--7", "marking-definition--9"])
|
||||
|
||||
for m in before["object_marking_refs"]:
|
||||
assert m in ["marking-definition--7", "marking-definition--9"]
|
||||
|
||||
assert ["marking-definition--1", "marking-definition--2", "marking-definition--3"] not in before["object_marking_refs"]
|
||||
|
||||
for x in before["object_marking_refs"]:
|
||||
assert x in after["object_marking_refs"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [
|
||||
([]),
|
||||
([""]),
|
||||
(""),
|
||||
(["marking-definition--7", 687])
|
||||
])
|
||||
def test_set_marking_bad_input(data):
|
||||
before = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"object_marking_refs": ["marking-definition--1"]
|
||||
}
|
||||
after = {
|
||||
"description": "test description",
|
||||
"title": "foo",
|
||||
"object_marking_refs": ["marking-definition--1"]
|
||||
}
|
||||
with pytest.raises(AssertionError):
|
||||
markings.set_markings(before, None, data)
|
||||
|
||||
assert before == after
|
Loading…
Reference in New Issue