"""Functions for working with STIX2 object markings.""" from stix2 import exceptions from stix2.markings import utils from stix2.utils import new_version 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 identifiers 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): """ Append 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. Returns: A new version of the given SDO or SRO with specified markings added. """ marking = utils.convert_to_marking_list(marking) object_markings = set(obj.get('object_marking_refs', []) + marking) return new_version(obj, object_marking_refs=list(object_markings), allow_custom=True) def remove_markings(obj, marking): """ Remove an 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: MarkingNotFoundError: If markings to remove are not found on the provided SDO or SRO. Returns: A new version of the given SDO or SRO with specified markings removed. """ marking = utils.convert_to_marking_list(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 exceptions.MarkingNotFoundError(obj, marking) new_markings = [x for x in object_markings if x not in marking] if new_markings: return new_version(obj, object_marking_refs=new_markings, allow_custom=True) else: return new_version(obj, object_marking_refs=None, allow_custom=True) def set_markings(obj, marking): """ Remove all object level markings and append 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. Returns: A new version of the given SDO or SRO with specified markings removed and new ones added. """ return add_markings(clear_markings(obj), marking) def clear_markings(obj): """ Remove all object level markings from the object_marking_refs collection. Args: obj: A SDO or SRO object. Returns: A new version of the given SDO or SRO with object_marking_refs cleared. """ return new_version(obj, object_marking_refs=None, allow_custom=True) def is_marked(obj, marking=None): """ Check 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_marking_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)