update marking API methods to allow/use the 'lang' property
including utility methods that expand collapse markingsmaster
parent
f8d4669f80
commit
4bbabaecb2
|
@ -22,7 +22,7 @@ Note:
|
||||||
from stix2.markings import granular_markings, object_markings
|
from stix2.markings import granular_markings, object_markings
|
||||||
|
|
||||||
|
|
||||||
def get_markings(obj, selectors=None, inherited=False, descendants=False):
|
def get_markings(obj, selectors=None, inherited=False, descendants=False, marking_ref=True, lang=True):
|
||||||
"""
|
"""
|
||||||
Get all markings associated to the field(s) specified by selectors.
|
Get all markings associated to the field(s) specified by selectors.
|
||||||
|
|
||||||
|
@ -30,10 +30,13 @@ def get_markings(obj, selectors=None, inherited=False, descendants=False):
|
||||||
obj: An SDO or SRO object.
|
obj: An SDO or SRO object.
|
||||||
selectors: string or list of selectors strings relative to the SDO or
|
selectors: string or list of selectors strings relative to the SDO or
|
||||||
SRO in which the properties appear.
|
SRO in which the properties appear.
|
||||||
inherited: If True, include object level markings and granular markings
|
inherited (bool): If True, include object level markings and granular
|
||||||
inherited relative to the properties.
|
markings inherited relative to the properties.
|
||||||
descendants: If True, include granular markings applied to any children
|
descendants (bool): If True, include granular markings applied to any
|
||||||
relative to the properties.
|
children relative to the properties.
|
||||||
|
marking_ref (bool): If False, excludes markings that use
|
||||||
|
``marking_ref`` property.
|
||||||
|
lang (bool): If False, excludes markings that use ``lang`` property.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: Marking identifiers that matched the selectors expression.
|
list: Marking identifiers that matched the selectors expression.
|
||||||
|
@ -51,6 +54,8 @@ def get_markings(obj, selectors=None, inherited=False, descendants=False):
|
||||||
selectors,
|
selectors,
|
||||||
inherited,
|
inherited,
|
||||||
descendants,
|
descendants,
|
||||||
|
marking_ref,
|
||||||
|
lang
|
||||||
)
|
)
|
||||||
|
|
||||||
if inherited:
|
if inherited:
|
||||||
|
@ -59,7 +64,7 @@ def get_markings(obj, selectors=None, inherited=False, descendants=False):
|
||||||
return list(set(results))
|
return list(set(results))
|
||||||
|
|
||||||
|
|
||||||
def set_markings(obj, marking, selectors=None):
|
def set_markings(obj, marking, selectors=None, marking_ref=True, lang=True):
|
||||||
"""
|
"""
|
||||||
Remove all markings associated with selectors and appends a new granular
|
Remove all markings associated with selectors and appends a new granular
|
||||||
marking. Refer to `clear_markings` and `add_markings` for details.
|
marking. Refer to `clear_markings` and `add_markings` for details.
|
||||||
|
@ -70,6 +75,10 @@ def set_markings(obj, marking, selectors=None):
|
||||||
properties selected by `selectors`.
|
properties selected by `selectors`.
|
||||||
selectors: string or list of selectors strings relative to the SDO or
|
selectors: string or list of selectors strings relative to the SDO or
|
||||||
SRO in which the properties appear.
|
SRO in which the properties appear.
|
||||||
|
marking_ref (bool): If False, markings that use the ``marking_ref``
|
||||||
|
property will not be removed.
|
||||||
|
lang (bool): If False, markings that use the ``lang`` property
|
||||||
|
will not be removed.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A new version of the given SDO or SRO with specified markings removed
|
A new version of the given SDO or SRO with specified markings removed
|
||||||
|
@ -83,7 +92,7 @@ def set_markings(obj, marking, selectors=None):
|
||||||
if selectors is None:
|
if selectors is None:
|
||||||
return object_markings.set_markings(obj, marking)
|
return object_markings.set_markings(obj, marking)
|
||||||
else:
|
else:
|
||||||
return granular_markings.set_markings(obj, marking, selectors)
|
return granular_markings.set_markings(obj, marking, selectors, marking_ref, lang)
|
||||||
|
|
||||||
|
|
||||||
def remove_markings(obj, marking, selectors=None):
|
def remove_markings(obj, marking, selectors=None):
|
||||||
|
@ -144,7 +153,7 @@ def add_markings(obj, marking, selectors=None):
|
||||||
return granular_markings.add_markings(obj, marking, selectors)
|
return granular_markings.add_markings(obj, marking, selectors)
|
||||||
|
|
||||||
|
|
||||||
def clear_markings(obj, selectors=None):
|
def clear_markings(obj, selectors=None, marking_ref=True, lang=True):
|
||||||
"""
|
"""
|
||||||
Remove all markings associated with the selectors.
|
Remove all markings associated with the selectors.
|
||||||
|
|
||||||
|
@ -152,6 +161,10 @@ def clear_markings(obj, selectors=None):
|
||||||
obj: An SDO or SRO object.
|
obj: An SDO or SRO object.
|
||||||
selectors: string or list of selectors strings relative to the SDO or
|
selectors: string or list of selectors strings relative to the SDO or
|
||||||
SRO in which the field(s) appear(s).
|
SRO in which the field(s) appear(s).
|
||||||
|
marking_ref (bool): If False, markings that use the ``marking_ref``
|
||||||
|
property will not be removed.
|
||||||
|
lang (bool): If False, markings that use the ``lang`` property
|
||||||
|
will not be removed.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
InvalidSelectorError: If `selectors` fail validation.
|
InvalidSelectorError: If `selectors` fail validation.
|
||||||
|
@ -169,7 +182,7 @@ def clear_markings(obj, selectors=None):
|
||||||
if selectors is None:
|
if selectors is None:
|
||||||
return object_markings.clear_markings(obj)
|
return object_markings.clear_markings(obj)
|
||||||
else:
|
else:
|
||||||
return granular_markings.clear_markings(obj, selectors)
|
return granular_markings.clear_markings(obj, selectors, marking_ref, lang)
|
||||||
|
|
||||||
|
|
||||||
def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=False):
|
def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=False):
|
||||||
|
@ -182,10 +195,11 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa
|
||||||
properties selected by `selectors`.
|
properties selected by `selectors`.
|
||||||
selectors: string or list of selectors strings relative to the SDO or
|
selectors: string or list of selectors strings relative to the SDO or
|
||||||
SRO in which the field(s) appear(s).
|
SRO in which the field(s) appear(s).
|
||||||
inherited: If True, include object level markings and granular markings
|
inherited (bool): If True, include object level markings and granular
|
||||||
inherited to determine if the properties is/are marked.
|
markings inherited to determine if the properties is/are marked.
|
||||||
descendants: If True, include granular markings applied to any children
|
descendants (bool): If True, include granular markings applied to any
|
||||||
of the given selector to determine if the properties is/are marked.
|
children of the given selector to determine if the properties
|
||||||
|
is/are marked.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if ``selectors`` is found on internal SDO or SRO collection.
|
bool: True if ``selectors`` is found on internal SDO or SRO collection.
|
||||||
|
@ -228,7 +242,7 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class _MarkingsMixin():
|
class _MarkingsMixin(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
from stix2 import exceptions
|
from stix2 import exceptions
|
||||||
from stix2.markings import utils
|
from stix2.markings import utils
|
||||||
from stix2.utils import new_version
|
from stix2.utils import new_version, is_marking
|
||||||
|
|
||||||
|
|
||||||
def get_markings(obj, selectors, inherited=False, descendants=False):
|
def get_markings(obj, selectors, inherited=False, descendants=False, marking_ref=True, lang=True):
|
||||||
"""
|
"""
|
||||||
Get all granular markings associated to with the properties.
|
Get all granular markings associated to with the properties.
|
||||||
|
|
||||||
|
@ -13,10 +13,13 @@ def get_markings(obj, selectors, inherited=False, descendants=False):
|
||||||
obj: An SDO or SRO object.
|
obj: An SDO or SRO object.
|
||||||
selectors: string or list of selector strings relative to the SDO or
|
selectors: string or list of selector strings relative to the SDO or
|
||||||
SRO in which the properties appear.
|
SRO in which the properties appear.
|
||||||
inherited: If True, include markings inherited relative to the
|
inherited (bool): If True, include markings inherited relative to the
|
||||||
properties.
|
properties.
|
||||||
descendants: If True, include granular markings applied to any children
|
descendants (bool): If True, include granular markings applied to any
|
||||||
relative to the properties.
|
children relative to the properties.
|
||||||
|
marking_ref (bool): If False, excludes markings that use
|
||||||
|
``marking_ref`` property.
|
||||||
|
lang (bool): If False, excludes markings that use ``lang`` property.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
InvalidSelectorError: If `selectors` fail validation.
|
InvalidSelectorError: If `selectors` fail validation.
|
||||||
|
@ -43,13 +46,18 @@ def get_markings(obj, selectors, inherited=False, descendants=False):
|
||||||
(user_selector.startswith(marking_selector) and inherited), # Catch inherited selectors.
|
(user_selector.startswith(marking_selector) and inherited), # Catch inherited selectors.
|
||||||
(marking_selector.startswith(user_selector) and descendants),
|
(marking_selector.startswith(user_selector) and descendants),
|
||||||
]): # Catch descendants selectors
|
]): # Catch descendants selectors
|
||||||
refs = marking.get('marking_ref', [])
|
ref = marking.get('marking_ref')
|
||||||
results.update([refs])
|
lng = marking.get('lang')
|
||||||
|
|
||||||
|
if ref and marking_ref:
|
||||||
|
results.add(ref)
|
||||||
|
if lng and lang:
|
||||||
|
results.add(lng)
|
||||||
|
|
||||||
return list(results)
|
return list(results)
|
||||||
|
|
||||||
|
|
||||||
def set_markings(obj, marking, selectors):
|
def set_markings(obj, marking, selectors, marking_ref=True, lang=True):
|
||||||
"""
|
"""
|
||||||
Remove all granular markings associated with selectors and append a new
|
Remove all granular markings associated with selectors and append a new
|
||||||
granular marking. Refer to `clear_markings` and `add_markings` for details.
|
granular marking. Refer to `clear_markings` and `add_markings` for details.
|
||||||
|
@ -60,19 +68,25 @@ def set_markings(obj, marking, selectors):
|
||||||
SRO in which the properties appear.
|
SRO in which the properties appear.
|
||||||
marking: identifier or list of marking identifiers that apply to the
|
marking: identifier or list of marking identifiers that apply to the
|
||||||
properties selected by `selectors`.
|
properties selected by `selectors`.
|
||||||
|
marking_ref (bool): If False, markings that use the ``marking_ref``
|
||||||
|
property will not be removed.
|
||||||
|
lang (bool): If False, markings that use the ``lang`` property
|
||||||
|
will not be removed.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A new version of the given SDO or SRO with specified markings removed
|
A new version of the given SDO or SRO with specified markings removed
|
||||||
and new ones added.
|
and new ones added.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
obj = clear_markings(obj, selectors)
|
obj = clear_markings(obj, selectors, marking_ref, lang)
|
||||||
return add_markings(obj, marking, selectors)
|
return add_markings(obj, marking, selectors)
|
||||||
|
|
||||||
|
|
||||||
def remove_markings(obj, marking, selectors):
|
def remove_markings(obj, marking, selectors):
|
||||||
"""
|
"""
|
||||||
Remove a granular marking from the granular_markings collection.
|
Remove a granular marking from the granular_markings collection. The method
|
||||||
|
makes a best-effort attempt to distinguish between a marking-definition
|
||||||
|
or language granular marking.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
obj: An SDO or SRO object.
|
obj: An SDO or SRO object.
|
||||||
|
@ -103,7 +117,10 @@ def remove_markings(obj, marking, selectors):
|
||||||
|
|
||||||
to_remove = []
|
to_remove = []
|
||||||
for m in marking:
|
for m in marking:
|
||||||
to_remove.append({'marking_ref': m, 'selectors': selectors})
|
if is_marking(m):
|
||||||
|
to_remove.append({'marking_ref': m, 'selectors': selectors})
|
||||||
|
else:
|
||||||
|
to_remove.append({'lang': m, 'selectors': selectors})
|
||||||
|
|
||||||
remove = utils.build_granular_marking(to_remove).get('granular_markings')
|
remove = utils.build_granular_marking(to_remove).get('granular_markings')
|
||||||
|
|
||||||
|
@ -124,7 +141,9 @@ def remove_markings(obj, marking, selectors):
|
||||||
|
|
||||||
def add_markings(obj, marking, selectors):
|
def add_markings(obj, marking, selectors):
|
||||||
"""
|
"""
|
||||||
Append a granular marking to the granular_markings collection.
|
Append a granular marking to the granular_markings collection. The method
|
||||||
|
makes a best-effort attempt to distinguish between a marking-definition
|
||||||
|
or language granular marking.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
obj: An SDO or SRO object.
|
obj: An SDO or SRO object.
|
||||||
|
@ -146,7 +165,10 @@ def add_markings(obj, marking, selectors):
|
||||||
|
|
||||||
granular_marking = []
|
granular_marking = []
|
||||||
for m in marking:
|
for m in marking:
|
||||||
granular_marking.append({'marking_ref': m, 'selectors': sorted(selectors)})
|
if is_marking(m):
|
||||||
|
granular_marking.append({'marking_ref': m, 'selectors': sorted(selectors)})
|
||||||
|
else:
|
||||||
|
granular_marking.append({'lang': m, 'selectors': sorted(selectors)})
|
||||||
|
|
||||||
if obj.get('granular_markings'):
|
if obj.get('granular_markings'):
|
||||||
granular_marking.extend(obj.get('granular_markings'))
|
granular_marking.extend(obj.get('granular_markings'))
|
||||||
|
@ -156,7 +178,7 @@ def add_markings(obj, marking, selectors):
|
||||||
return new_version(obj, granular_markings=granular_marking, allow_custom=True)
|
return new_version(obj, granular_markings=granular_marking, allow_custom=True)
|
||||||
|
|
||||||
|
|
||||||
def clear_markings(obj, selectors):
|
def clear_markings(obj, selectors, marking_ref=True, lang=True):
|
||||||
"""
|
"""
|
||||||
Remove all granular markings associated with the selectors.
|
Remove all granular markings associated with the selectors.
|
||||||
|
|
||||||
|
@ -164,6 +186,10 @@ def clear_markings(obj, selectors):
|
||||||
obj: An SDO or SRO object.
|
obj: An SDO or SRO object.
|
||||||
selectors: string or list of selectors strings relative to the SDO or
|
selectors: string or list of selectors strings relative to the SDO or
|
||||||
SRO in which the properties appear.
|
SRO in which the properties appear.
|
||||||
|
marking_ref (bool): If False, markings that use the ``marking_ref``
|
||||||
|
property will not be removed.
|
||||||
|
lang (bool): If False, markings that use the ``lang`` property
|
||||||
|
will not be removed.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
InvalidSelectorError: If `selectors` fail validation.
|
InvalidSelectorError: If `selectors` fail validation.
|
||||||
|
@ -184,11 +210,12 @@ def clear_markings(obj, selectors):
|
||||||
|
|
||||||
granular_markings = utils.expand_markings(granular_markings)
|
granular_markings = utils.expand_markings(granular_markings)
|
||||||
|
|
||||||
sdo = utils.build_granular_marking(
|
granular_dict = utils.build_granular_marking([
|
||||||
[{'selectors': selectors, 'marking_ref': 'N/A'}],
|
{'selectors': selectors, 'marking_ref': 'N/A'},
|
||||||
)
|
{'selectors': selectors, 'lang': 'N/A'}
|
||||||
|
])
|
||||||
|
|
||||||
clear = sdo.get('granular_markings', [])
|
clear = granular_dict.get('granular_markings', [])
|
||||||
|
|
||||||
if not any(
|
if not any(
|
||||||
clear_selector in sdo_selectors.get('selectors', [])
|
clear_selector in sdo_selectors.get('selectors', [])
|
||||||
|
@ -201,10 +228,13 @@ def clear_markings(obj, selectors):
|
||||||
for granular_marking in granular_markings:
|
for granular_marking in granular_markings:
|
||||||
for s in selectors:
|
for s in selectors:
|
||||||
if s in granular_marking.get('selectors', []):
|
if s in granular_marking.get('selectors', []):
|
||||||
marking_refs = granular_marking.get('marking_ref')
|
ref = granular_marking.get('marking_ref')
|
||||||
|
lng = granular_marking.get('lang')
|
||||||
|
|
||||||
if marking_refs:
|
if ref and marking_ref:
|
||||||
granular_marking['marking_ref'] = ''
|
granular_marking['marking_ref'] = ''
|
||||||
|
if lng and lang:
|
||||||
|
granular_marking['lang'] = ''
|
||||||
|
|
||||||
granular_markings = utils.compress_markings(granular_markings)
|
granular_markings = utils.compress_markings(granular_markings)
|
||||||
|
|
||||||
|
@ -222,11 +252,12 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa
|
||||||
obj: An SDO or SRO object.
|
obj: An SDO or SRO object.
|
||||||
marking: identifier or list of marking identifiers that apply to the
|
marking: identifier or list of marking identifiers that apply to the
|
||||||
properties selected by `selectors`.
|
properties selected by `selectors`.
|
||||||
selectors: string or list of selectors strings relative to the SDO or
|
selectors (bool): string or list of selectors strings relative to the
|
||||||
SRO in which the properties appear.
|
SDO or SRO in which the properties appear.
|
||||||
inherited: If True, return markings inherited from the given selector.
|
inherited (bool): If True, return markings inherited from the given
|
||||||
descendants: If True, return granular markings applied to any children
|
selector.
|
||||||
of the given selector.
|
descendants (bool): If True, return granular markings applied to any
|
||||||
|
children of the given selector.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
InvalidSelectorError: If `selectors` fail validation.
|
InvalidSelectorError: If `selectors` fail validation.
|
||||||
|
@ -262,9 +293,12 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa
|
||||||
(marking_selector.startswith(user_selector) and descendants),
|
(marking_selector.startswith(user_selector) and descendants),
|
||||||
]): # Catch descendants selectors
|
]): # Catch descendants selectors
|
||||||
marking_ref = granular_marking.get('marking_ref', '')
|
marking_ref = granular_marking.get('marking_ref', '')
|
||||||
|
lang = granular_marking.get('lang', '')
|
||||||
|
|
||||||
if marking and any(x == marking_ref for x in marking):
|
if marking and any(x == marking_ref for x in marking):
|
||||||
markings.update([marking_ref])
|
markings.update([marking_ref])
|
||||||
|
if marking and any(x == lang for x in marking):
|
||||||
|
markings.update([lang])
|
||||||
|
|
||||||
marked = True
|
marked = True
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import collections
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from stix2 import exceptions
|
from stix2 import exceptions
|
||||||
|
from stix2.utils import is_marking
|
||||||
|
|
||||||
|
|
||||||
def _evaluate_expression(obj, selector):
|
def _evaluate_expression(obj, selector):
|
||||||
|
@ -121,10 +122,15 @@ def compress_markings(granular_markings):
|
||||||
if granular_marking.get('marking_ref'):
|
if granular_marking.get('marking_ref'):
|
||||||
map_[granular_marking.get('marking_ref')].update(granular_marking.get('selectors'))
|
map_[granular_marking.get('marking_ref')].update(granular_marking.get('selectors'))
|
||||||
|
|
||||||
|
if granular_marking.get('lang'):
|
||||||
|
map_[granular_marking.get('lang')].update(granular_marking.get('selectors'))
|
||||||
|
|
||||||
compressed = \
|
compressed = \
|
||||||
[
|
[
|
||||||
{'marking_ref': marking_ref, 'selectors': sorted(selectors)}
|
{'marking_ref': item, 'selectors': sorted(selectors)}
|
||||||
for marking_ref, selectors in six.iteritems(map_)
|
if is_marking(item) else
|
||||||
|
{'lang': item, 'selectors': sorted(selectors)}
|
||||||
|
for item, selectors in six.iteritems(map_)
|
||||||
]
|
]
|
||||||
|
|
||||||
return compressed
|
return compressed
|
||||||
|
@ -174,13 +180,22 @@ def expand_markings(granular_markings):
|
||||||
for marking in granular_markings:
|
for marking in granular_markings:
|
||||||
selectors = marking.get('selectors')
|
selectors = marking.get('selectors')
|
||||||
marking_ref = marking.get('marking_ref')
|
marking_ref = marking.get('marking_ref')
|
||||||
|
lang = marking.get('lang')
|
||||||
|
|
||||||
expanded.extend(
|
if marking_ref:
|
||||||
[
|
expanded.extend(
|
||||||
{'marking_ref': marking_ref, 'selectors': [selector]}
|
[
|
||||||
for selector in selectors
|
{'marking_ref': marking_ref, 'selectors': [selector]}
|
||||||
],
|
for selector in selectors
|
||||||
)
|
],
|
||||||
|
)
|
||||||
|
if lang:
|
||||||
|
expanded.extend(
|
||||||
|
[
|
||||||
|
{'lang': lang, 'selectors': [selector]}
|
||||||
|
for selector in selectors
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
return expanded
|
return expanded
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue