diff --git a/stix2/base.py b/stix2/base.py index e018059..5af3607 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -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: diff --git a/stix2/custom.py b/stix2/custom.py index bd2fe1d..687618d 100644 --- a/stix2/custom.py +++ b/stix2/custom.py @@ -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) diff --git a/stix2/v20/base.py b/stix2/v20/base.py new file mode 100644 index 0000000..e32069a --- /dev/null +++ b/stix2/v20/base.py @@ -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 diff --git a/stix2/v20/bundle.py b/stix2/v20/bundle.py index ffd70ea..b811a79 100644 --- a/stix2/v20/bundle.py +++ b/stix2/v20/bundle.py @@ -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 `__. """ diff --git a/stix2/v20/common.py b/stix2/v20/common.py index a1ffa60..55f2c3e 100644 --- a/stix2/v20/common.py +++ b/stix2/v20/common.py @@ -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 `__. """ @@ -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 `__. """ @@ -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 `__. """ @@ -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 `__. """ @@ -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 `__. """ @@ -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 `__. """ @@ -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 diff --git a/stix2/v20/observables.py b/stix2/v20/observables.py index 81e2c48..eb9bfde 100644 --- a/stix2/v20/observables.py +++ b/stix2/v20/observables.py @@ -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 `__. """ # 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 `__. """ # 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 `__. """ # 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 `__. """ # 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 `__. """ # 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 `__. """ # 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 diff --git a/stix2/v20/sdo.py b/stix2/v20/sdo.py index 430bfc0..b083e42 100644 --- a/stix2/v20/sdo.py +++ b/stix2/v20/sdo.py @@ -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 diff --git a/stix2/v20/sro.py b/stix2/v20/sro.py index b85eb68..0a07969 100644 --- a/stix2/v20/sro.py +++ b/stix2/v20/sro.py @@ -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 diff --git a/stix2/v21/base.py b/stix2/v21/base.py new file mode 100644 index 0000000..bfe1d5e --- /dev/null +++ b/stix2/v21/base.py @@ -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 diff --git a/stix2/v21/bundle.py b/stix2/v21/bundle.py index 168771f..ca60fe0 100644 --- a/stix2/v21/bundle.py +++ b/stix2/v21/bundle.py @@ -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 `__. diff --git a/stix2/v21/common.py b/stix2/v21/common.py index ac8daf1..4254767 100644 --- a/stix2/v21/common.py +++ b/stix2/v21/common.py @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 diff --git a/stix2/v21/observables.py b/stix2/v21/observables.py index 8c9a2a1..e71e445 100644 --- a/stix2/v21/observables.py +++ b/stix2/v21/observables.py @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 `__. @@ -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 diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index f2dc0ea..42c58e4 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -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 diff --git a/stix2/v21/sro.py b/stix2/v21/sro.py index 059bb66..91b8b80 100644 --- a/stix2/v21/sro.py +++ b/stix2/v21/sro.py @@ -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