Rework spec version detection for _STIXBase objs

master
Chris Lenk 2020-03-21 22:22:36 -04:00
parent 2dea4caf00
commit e31634c32b
14 changed files with 113 additions and 70 deletions

View File

@ -79,11 +79,6 @@ def get_required_properties(properties):
class _STIXBase(Mapping):
"""Base class for STIX object types"""
def get_class_version(self):
module_name = self.__class__.__module__
module_parts = module_name.split(".")
return module_parts[1]
def object_properties(self):
props = set(self._properties.keys())
custom_props = list(set(self._inner.keys()) - props)
@ -175,7 +170,7 @@ class _STIXBase(Mapping):
if custom_props or extra_kwargs:
self._allow_custom = True
if self.get_class_version() == "v21":
if self._spec_version == "2.1":
all_custom_prop_names = extra_kwargs
all_custom_prop_names.extend(list(custom_props.keys()))
for prop_name in all_custom_prop_names:

View File

@ -3,18 +3,18 @@ import re
import six
from .base import _cls_init, _Extension, _Observable, _STIXBase
from .base import _cls_init
from .core import (
STIXDomainObject, _register_marking, _register_object,
_register_observable, _register_observable_extension,
_register_marking, _register_object, _register_observable,
_register_observable_extension,
)
from .utils import (
PREFIX_21_REGEX, TYPE_21_REGEX, TYPE_REGEX, get_class_hierarchy_names,
)
def _custom_object_builder(cls, type, properties, version):
class _CustomObject(cls, STIXDomainObject):
def _custom_object_builder(cls, type, properties, version, base_class):
class _CustomObject(cls, base_class):
if version == "2.0":
if not re.match(TYPE_REGEX, type):
@ -48,16 +48,16 @@ def _custom_object_builder(cls, type, properties, version):
_properties = OrderedDict(properties)
def __init__(self, **kwargs):
_STIXBase.__init__(self, **kwargs)
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
_register_object(_CustomObject, version=version)
return _CustomObject
def _custom_marking_builder(cls, type, properties, version):
def _custom_marking_builder(cls, type, properties, version, base_class):
class _CustomMarking(cls, _STIXBase):
class _CustomMarking(cls, base_class):
if not properties or not isinstance(properties, list):
raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]")
@ -66,18 +66,18 @@ def _custom_marking_builder(cls, type, properties, version):
_properties = OrderedDict(properties)
def __init__(self, **kwargs):
_STIXBase.__init__(self, **kwargs)
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
_register_marking(_CustomMarking, version=version)
return _CustomMarking
def _custom_observable_builder(cls, type, properties, version, id_contrib_props=None):
def _custom_observable_builder(cls, type, properties, version, base_class, id_contrib_props=None):
if id_contrib_props is None:
id_contrib_props = []
class _CustomObservable(cls, _Observable):
class _CustomObservable(cls, base_class):
if version == "2.0":
if not re.match(TYPE_REGEX, type):
@ -137,14 +137,14 @@ def _custom_observable_builder(cls, type, properties, version, id_contrib_props=
_id_contributing_properties = id_contrib_props
def __init__(self, **kwargs):
_Observable.__init__(self, **kwargs)
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
_register_observable(_CustomObservable, version=version)
return _CustomObservable
def _custom_extension_builder(cls, observable, type, properties, version):
def _custom_extension_builder(cls, observable, type, properties, version, base_class):
try:
prop_dict = OrderedDict(properties)
@ -158,13 +158,13 @@ def _custom_extension_builder(cls, observable, type, properties, version):
e,
)
class _CustomExtension(cls, _Extension):
class _CustomExtension(cls, base_class):
_type = type
_properties = prop_dict
def __init__(self, **kwargs):
_Extension.__init__(self, **kwargs)
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
_register_observable_extension(observable, _CustomExtension, version=version)

24
stix2/v20/base.py Normal file
View File

@ -0,0 +1,24 @@
"""Base classes for STIX 2.0 type definitions."""
from ..base import _Extension, _Observable, _STIXBase
from ..core import STIXDomainObject, STIXRelationshipObject
class _STIXBase20(_STIXBase):
_spec_version = "2.0"
class _Observable(_Observable, _STIXBase20):
pass
class _Extension(_Extension, _STIXBase20):
pass
class STIXDomainObject(STIXDomainObject, _STIXBase20):
pass
class STIXRelationshipObject(STIXRelationshipObject, _STIXBase20):
pass

View File

@ -2,13 +2,13 @@
from collections import OrderedDict
from ..base import _STIXBase
from ..properties import (
IDProperty, ListProperty, STIXObjectProperty, StringProperty, TypeProperty,
)
from .base import _STIXBase20
class Bundle(_STIXBase):
class Bundle(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709293>`__.
"""

View File

@ -5,7 +5,6 @@ import copy
import six
from ..base import _STIXBase
from ..custom import _custom_marking_builder
from ..markings import _MarkingsMixin
from ..markings.utils import check_tlp_marking
@ -14,6 +13,7 @@ from ..properties import (
SelectorProperty, StringProperty, TimestampProperty, TypeProperty,
)
from ..utils import NOW, _get_dict
from .base import _STIXBase20
def _should_set_millisecond(cr, marking_type):
@ -31,7 +31,7 @@ def _should_set_millisecond(cr, marking_type):
return False
class ExternalReference(_STIXBase):
class ExternalReference(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709261>`__.
"""
@ -49,7 +49,7 @@ class ExternalReference(_STIXBase):
self._check_at_least_one_property(['description', 'external_id', 'url'])
class KillChainPhase(_STIXBase):
class KillChainPhase(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709267>`__.
"""
@ -60,7 +60,7 @@ class KillChainPhase(_STIXBase):
])
class GranularMarking(_STIXBase):
class GranularMarking(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709290>`__.
"""
@ -71,7 +71,7 @@ class GranularMarking(_STIXBase):
])
class TLPMarking(_STIXBase):
class TLPMarking(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709287>`__.
"""
@ -83,7 +83,7 @@ class TLPMarking(_STIXBase):
])
class StatementMarking(_STIXBase):
class StatementMarking(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709286>`__.
"""
@ -113,7 +113,7 @@ class MarkingProperty(Property):
raise ValueError("must be a Statement, TLP Marking or a registered marking.")
class MarkingDefinition(_STIXBase, _MarkingsMixin):
class MarkingDefinition(_STIXBase20, _MarkingsMixin):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709284>`__.
"""
@ -182,7 +182,7 @@ def CustomMarking(type='x-custom-marking', properties=None):
"""
def wrapper(cls):
return _custom_marking_builder(cls, type, properties, '2.0')
return _custom_marking_builder(cls, type, properties, '2.0', _STIXBase20)
return wrapper

View File

@ -1,14 +1,13 @@
"""STIX 2.0 Cyber Observable Objects.
Embedded observable object types, such as Email MIME Component, which is
embedded in Email Message objects, inherit from ``_STIXBase`` instead of
Observable and do not have a ``_type`` attribute.
embedded in Email Message objects, inherit from ``_STIXBase20`` instead of
_Observable and do not have a ``_type`` attribute.
"""
from collections import OrderedDict
import itertools
from ..base import _Extension, _Observable, _STIXBase
from ..custom import _custom_extension_builder, _custom_observable_builder
from ..exceptions import AtLeastOnePropertyError, DependentPropertiesError
from ..properties import (
@ -17,6 +16,7 @@ from ..properties import (
HashesProperty, HexProperty, IntegerProperty, ListProperty,
ObjectReferenceProperty, StringProperty, TimestampProperty, TypeProperty,
)
from .base import _Extension, _Observable, _STIXBase20
class Artifact(_Observable):
@ -103,7 +103,7 @@ class EmailAddress(_Observable):
])
class EmailMIMEComponent(_STIXBase):
class EmailMIMEComponent(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part4-cyber-observable-objects/stix-v2.0-cs01-part4-cyber-observable-objects.html#_Toc496716231>`__.
""" # noqa
@ -166,7 +166,7 @@ class ArchiveExt(_Extension):
])
class AlternateDataStream(_STIXBase):
class AlternateDataStream(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part4-cyber-observable-objects/stix-v2.0-cs01-part4-cyber-observable-objects.html#_Toc496716239>`__.
""" # noqa
@ -220,7 +220,7 @@ class RasterImageExt(_Extension):
])
class WindowsPEOptionalHeaderType(_STIXBase):
class WindowsPEOptionalHeaderType(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part4-cyber-observable-objects/stix-v2.0-cs01-part4-cyber-observable-objects.html#_Toc496716248>`__.
""" # noqa
@ -264,7 +264,7 @@ class WindowsPEOptionalHeaderType(_STIXBase):
self._check_at_least_one_property()
class WindowsPESection(_STIXBase):
class WindowsPESection(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part4-cyber-observable-objects/stix-v2.0-cs01-part4-cyber-observable-objects.html#_Toc496716250>`__.
""" # noqa
@ -677,7 +677,7 @@ class UserAccount(_Observable):
])
class WindowsRegistryValueType(_STIXBase):
class WindowsRegistryValueType(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part4-cyber-observable-objects/stix-v2.0-cs01-part4-cyber-observable-objects.html#_Toc496716293>`__.
""" # noqa
@ -724,7 +724,7 @@ class WindowsRegistryKey(_Observable):
])
class X509V3ExtenstionsType(_STIXBase):
class X509V3ExtenstionsType(_STIXBase20):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part4-cyber-observable-objects/stix-v2.0-cs01-part4-cyber-observable-objects.html#_Toc496716298>`__.
""" # noqa
@ -795,7 +795,7 @@ def CustomObservable(type='x-custom-observable', properties=None):
properties,
[('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=type))],
]))
return _custom_observable_builder(cls, type, _properties, '2.0')
return _custom_observable_builder(cls, type, _properties, '2.0', _Observable)
return wrapper
@ -803,5 +803,5 @@ def CustomExtension(observable=None, type='x-custom-observable-ext', properties=
"""Decorator for custom extensions to STIX Cyber Observables.
"""
def wrapper(cls):
return _custom_extension_builder(cls, observable, type, properties, '2.0')
return _custom_extension_builder(cls, observable, type, properties, '2.0', _Extension)
return wrapper

View File

@ -5,7 +5,6 @@ import itertools
from stix2patterns.validator import run_validator
from ..core import STIXDomainObject
from ..custom import _custom_object_builder
from ..exceptions import InvalidValueError
from ..properties import (
@ -14,6 +13,7 @@ from ..properties import (
TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import STIXDomainObject
from .common import ExternalReference, GranularMarking, KillChainPhase
@ -374,5 +374,5 @@ def CustomObject(type='x-custom-type', properties=None):
],
sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]),
]))
return _custom_object_builder(cls, type, _properties, '2.0')
return _custom_object_builder(cls, type, _properties, '2.0', STIXDomainObject)
return wrapper

View File

@ -2,12 +2,12 @@
from collections import OrderedDict
from ..core import STIXRelationshipObject
from ..properties import (
BooleanProperty, IDProperty, IntegerProperty, ListProperty,
ReferenceProperty, StringProperty, TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import STIXRelationshipObject
from .common import ExternalReference, GranularMarking

24
stix2/v21/base.py Normal file
View File

@ -0,0 +1,24 @@
"""Base classes for STIX 2.1 type definitions."""
from ..base import _Extension, _Observable, _STIXBase
from ..core import STIXDomainObject, STIXRelationshipObject
class _STIXBase21(_STIXBase):
_spec_version = "2.1"
class _Observable(_Observable, _STIXBase21):
pass
class _Extension(_Extension, _STIXBase21):
pass
class STIXDomainObject(STIXDomainObject, _STIXBase21):
pass
class STIXRelationshipObject(STIXRelationshipObject, _STIXBase21):
pass

View File

@ -2,13 +2,13 @@
from collections import OrderedDict
from ..base import _STIXBase
from ..properties import (
IDProperty, ListProperty, STIXObjectProperty, TypeProperty,
)
from .base import _STIXBase21
class Bundle(_STIXBase):
class Bundle(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.

View File

@ -2,7 +2,6 @@
from collections import OrderedDict
from ..base import _STIXBase
from ..custom import _custom_marking_builder
from ..exceptions import InvalidValueError
from ..markings import _MarkingsMixin
@ -13,9 +12,10 @@ from ..properties import (
SelectorProperty, StringProperty, TimestampProperty, TypeProperty,
)
from ..utils import NOW, _get_dict
from .base import _STIXBase21
class ExternalReference(_STIXBase):
class ExternalReference(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -50,7 +50,7 @@ class ExternalReference(_STIXBase):
)
class KillChainPhase(_STIXBase):
class KillChainPhase(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -62,7 +62,7 @@ class KillChainPhase(_STIXBase):
])
class GranularMarking(_STIXBase):
class GranularMarking(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -79,7 +79,7 @@ class GranularMarking(_STIXBase):
self._check_at_least_one_property(['lang', 'marking_ref'])
class LanguageContent(_STIXBase):
class LanguageContent(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -107,7 +107,7 @@ class LanguageContent(_STIXBase):
])
class TLPMarking(_STIXBase):
class TLPMarking(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -119,7 +119,7 @@ class TLPMarking(_STIXBase):
])
class StatementMarking(_STIXBase):
class StatementMarking(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -150,7 +150,7 @@ class MarkingProperty(Property):
raise ValueError("must be a Statement, TLP Marking or a registered marking.")
class MarkingDefinition(_STIXBase, _MarkingsMixin):
class MarkingDefinition(_STIXBase21, _MarkingsMixin):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -215,7 +215,7 @@ def CustomMarking(type='x-custom-marking', properties=None):
"""
def wrapper(cls):
return _custom_marking_builder(cls, type, properties, '2.1')
return _custom_marking_builder(cls, type, properties, '2.1', _STIXBase21)
return wrapper

View File

@ -1,14 +1,13 @@
"""STIX 2.1 Cyber Observable Objects.
Embedded observable object types, such as Email MIME Component, which is
embedded in Email Message objects, inherit from ``_STIXBase`` instead of
Observable and do not have a ``_type`` attribute.
embedded in Email Message objects, inherit from ``_STIXBase21`` instead of
_Observable and do not have a ``_type`` attribute.
"""
from collections import OrderedDict
import itertools
from ..base import _Extension, _Observable, _STIXBase
from ..custom import _custom_extension_builder, _custom_observable_builder
from ..exceptions import AtLeastOnePropertyError, DependentPropertiesError
from ..properties import (
@ -18,6 +17,7 @@ from ..properties import (
ObjectReferenceProperty, ReferenceProperty, StringProperty,
TimestampProperty, TypeProperty,
)
from .base import _Extension, _Observable, _STIXBase21
from .common import GranularMarking
@ -142,7 +142,7 @@ class EmailAddress(_Observable):
_id_contributing_properties = ["value"]
class EmailMIMEComponent(_STIXBase):
class EmailMIMEComponent(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -214,7 +214,7 @@ class ArchiveExt(_Extension):
])
class AlternateDataStream(_STIXBase):
class AlternateDataStream(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -271,7 +271,7 @@ class RasterImageExt(_Extension):
])
class WindowsPEOptionalHeaderType(_STIXBase):
class WindowsPEOptionalHeaderType(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -316,7 +316,7 @@ class WindowsPEOptionalHeaderType(_STIXBase):
self._check_at_least_one_property()
class WindowsPESection(_STIXBase):
class WindowsPESection(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -841,7 +841,7 @@ class UserAccount(_Observable):
_id_contributing_properties = ["account_type", "user_id", "account_login"]
class WindowsRegistryValueType(_STIXBase):
class WindowsRegistryValueType(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -896,7 +896,7 @@ class WindowsRegistryKey(_Observable):
_id_contributing_properties = ["key", "values"]
class X509V3ExtenstionsType(_STIXBase):
class X509V3ExtenstionsType(_STIXBase21):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <link here>`__.
@ -988,7 +988,7 @@ def CustomObservable(type='x-custom-observable', properties=None, id_contrib_pro
properties,
[('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=type))],
]))
return _custom_observable_builder(cls, type, _properties, '2.1', id_contrib_props)
return _custom_observable_builder(cls, type, _properties, '2.1', _Observable, id_contrib_props)
return wrapper
@ -996,5 +996,5 @@ def CustomExtension(observable=None, type='x-custom-observable-ext', properties=
"""Decorator for custom extensions to STIX Cyber Observables.
"""
def wrapper(cls):
return _custom_extension_builder(cls, observable, type, properties, '2.1')
return _custom_extension_builder(cls, observable, type, properties, '2.1', _Extension)
return wrapper

View File

@ -7,7 +7,6 @@ import warnings
from six.moves.urllib.parse import quote_plus
from stix2patterns.validator import run_validator
from ..core import STIXDomainObject
from ..custom import _custom_object_builder
from ..exceptions import (
InvalidValueError, PropertyPresenceError, STIXDeprecationWarning,
@ -18,6 +17,7 @@ from ..properties import (
StringProperty, TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import STIXDomainObject
from .common import ExternalReference, GranularMarking, KillChainPhase
@ -828,6 +828,6 @@ def CustomObject(type='x-custom-type', properties=None):
],
sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]),
]))
return _custom_object_builder(cls, type, _properties, '2.1')
return _custom_object_builder(cls, type, _properties, '2.1', STIXDomainObject)
return wrapper

View File

@ -2,12 +2,12 @@
from collections import OrderedDict
from ..core import STIXRelationshipObject
from ..properties import (
BooleanProperty, IDProperty, IntegerProperty, ListProperty,
ReferenceProperty, StringProperty, TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import STIXRelationshipObject
from .common import ExternalReference, GranularMarking