Merge pull request #384 from oasis-open/365-versioned-classes

Validate custom type/property name formats
master
Chris Lenk 2020-04-03 17:30:24 -04:00 committed by GitHub
commit df92770d25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 667 additions and 393 deletions

View File

@ -23,7 +23,6 @@
DEFAULT_VERSION = '2.0' # Default version will always be the latest STIX 2.X version
from .confidence import scales
from .core import _collect_stix2_mappings, parse, parse_observable
from .datastore import CompositeDataSource
from .datastore.filesystem import (
FileSystemSink, FileSystemSource, FileSystemStore,
@ -38,6 +37,7 @@ from .markings import (
add_markings, clear_markings, get_markings, is_marked, remove_markings,
set_markings,
)
from .parsing import _collect_stix2_mappings, parse, parse_observable
from .patterns import (
AndBooleanExpression, AndObservationExpression, BasicObjectPathComponent,
BinaryConstant, BooleanConstant, EqualityComparisonExpression,

View File

@ -2,11 +2,13 @@
import copy
import datetime as dt
import re
import uuid
import simplejson as json
import six
import stix2
from stix2.canonicalization.Canonicalize import canonicalize
from .exceptions import (
@ -14,8 +16,11 @@ from .exceptions import (
ImmutableError, InvalidObjRefError, InvalidValueError,
MissingPropertiesError, MutuallyExclusivePropertiesError,
)
from .markings import _MarkingsMixin
from .markings.utils import validate
from .utils import NOW, find_property_index, format_datetime, get_timestamp
from .utils import (
NOW, PREFIX_21_REGEX, find_property_index, format_datetime, get_timestamp,
)
from .utils import new_version as _new_version
from .utils import revoke as _revoke
@ -157,12 +162,23 @@ class _STIXBase(Mapping):
custom_props = kwargs.pop('custom_properties', {})
if custom_props and not isinstance(custom_props, dict):
raise ValueError("'custom_properties' must be a dictionary")
if not self._allow_custom:
extra_kwargs = list(set(kwargs) - set(self._properties))
if extra_kwargs:
raise ExtraPropertiesError(cls, extra_kwargs)
if custom_props:
extra_kwargs = list(set(kwargs) - set(self._properties))
if extra_kwargs and not self._allow_custom:
raise ExtraPropertiesError(cls, extra_kwargs)
# because allow_custom is true, any extra kwargs are custom
if custom_props or extra_kwargs:
self._allow_custom = True
if isinstance(self, stix2.v21._STIXBase21):
all_custom_prop_names = extra_kwargs
all_custom_prop_names.extend(list(custom_props.keys()))
for prop_name in all_custom_prop_names:
if not re.match(PREFIX_21_REGEX, prop_name):
raise InvalidValueError(
self.__class__, prop_name,
reason="Property name '%s' must begin with an alpha character." % prop_name,
)
# Remove any keyword arguments whose value is None or [] (i.e. empty list)
setting_kwargs = {}
@ -305,6 +321,14 @@ class _STIXBase(Mapping):
return json.dumps(self, cls=STIXJSONEncoder, **kwargs)
class _DomainObject(_STIXBase, _MarkingsMixin):
pass
class _RelationshipObject(_STIXBase, _MarkingsMixin):
pass
class _Observable(_STIXBase):
def __init__(self, **kwargs):

View File

@ -1,140 +1,91 @@
from collections import OrderedDict
import re
import six
from .base import _cls_init, _Extension, _Observable, _STIXBase
from .core import (
STIXDomainObject, _register_marking, _register_object,
_register_observable, _register_observable_extension,
from .base import _cls_init
from .parsing import (
_register_marking, _register_object, _register_observable,
_register_observable_extension,
)
from .utils import TYPE_REGEX, get_class_hierarchy_names
def _custom_object_builder(cls, type, properties, version):
class _CustomObject(cls, STIXDomainObject):
if not re.match(TYPE_REGEX, type):
raise ValueError(
"Invalid type name '%s': must only contain the "
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." % type,
)
elif len(type) < 3 or len(type) > 250:
raise ValueError(
"Invalid type name '%s': must be between 3 and 250 characters." % type,
)
if not properties or not isinstance(properties, list):
raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]")
_type = type
_properties = OrderedDict(properties)
def __init__(self, **kwargs):
_STIXBase.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
_register_object(_CustomObject, version=version)
return _CustomObject
def _custom_marking_builder(cls, type, properties, version):
class _CustomMarking(cls, _STIXBase):
if not properties or not isinstance(properties, list):
raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]")
_type = type
_properties = OrderedDict(properties)
def __init__(self, **kwargs):
_STIXBase.__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):
if id_contrib_props is None:
id_contrib_props = []
class _CustomObservable(cls, _Observable):
if not re.match(TYPE_REGEX, type):
raise ValueError(
"Invalid observable type name '%s': must only contain the "
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." % type,
)
elif len(type) < 3 or len(type) > 250:
raise ValueError("Invalid observable type name '%s': must be between 3 and 250 characters." % type)
if not properties or not isinstance(properties, list):
raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]")
if version == "2.0":
# If using STIX2.0, check properties ending in "_ref/s" are ObjectReferenceProperties
for prop_name, prop in properties:
if prop_name.endswith('_ref') and ('ObjectReferenceProperty' not in get_class_hierarchy_names(prop)):
raise ValueError(
"'%s' is named like an object reference property but "
"is not an ObjectReferenceProperty." % prop_name,
)
elif (prop_name.endswith('_refs') and ('ListProperty' not in get_class_hierarchy_names(prop) or
'ObjectReferenceProperty' not in get_class_hierarchy_names(prop.contained))):
raise ValueError(
"'%s' is named like an object reference list property but "
"is not a ListProperty containing ObjectReferenceProperty." % prop_name,
)
else:
# If using STIX2.1 (or newer...), check properties ending in "_ref/s" are ReferenceProperties
for prop_name, prop in properties:
if prop_name.endswith('_ref') and ('ReferenceProperty' not in get_class_hierarchy_names(prop)):
raise ValueError(
"'%s' is named like a reference property but "
"is not a ReferenceProperty." % prop_name,
)
elif (prop_name.endswith('_refs') and ('ListProperty' not in get_class_hierarchy_names(prop) or
'ReferenceProperty' not in get_class_hierarchy_names(prop.contained))):
raise ValueError(
"'%s' is named like a reference list property but "
"is not a ListProperty containing ReferenceProperty." % prop_name,
)
_type = type
_properties = OrderedDict(properties)
if version != '2.0':
_id_contributing_properties = id_contrib_props
def __init__(self, **kwargs):
_Observable.__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 _get_properties_dict(properties):
try:
prop_dict = OrderedDict(properties)
return OrderedDict(properties)
except TypeError as e:
six.raise_from(
ValueError(
"Extension properties must be dict-like, e.g. a list "
"properties must be dict-like, e.g. a list "
"containing tuples. For example, "
"[('property1', IntegerProperty())]",
),
e,
)
class _CustomExtension(cls, _Extension):
def _custom_object_builder(cls, type, properties, version, base_class):
prop_dict = _get_properties_dict(properties)
class _CustomObject(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_object(_CustomObject, version=version)
return _CustomObject
def _custom_marking_builder(cls, type, properties, version, base_class):
prop_dict = _get_properties_dict(properties)
class _CustomMarking(cls, base_class):
_type = type
_properties = prop_dict
def __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, base_class, id_contrib_props=None):
if id_contrib_props is None:
id_contrib_props = []
prop_dict = _get_properties_dict(properties)
class _CustomObservable(cls, base_class):
_type = type
_properties = prop_dict
if version != '2.0':
_id_contributing_properties = id_contrib_props
def __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, base_class):
prop_dict = _get_properties_dict(properties)
class _CustomExtension(cls, base_class):
_type = type
_properties = prop_dict
def __init__(self, **kwargs):
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
_register_observable_extension(observable, _CustomExtension, version=version)

View File

@ -10,11 +10,11 @@ import six
from stix2 import v20, v21
from stix2.base import _STIXBase
from stix2.core import parse
from stix2.datastore import (
DataSink, DataSource, DataSourceError, DataStoreMixin,
)
from stix2.datastore.filters import Filter, FilterSet, apply_common_filters
from stix2.parsing import parse
from stix2.utils import format_datetime, get_type_from_id

View File

@ -7,9 +7,9 @@ import os
from stix2 import v20, v21
from stix2.base import _STIXBase
from stix2.core import parse
from stix2.datastore import DataSink, DataSource, DataStoreMixin
from stix2.datastore.filters import FilterSet, apply_common_filters
from stix2.parsing import parse
def _add(store, stix_data, allow_custom=True, version=None):

View File

@ -4,11 +4,11 @@ from requests.exceptions import HTTPError
from stix2 import v20, v21
from stix2.base import _STIXBase
from stix2.core import parse
from stix2.datastore import (
DataSink, DataSource, DataSourceError, DataStoreMixin,
)
from stix2.datastore.filters import Filter, FilterSet, apply_common_filters
from stix2.parsing import parse
from stix2.utils import deduplicate
try:

View File

@ -4,8 +4,8 @@ import copy
import logging
import time
from .core import parse as _parse
from .datastore import CompositeDataSource, DataStoreMixin
from .parsing import parse as _parse
from .utils import STIXdatetime, parse_into_datetime
logger = logging.getLogger(__name__)

View File

@ -7,22 +7,13 @@ import re
import stix2
from .base import _Observable, _STIXBase
from .base import _DomainObject, _Observable
from .exceptions import DuplicateRegistrationError, ParseError
from .markings import _MarkingsMixin
from .utils import SCO21_EXT_REGEX, TYPE_REGEX, _get_dict
from .utils import PREFIX_21_REGEX, _get_dict, get_class_hierarchy_names
STIX2_OBJ_MAPS = {}
class STIXDomainObject(_STIXBase, _MarkingsMixin):
pass
class STIXRelationshipObject(_STIXBase, _MarkingsMixin):
pass
def parse(data, allow_custom=False, version=None):
"""Convert a string, dict or file-like object into a STIX object.
@ -201,7 +192,7 @@ def parse_observable(data, _valid_refs=None, allow_custom=False, version=None):
return obj_class(allow_custom=allow_custom, **obj)
def _register_object(new_type, version=None):
def _register_object(new_type, version=stix2.DEFAULT_VERSION):
"""Register a custom STIX Object type.
Args:
@ -209,7 +200,26 @@ def _register_object(new_type, version=None):
version (str): Which STIX2 version to use. (e.g. "2.0", "2.1"). If
None, use latest version.
Raises:
ValueError: If the class being registered wasn't created with the
@CustomObject decorator.
DuplicateRegistrationError: If the class has already been registered.
"""
if not issubclass(new_type, _DomainObject):
raise ValueError(
"'%s' must be created with the @CustomObject decorator." %
new_type.__name__,
)
properties = new_type._properties
if version == "2.1":
for prop_name, prop in properties.items():
if not re.match(PREFIX_21_REGEX, prop_name):
raise ValueError("Property name '%s' must begin with an alpha character" % prop_name)
if version:
v = 'v' + version.replace('.', '')
else:
@ -222,7 +232,7 @@ def _register_object(new_type, version=None):
OBJ_MAP[new_type._type] = new_type
def _register_marking(new_marking, version=None):
def _register_marking(new_marking, version=stix2.DEFAULT_VERSION):
"""Register a custom STIX Marking Definition type.
Args:
@ -231,6 +241,17 @@ def _register_marking(new_marking, version=None):
None, use latest version.
"""
mark_type = new_marking._type
properties = new_marking._properties
stix2.properties._validate_type(mark_type, version)
if version == "2.1":
for prop_name, prop_value in properties.items():
if not re.match(PREFIX_21_REGEX, prop_name):
raise ValueError("Property name '%s' must begin with an alpha character." % prop_name)
if version:
v = 'v' + version.replace('.', '')
else:
@ -238,12 +259,12 @@ def _register_marking(new_marking, version=None):
v = 'v' + stix2.DEFAULT_VERSION.replace('.', '')
OBJ_MAP_MARKING = STIX2_OBJ_MAPS[v]['markings']
if new_marking._type in OBJ_MAP_MARKING.keys():
raise DuplicateRegistrationError("STIX Marking", new_marking._type)
OBJ_MAP_MARKING[new_marking._type] = new_marking
if mark_type in OBJ_MAP_MARKING.keys():
raise DuplicateRegistrationError("STIX Marking", mark_type)
OBJ_MAP_MARKING[mark_type] = new_marking
def _register_observable(new_observable, version=None):
def _register_observable(new_observable, version=stix2.DEFAULT_VERSION):
"""Register a custom STIX Cyber Observable type.
Args:
@ -252,6 +273,39 @@ def _register_observable(new_observable, version=None):
None, use latest version.
"""
properties = new_observable._properties
if version == "2.0":
# If using STIX2.0, check properties ending in "_ref/s" are ObjectReferenceProperties
for prop_name, prop in properties.items():
if prop_name.endswith('_ref') and ('ObjectReferenceProperty' not in get_class_hierarchy_names(prop)):
raise ValueError(
"'%s' is named like an object reference property but "
"is not an ObjectReferenceProperty." % prop_name,
)
elif (prop_name.endswith('_refs') and ('ListProperty' not in get_class_hierarchy_names(prop) or
'ObjectReferenceProperty' not in get_class_hierarchy_names(prop.contained))):
raise ValueError(
"'%s' is named like an object reference list property but "
"is not a ListProperty containing ObjectReferenceProperty." % prop_name,
)
else:
# If using STIX2.1 (or newer...), check properties ending in "_ref/s" are ReferenceProperties
for prop_name, prop in properties.items():
if not re.match(PREFIX_21_REGEX, prop_name):
raise ValueError("Property name '%s' must begin with an alpha character." % prop_name)
elif prop_name.endswith('_ref') and ('ReferenceProperty' not in get_class_hierarchy_names(prop)):
raise ValueError(
"'%s' is named like a reference property but "
"is not a ReferenceProperty." % prop_name,
)
elif (prop_name.endswith('_refs') and ('ListProperty' not in get_class_hierarchy_names(prop) or
'ReferenceProperty' not in get_class_hierarchy_names(prop.contained))):
raise ValueError(
"'%s' is named like a reference list property but "
"is not a ListProperty containing ReferenceProperty." % prop_name,
)
if version:
v = 'v' + version.replace('.', '')
else:
@ -280,30 +334,12 @@ def _register_observable_extension(
obs_class = observable if isinstance(observable, type) else \
type(observable)
ext_type = new_extension._type
properties = new_extension._properties
if not issubclass(obs_class, _Observable):
raise ValueError("'observable' must be a valid Observable class!")
if version == "2.0":
if not re.match(TYPE_REGEX, ext_type):
raise ValueError(
"Invalid extension type name '%s': must only contain the "
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." %
ext_type,
)
else: # 2.1+
if not re.match(SCO21_EXT_REGEX, ext_type):
raise ValueError(
"Invalid extension type name '%s': must only contain the "
"characters a-z (lowercase ASCII), 0-9, hyphen (-), and end "
"with '-ext'." % ext_type,
)
if len(ext_type) < 3 or len(ext_type) > 250:
raise ValueError(
"Invalid extension type name '%s': must be between 3 and 250"
" characters." % ext_type,
)
stix2.properties._validate_type(ext_type, version)
if not new_extension._properties:
raise ValueError(
@ -311,6 +347,17 @@ def _register_observable_extension(
ext_type,
)
if version == "2.1":
if not ext_type.endswith('-ext'):
raise ValueError(
"Invalid extension type name '%s': must end with '-ext'." %
ext_type,
)
for prop_name, prop_value in properties.items():
if not re.match(PREFIX_21_REGEX, prop_name):
raise ValueError("Property name '%s' must begin with an alpha character." % prop_name)
v = 'v' + version.replace('.', '')
try:

View File

@ -12,12 +12,15 @@ from six import string_types, text_type
import stix2
from .base import _STIXBase
from .core import STIX2_OBJ_MAPS, parse, parse_observable
from .exceptions import (
CustomContentError, DictionaryKeyError, MissingPropertiesError,
MutuallyExclusivePropertiesError,
)
from .utils import _get_dict, get_class_hierarchy_names, parse_into_datetime
from .parsing import STIX2_OBJ_MAPS, parse, parse_observable
from .utils import (
TYPE_21_REGEX, TYPE_REGEX, _get_dict, get_class_hierarchy_names,
parse_into_datetime,
)
try:
from collections.abc import Mapping
@ -81,6 +84,36 @@ def _validate_id(id_, spec_version, required_prefix):
raise ValueError(ERROR_INVALID_ID.format(id_))
def _validate_type(type_, spec_version):
"""
Check the STIX type name for correctness, raise an exception if there are
errors.
:param type_: The STIX type name
:param spec_version: The STIX specification version to use
:raises ValueError: If there are any errors with the identifier
"""
if spec_version == "2.0":
if not re.match(TYPE_REGEX, type_):
raise ValueError(
"Invalid type name '%s': must only contain the "
"characters a-z (lowercase ASCII), 0-9, and hyphen (-)." %
type_,
)
else: # 2.1+
if not re.match(TYPE_21_REGEX, type_):
raise ValueError(
"Invalid type name '%s': must only contain the "
"characters a-z (lowercase ASCII), 0-9, and hyphen (-) "
"and must begin with an a-z character" % type_,
)
if len(type_) < 3 or len(type_) > 250:
raise ValueError(
"Invalid type name '%s': must be between 3 and 250 characters." % type_,
)
class Property(object):
"""Represent a property of STIX data type.
@ -232,7 +265,9 @@ class StringProperty(Property):
class TypeProperty(Property):
def __init__(self, type):
def __init__(self, type, spec_version=stix2.DEFAULT_VERSION):
_validate_type(type, spec_version)
self.spec_version = spec_version
super(TypeProperty, self).__init__(fixed=type)
@ -643,7 +678,7 @@ class STIXObjectProperty(Property):
def clean(self, value):
# Any STIX Object (SDO, SRO, or Marking Definition) can be added to
# a bundle with no further checks.
if any(x in ('STIXDomainObject', 'STIXRelationshipObject', 'MarkingDefinition')
if any(x in ('_DomainObject', '_RelationshipObject', 'MarkingDefinition')
for x in get_class_hierarchy_names(value)):
# A simple "is this a spec version 2.1+ object" test. For now,
# limit 2.0 bundles to 2.0 objects. It's not possible yet to

View File

@ -2,7 +2,7 @@ from __future__ import unicode_literals
import pytest
from stix2.core import _detect_spec_version
from stix2.parsing import _detect_spec_version
@pytest.mark.parametrize(

View File

@ -1,7 +1,7 @@
import pytest
import stix2
from stix2 import core
from stix2 import parsing
import stix2.v20
from ...exceptions import DuplicateRegistrationError, InvalidValueError
@ -483,7 +483,7 @@ def test_custom_observable_object_invalid_type_name():
)
class NewObs(object):
pass # pragma: no cover
assert "Invalid observable type name 'x':" in str(excinfo.value)
assert "Invalid type name 'x':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v20.CustomObservable(
@ -493,7 +493,7 @@ def test_custom_observable_object_invalid_type_name():
)
class NewObs2(object):
pass # pragma: no cover
assert "Invalid observable type name 'x_new_obs':" in str(excinfo.value)
assert "Invalid type name 'x_new_obs':" in str(excinfo.value)
def test_custom_observable_object_invalid_ref_property():
@ -808,7 +808,7 @@ def test_custom_extension_invalid_type_name():
)
class FooExtension():
pass # pragma: no cover
assert "Invalid extension type name 'x':" in str(excinfo.value)
assert "Invalid type name 'x':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v20.CustomExtension(
@ -818,7 +818,7 @@ def test_custom_extension_invalid_type_name():
)
class BlaExtension():
pass # pragma: no cover
assert "Invalid extension type name 'x_new_ext':" in str(excinfo.value)
assert "Invalid type name 'x_new_ext':" in str(excinfo.value)
def test_custom_extension_no_properties():
@ -968,9 +968,8 @@ def test_register_custom_object():
class CustomObject2(object):
_type = 'awesome-object'
stix2.core._register_object(CustomObject2, version="2.0")
# Note that we will always check against newest OBJ_MAP.
assert (CustomObject2._type, CustomObject2) in stix2.v20.OBJ_MAP.items()
with pytest.raises(ValueError):
stix2.parsing._register_object(CustomObject2, version="2.0")
def test_extension_property_location():
@ -1030,10 +1029,10 @@ def test_register_custom_object_with_version():
"id": "x-new-type-2--00000000-0000-4000-8000-000000000007",
}
cust_obj_1 = core.dict_to_stix2(custom_obj_1, version='2.0')
cust_obj_1 = parsing.dict_to_stix2(custom_obj_1, version='2.0')
v = 'v20'
assert cust_obj_1.type in core.STIX2_OBJ_MAPS[v]['objects']
assert cust_obj_1.type in parsing.STIX2_OBJ_MAPS[v]['objects']
# spec_version is not in STIX 2.0, and is required in 2.1, so this
# suffices as a test for a STIX 2.0 object.
assert "spec_version" not in cust_obj_1
@ -1065,7 +1064,7 @@ def test_register_observable_with_version():
custom_obs = NewObservable2(property1="Test Observable")
v = 'v20'
assert custom_obs.type in core.STIX2_OBJ_MAPS[v]['observables']
assert custom_obs.type in parsing.STIX2_OBJ_MAPS[v]['observables']
def test_register_duplicate_observable_with_version():
@ -1091,7 +1090,7 @@ def test_register_marking_with_version():
v = 'v20'
no = NewObj2(property1='something')
assert no._type in core.STIX2_OBJ_MAPS[v]['markings']
assert no._type in parsing.STIX2_OBJ_MAPS[v]['markings']
def test_register_observable_extension_with_version():
@ -1106,7 +1105,7 @@ def test_register_observable_extension_with_version():
v = 'v20'
example = SomeCustomExtension2(keys='test123')
assert example._type in core.STIX2_OBJ_MAPS[v]['observable-extensions']['user-account']
assert example._type in parsing.STIX2_OBJ_MAPS[v]['observable-extensions']['user-account']
def test_register_duplicate_observable_extension():

View File

@ -249,14 +249,12 @@ def test_not_registered_marking_raises_exception():
def test_marking_wrong_type_construction():
with pytest.raises(ValueError) as excinfo:
with pytest.raises(ValueError):
# Test passing wrong type for properties.
@stix2.v20.CustomMarking('x-new-marking-type2', ("a", "b"))
class NewObject3(object):
pass
assert str(excinfo.value) == "Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]"
def test_campaign_add_markings():
campaign = stix2.v20.Campaign(

View File

@ -1,7 +1,7 @@
import pytest
import stix2
from stix2 import core, exceptions
from stix2 import exceptions, parsing
BUNDLE = {
"type": "bundle",
@ -44,14 +44,14 @@ BUNDLE = {
def test_dict_to_stix2_bundle_with_version():
with pytest.raises(exceptions.ExtraPropertiesError) as excinfo:
core.dict_to_stix2(BUNDLE, version='2.1')
parsing.dict_to_stix2(BUNDLE, version='2.1')
assert str(excinfo.value) == "Unexpected properties for Bundle: (spec_version)."
def test_parse_observable_with_version():
observable = {"type": "file", "name": "foo.exe"}
obs_obj = core.parse_observable(observable, version='2.0')
obs_obj = parsing.parse_observable(observable, version='2.0')
v = 'v20'
assert v in str(obs_obj.__class__)
@ -60,15 +60,15 @@ def test_parse_observable_with_version():
@pytest.mark.xfail(reason="The default version is no longer 2.0", condition=stix2.DEFAULT_VERSION != "2.0")
def test_parse_observable_with_no_version():
observable = {"type": "file", "name": "foo.exe"}
obs_obj = core.parse_observable(observable)
obs_obj = parsing.parse_observable(observable)
v = 'v20'
assert v in str(obs_obj.__class__)
def test_register_marking_with_version():
core._register_marking(stix2.v20.TLP_WHITE.__class__, version='2.0')
parsing._register_marking(stix2.v20.TLP_WHITE.__class__, version='2.0')
v = 'v20'
assert stix2.v20.TLP_WHITE.definition._type in core.STIX2_OBJ_MAPS[v]['markings']
assert stix2.v20.TLP_WHITE.definition._type in parsing.STIX2_OBJ_MAPS[v]['markings']
assert v in str(stix2.v20.TLP_WHITE.__class__)

View File

@ -9,6 +9,8 @@ import stix2.v21
from ...exceptions import DuplicateRegistrationError, InvalidValueError
from .constants import FAKE_TIME, IDENTITY_ID, MARKING_DEFINITION_ID
# Custom Properties in SDOs
IDENTITY_CUSTOM_PROP = stix2.v21.Identity(
name="John Smith",
identity_class="individual",
@ -18,6 +20,18 @@ IDENTITY_CUSTOM_PROP = stix2.v21.Identity(
def test_identity_custom_property():
identity = stix2.v21.Identity(
id=IDENTITY_ID,
created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z",
name="John Smith",
identity_class="individual",
custom_properties={
"foo": "bar",
},
)
assert identity.foo == "bar"
with pytest.raises(ValueError) as excinfo:
stix2.v21.Identity(
id=IDENTITY_ID,
@ -43,17 +57,47 @@ def test_identity_custom_property():
)
assert "Unexpected properties for Identity" in str(excinfo.value)
identity = stix2.v21.Identity(
id=IDENTITY_ID,
created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z",
name="John Smith",
identity_class="individual",
custom_properties={
"foo": "bar",
},
)
assert identity.foo == "bar"
# leading numeric character is illegal in 2.1
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.v21.Identity(
id=IDENTITY_ID,
created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z",
name="John Smith",
identity_class="individual",
custom_properties={
"7foo": "bar",
},
)
assert "must begin with an alpha character." in str(excinfo.value)
# leading "_" is illegal in 2.1
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.v21.Identity(
id=IDENTITY_ID,
created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z",
name="John Smith",
identity_class="individual",
custom_properties={
"_foo": "bar",
},
)
assert "must begin with an alpha character." in str(excinfo.value)
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
identity = stix2.v21.Identity(
id=IDENTITY_ID,
created="2015-12-21T19:59:11Z",
modified="2015-12-21T19:59:11Z",
name="John Smith",
identity_class="individual",
_x_foo="bar",
allow_custom=True,
)
assert "must begin with an alpha character." in str(excinfo.value)
def test_identity_custom_property_invalid():
@ -165,6 +209,8 @@ def test_custom_properties_dict_in_bundled_object():
assert bundle.objects[0].x_foo == "bar"
assert '"x_foo": "bar"' in str(bundle)
# Custom properties in SCOs
def test_custom_property_in_observed_data():
artifact = stix2.v21.File(
@ -184,6 +230,18 @@ def test_custom_property_in_observed_data():
assert '"x_foo": "bar"' in str(observed_data)
def test_invalid_custom_property_in_observed_data():
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
stix2.v21.File(
custom_properties={"8foo": 1},
allow_custom=True,
name='test',
x_foo='bar',
)
assert "must begin with an alpha character." in str(excinfo.value)
def test_custom_property_object_in_observable_extension():
ntfs = stix2.v21.NTFSExt(
allow_custom=True,
@ -245,6 +303,8 @@ def test_identity_custom_property_revoke():
identity = IDENTITY_CUSTOM_PROP.revoke()
assert identity.x_foo == "bar"
# Custom markings
def test_identity_custom_property_edit_markings():
marking_obj = stix2.v21.MarkingDefinition(
@ -267,6 +327,19 @@ def test_identity_custom_property_edit_markings():
identity2.clear_markings('x_foo')
def test_invalid_custom_property_in_marking():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomMarking(
'x-new-obj', [
('9property1', stix2.properties.StringProperty(required=True)),
],
)
class NewObj():
pass
assert "must begin with an alpha character." in str(excinfo.value)
def test_custom_marking_no_init_1():
@stix2.v21.CustomMarking(
'x-new-obj', [
@ -293,6 +366,40 @@ def test_custom_marking_no_init_2():
assert no2.property1 == 'something'
def test_custom_marking_invalid_type_name():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomMarking(
'x', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class NewObj(object):
pass # pragma: no cover
assert "Invalid type name 'x': " in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomMarking(
'x_new_marking', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class NewObj2(object):
pass # pragma: no cover
assert "Invalid type name 'x_new_marking':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomMarking(
'7x-new-marking', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class NewObj3(object):
pass # pragma: no cover
assert "Invalid type name '7x-new-marking':" in str(excinfo.value)
# Custom Objects
@stix2.v21.CustomObject(
'x-new-type', [
('property1', stix2.properties.StringProperty(required=True)),
@ -374,6 +481,16 @@ def test_custom_object_invalid_type_name():
pass # pragma: no cover
assert "Invalid type name 'x_new_object':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomObject(
'7x-new-object', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class NewObj3(object):
pass # pragma: no cover
assert "Invalid type name '7x-new-object':" in str(excinfo.value)
def test_parse_custom_object_type():
nt_string = """{
@ -412,6 +529,8 @@ def test_parse_unregistered_custom_object_type_w_allow_custom():
custom_obj = stix2.parse(nt_string, version="2.1", allow_custom=True)
assert custom_obj["type"] == "x-foobar-observable"
# Custom SCOs
@stix2.v21.CustomObservable(
'x-new-observable', [
@ -479,6 +598,18 @@ def test_custom_observable_object_no_init_2():
assert no2.property1 == 'something'
def test_invalid_custom_property_in_custom_observable_object():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomObservable(
'x-new-sco', [
('5property1', stix2.properties.StringProperty()),
],
)
class NewObs(object):
pass # pragma: no cover
assert "must begin with an alpha character." in str(excinfo.value)
def test_custom_observable_object_invalid_type_name():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomObservable(
@ -488,7 +619,7 @@ def test_custom_observable_object_invalid_type_name():
)
class NewObs(object):
pass # pragma: no cover
assert "Invalid observable type name 'x':" in str(excinfo.value)
assert "Invalid type name 'x':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomObservable(
@ -498,7 +629,17 @@ def test_custom_observable_object_invalid_type_name():
)
class NewObs2(object):
pass # pragma: no cover
assert "Invalid observable type name 'x_new_obs':" in str(excinfo.value)
assert "Invalid type name 'x_new_obs':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomObservable(
'7x-new-obs', [
('property1', stix2.properties.StringProperty()),
],
)
class NewObs3(object):
pass # pragma: no cover
assert "Invalid type name '7x-new-obs':" in str(excinfo.value)
def test_custom_observable_object_invalid_ref_property():
@ -736,6 +877,8 @@ def test_custom_observable_object_no_id_contrib_props():
assert uuid_obj.variant == uuid.RFC_4122
assert uuid_obj.version == 4
# Custom Extensions
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new-ext', [
@ -862,7 +1005,7 @@ def test_custom_extension_invalid_type_name():
)
class FooExtension():
pass # pragma: no cover
assert "Invalid extension type name 'x':" in str(excinfo.value)
assert "Invalid type name 'x':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
@ -872,7 +1015,17 @@ def test_custom_extension_invalid_type_name():
)
class BlaExtension():
pass # pragma: no cover
assert "Invalid extension type name 'x_new_ext':" in str(excinfo.value)
assert "Invalid type name 'x_new_ext':" in str(excinfo.value)
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
stix2.v21.File, '7x-new-ext', {
'property1': stix2.properties.StringProperty(required=True),
},
)
class Bla2Extension():
pass # pragma: no cover
assert "Invalid type name '7x-new-ext':" in str(excinfo.value)
def test_custom_extension_no_properties():
@ -922,6 +1075,19 @@ def test_custom_extension_no_init_2():
assert ne2.property1 == "foobar"
def test_invalid_custom_property_in_extension():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new3-ext', [
('6property1', stix2.properties.StringProperty(required=True)),
],
)
class NewExt():
pass
assert "must begin with an alpha character." in str(excinfo.value)
def test_parse_observable_with_custom_extension():
input_str = """{
"type": "domain-name",
@ -1020,9 +1186,9 @@ def test_register_custom_object():
class CustomObject2(object):
_type = 'awesome-object'
stix2.core._register_object(CustomObject2, version="2.1")
# Note that we will always check against newest OBJ_MAP.
assert (CustomObject2._type, CustomObject2) in stix2.v21.OBJ_MAP.items()
with pytest.raises(ValueError) as excinfo:
stix2.parsing._register_object(CustomObject2, version="2.1")
assert '@CustomObject decorator' in str(excinfo)
def test_extension_property_location():
@ -1084,10 +1250,10 @@ def test_register_custom_object_with_version():
"spec_version": "2.1",
}
cust_obj_1 = stix2.core.dict_to_stix2(custom_obj_1, version='2.1')
cust_obj_1 = stix2.parsing.dict_to_stix2(custom_obj_1, version='2.1')
v = 'v21'
assert cust_obj_1.type in stix2.core.STIX2_OBJ_MAPS[v]['objects']
assert cust_obj_1.type in stix2.parsing.STIX2_OBJ_MAPS[v]['objects']
assert cust_obj_1.spec_version == "2.1"
@ -1117,7 +1283,7 @@ def test_register_observable():
custom_obs = NewObservable3(property1="Test Observable")
v = 'v21'
assert custom_obs.type in stix2.core.STIX2_OBJ_MAPS[v]['observables']
assert custom_obs.type in stix2.parsing.STIX2_OBJ_MAPS[v]['observables']
def test_register_duplicate_observable():
@ -1145,8 +1311,8 @@ def test_register_observable_custom_extension():
example = NewExtension2(property1="Hi there")
v = 'v21'
assert 'domain-name' in stix2.core.STIX2_OBJ_MAPS[v]['observables']
assert example._type in stix2.core.STIX2_OBJ_MAPS[v]['observable-extensions']['domain-name']
assert 'domain-name' in stix2.parsing.STIX2_OBJ_MAPS[v]['observables']
assert example._type in stix2.parsing.STIX2_OBJ_MAPS[v]['observable-extensions']['domain-name']
def test_register_duplicate_observable_extension():

View File

@ -277,14 +277,12 @@ def test_not_registered_marking_raises_exception():
def test_marking_wrong_type_construction():
with pytest.raises(ValueError) as excinfo:
with pytest.raises(ValueError):
# Test passing wrong type for properties.
@stix2.v21.CustomMarking('x-new-marking-type2', ("a", "b"))
class NewObject3(object):
pass
assert str(excinfo.value) == "Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]"
def test_campaign_add_markings():
campaign = stix2.v21.Campaign(

View File

@ -1,7 +1,7 @@
import pytest
import stix2
from stix2 import core, exceptions
from stix2 import exceptions, parsing
BUNDLE = {
"type": "bundle",
@ -48,7 +48,7 @@ BUNDLE = {
def test_dict_to_stix2_bundle_with_version():
with pytest.raises(exceptions.InvalidValueError) as excinfo:
core.dict_to_stix2(BUNDLE, version='2.0')
parsing.dict_to_stix2(BUNDLE, version='2.0')
msg = "Invalid value for Bundle 'objects': Spec version 2.0 bundles don't yet support containing objects of a different spec version."
assert str(excinfo.value) == msg
@ -56,7 +56,7 @@ def test_dict_to_stix2_bundle_with_version():
def test_parse_observable_with_version():
observable = {"type": "file", "name": "foo.exe"}
obs_obj = core.parse_observable(observable, version='2.1')
obs_obj = parsing.parse_observable(observable, version='2.1')
v = 'v21'
assert v in str(obs_obj.__class__)
@ -65,25 +65,25 @@ def test_parse_observable_with_version():
@pytest.mark.xfail(reason="The default version is not 2.1", condition=stix2.DEFAULT_VERSION != "2.1")
def test_parse_observable_with_no_version():
observable = {"type": "file", "name": "foo.exe"}
obs_obj = core.parse_observable(observable)
obs_obj = parsing.parse_observable(observable)
v = 'v21'
assert v in str(obs_obj.__class__)
def test_register_marking_with_version():
core._register_marking(stix2.v21.TLP_WHITE.__class__, version='2.1')
parsing._register_marking(stix2.v21.TLP_WHITE.__class__, version='2.1')
v = 'v21'
assert stix2.v21.TLP_WHITE.definition._type in core.STIX2_OBJ_MAPS[v]['markings']
assert stix2.v21.TLP_WHITE.definition._type in parsing.STIX2_OBJ_MAPS[v]['markings']
assert v in str(stix2.v21.TLP_WHITE.__class__)
@pytest.mark.xfail(reason="The default version is not 2.1", condition=stix2.DEFAULT_VERSION != "2.1")
def test_register_marking_with_no_version():
# Uses default version (2.0 in this case)
core._register_marking(stix2.v21.TLP_WHITE.__class__)
parsing._register_marking(stix2.v21.TLP_WHITE.__class__)
v = 'v21'
assert stix2.v21.TLP_WHITE.definition._type in core.STIX2_OBJ_MAPS[v]['markings']
assert stix2.v21.TLP_WHITE.definition._type in parsing.STIX2_OBJ_MAPS[v]['markings']
assert v in str(stix2.v21.TLP_WHITE.__class__)

View File

@ -8,12 +8,13 @@ import copy
import datetime as dt
import enum
import json
import re
from dateutil import parser
import pytz
import six
import stix2.base
import stix2
from .exceptions import (
InvalidValueError, RevokeError, UnmodifiablePropertyError,
@ -27,8 +28,9 @@ NOW = object()
# STIX object properties that cannot be modified
STIX_UNMOD_PROPERTIES = ['created', 'created_by_ref', 'id', 'type']
TYPE_REGEX = r'^\-?[a-z0-9]+(-[a-z0-9]+)*\-?$'
SCO21_EXT_REGEX = r'^\-?[a-z0-9]+(-[a-z0-9]+)*\-ext$'
TYPE_REGEX = re.compile(r'^\-?[a-z0-9]+(-[a-z0-9]+)*\-?$')
TYPE_21_REGEX = re.compile(r'^([a-z][a-z0-9]*)+(-[a-z0-9]+)*\-?$')
PREFIX_21_REGEX = re.compile(r'^[a-z].*')
class Precision(enum.Enum):
@ -360,14 +362,12 @@ def find_property_index(obj, search_key, search_value):
Returns:
int: An index; -1 if the key and value aren't found
"""
from .base import _STIXBase
# Special-case keys which are numbers-as-strings, e.g. for cyber-observable
# mappings. Use the int value of the key as the index.
if search_key.isdigit():
return int(search_key)
if isinstance(obj, _STIXBase):
if isinstance(obj, stix2.base._STIXBase):
if search_key in obj and obj[search_key] == search_value:
idx = _find(obj.object_properties(), search_key)
else:

View File

@ -14,6 +14,9 @@
# flake8: noqa
from .base import (
_DomainObject, _Extension, _Observable, _RelationshipObject, _STIXBase20,
)
from .bundle import Bundle
from .common import (
TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, CustomMarking, ExternalReference,

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

@ -0,0 +1,25 @@
"""Base classes for STIX 2.0 type definitions."""
from ..base import (
_DomainObject, _Extension, _Observable, _RelationshipObject, _STIXBase,
)
class _STIXBase20(_STIXBase):
pass
class _Observable(_Observable, _STIXBase20):
pass
class _Extension(_Extension, _STIXBase20):
pass
class _DomainObject(_DomainObject, _STIXBase20):
pass
class _RelationshipObject(_RelationshipObject, _STIXBase20):
pass

View File

@ -2,20 +2,20 @@
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>`__.
"""
_type = 'bundle'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
# Not technically correct: STIX 2.0 spec doesn't say spec_version must
# have this value, but it's all we support for now.

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,14 +113,14 @@ 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>`__.
"""
_type = 'marking-definition'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW)),
@ -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):
@ -26,7 +26,7 @@ class Artifact(_Observable):
_type = 'artifact'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('mime_type', StringProperty()),
('payload_bin', BinaryProperty()),
('url', StringProperty()),
@ -47,7 +47,7 @@ class AutonomousSystem(_Observable):
_type = 'autonomous-system'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('number', IntegerProperty(required=True)),
('name', StringProperty()),
('rir', StringProperty()),
@ -62,7 +62,7 @@ class Directory(_Observable):
_type = 'directory'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('path', StringProperty(required=True)),
('path_enc', StringProperty()),
# these are not the created/modified timestamps of the object itself
@ -81,7 +81,7 @@ class DomainName(_Observable):
_type = 'domain-name'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'domain-name']))),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
@ -95,7 +95,7 @@ class EmailAddress(_Observable):
_type = 'email-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('display_name', StringProperty()),
('belongs_to_ref', ObjectReferenceProperty(valid_types='user-account')),
@ -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
@ -127,7 +127,7 @@ class EmailMessage(_Observable):
_type = 'email-message'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('is_multipart', BooleanProperty(required=True)),
('date', TimestampProperty()),
('content_type', StringProperty()),
@ -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
@ -306,7 +306,7 @@ class File(_Observable):
_type = 'file'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('hashes', HashesProperty()),
('size', IntegerProperty()),
('name', StringProperty()),
@ -339,7 +339,7 @@ class IPv4Address(_Observable):
_type = 'ipv4-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types='mac-addr'))),
('belongs_to_refs', ListProperty(ObjectReferenceProperty(valid_types='autonomous-system'))),
@ -354,7 +354,7 @@ class IPv6Address(_Observable):
_type = 'ipv6-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types='mac-addr'))),
('belongs_to_refs', ListProperty(ObjectReferenceProperty(valid_types='autonomous-system'))),
@ -369,7 +369,7 @@ class MACAddress(_Observable):
_type = 'mac-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
])
@ -382,7 +382,7 @@ class Mutex(_Observable):
_type = 'mutex'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('name', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
])
@ -483,7 +483,7 @@ class NetworkTraffic(_Observable):
_type = 'network-traffic'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('start', TimestampProperty()),
('end', TimestampProperty()),
('is_active', BooleanProperty()),
@ -575,7 +575,7 @@ class Process(_Observable):
_type = 'process'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('is_hidden', BooleanProperty()),
('pid', IntegerProperty()),
('name', StringProperty()),
@ -615,7 +615,7 @@ class Software(_Observable):
_type = 'software'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('name', StringProperty(required=True)),
('cpe', StringProperty()),
('languages', ListProperty(StringProperty)),
@ -632,7 +632,7 @@ class URL(_Observable):
_type = 'url'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
])
@ -659,7 +659,7 @@ class UserAccount(_Observable):
_type = 'user-account'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('user_id', StringProperty(required=True)),
('account_login', StringProperty()),
('account_type', StringProperty()), # open vocab
@ -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
@ -713,7 +713,7 @@ class WindowsRegistryKey(_Observable):
_type = 'windows-registry-key'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('key', StringProperty(required=True)),
('values', ListProperty(EmbeddedObjectProperty(type=WindowsRegistryValueType))),
# this is not the modified timestamps of the object itself
@ -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
@ -757,7 +757,7 @@ class X509Certificate(_Observable):
_type = 'x509-certificate'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('is_self_signed', BooleanProperty()),
('hashes', HashesProperty()),
('version', StringProperty()),
@ -791,11 +791,11 @@ def CustomObservable(type='x-custom-observable', properties=None):
"""
def wrapper(cls):
_properties = list(itertools.chain.from_iterable([
[('type', TypeProperty(type))],
[('type', TypeProperty(type, spec_version='2.0'))],
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,17 +13,18 @@ from ..properties import (
TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import _DomainObject
from .common import ExternalReference, GranularMarking, KillChainPhase
class AttackPattern(STIXDomainObject):
class AttackPattern(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714302>`__.
"""
_type = 'attack-pattern'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -40,14 +40,14 @@ class AttackPattern(STIXDomainObject):
])
class Campaign(STIXDomainObject):
class Campaign(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714305>`__.
"""
_type = 'campaign'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -66,14 +66,14 @@ class Campaign(STIXDomainObject):
])
class CourseOfAction(STIXDomainObject):
class CourseOfAction(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714308>`__.
"""
_type = 'course-of-action'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -88,14 +88,14 @@ class CourseOfAction(STIXDomainObject):
])
class Identity(STIXDomainObject):
class Identity(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714311>`__.
"""
_type = 'identity'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -113,14 +113,14 @@ class Identity(STIXDomainObject):
])
class Indicator(STIXDomainObject):
class Indicator(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714314>`__.
"""
_type = 'indicator'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -144,14 +144,14 @@ class Indicator(STIXDomainObject):
raise InvalidValueError(self.__class__, 'pattern', str(errors[0]))
class IntrusionSet(STIXDomainObject):
class IntrusionSet(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714317>`__.
"""
_type = 'intrusion-set'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -173,14 +173,14 @@ class IntrusionSet(STIXDomainObject):
])
class Malware(STIXDomainObject):
class Malware(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714320>`__.
"""
_type = 'malware'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -196,14 +196,14 @@ class Malware(STIXDomainObject):
])
class ObservedData(STIXDomainObject):
class ObservedData(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714323>`__.
"""
_type = 'observed-data'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -226,14 +226,14 @@ class ObservedData(STIXDomainObject):
super(ObservedData, self).__init__(*args, **kwargs)
class Report(STIXDomainObject):
class Report(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714326>`__.
"""
_type = 'report'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -250,14 +250,14 @@ class Report(STIXDomainObject):
])
class ThreatActor(STIXDomainObject):
class ThreatActor(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714329>`__.
"""
_type = 'threat-actor'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -280,14 +280,14 @@ class ThreatActor(STIXDomainObject):
])
class Tool(STIXDomainObject):
class Tool(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714332>`__.
"""
_type = 'tool'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -304,14 +304,14 @@ class Tool(STIXDomainObject):
])
class Vulnerability(STIXDomainObject):
class Vulnerability(_DomainObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714335>`__.
"""
_type = 'vulnerability'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -358,7 +358,7 @@ def CustomObject(type='x-custom-type', properties=None):
def wrapper(cls):
_properties = list(itertools.chain.from_iterable([
[
('type', TypeProperty(type)),
('type', TypeProperty(type, spec_version='2.0')),
('id', IDProperty(type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -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', _DomainObject)
return wrapper

View File

@ -2,16 +2,16 @@
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 _RelationshipObject
from .common import ExternalReference, GranularMarking
class Relationship(STIXRelationshipObject):
class Relationship(_RelationshipObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714340>`__.
"""
@ -20,7 +20,7 @@ class Relationship(STIXRelationshipObject):
_type = 'relationship'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
@ -52,14 +52,14 @@ class Relationship(STIXRelationshipObject):
super(Relationship, self).__init__(**kwargs)
class Sighting(STIXRelationshipObject):
class Sighting(_RelationshipObject):
"""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/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714343>`__.
"""
_type = 'sighting'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.0')),
('id', IDProperty(_type, spec_version='2.0')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),

View File

@ -14,6 +14,9 @@
# flake8: noqa
from .base import (
_DomainObject, _Extension, _Observable, _RelationshipObject, _STIXBase21,
)
from .bundle import Bundle
from .common import (
TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, CustomMarking, ExternalReference,

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

@ -0,0 +1,25 @@
"""Base classes for STIX 2.1 type definitions."""
from ..base import (
_DomainObject, _Extension, _Observable, _RelationshipObject, _STIXBase,
)
class _STIXBase21(_STIXBase):
pass
class _Observable(_Observable, _STIXBase21):
pass
class _Extension(_Extension, _STIXBase21):
pass
class _DomainObject(_DomainObject, _STIXBase21):
pass
class _RelationshipObject(_RelationshipObject, _STIXBase21):
pass

View File

@ -2,20 +2,20 @@
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):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_nuwp4rox8c7r>`__.
"""
_type = 'bundle'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('objects', ListProperty(STIXObjectProperty(spec_version='2.1'))),
])

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):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_bajcvqteiard>`__.
"""
@ -49,7 +49,7 @@ class ExternalReference(_STIXBase):
)
class KillChainPhase(_STIXBase):
class KillChainPhase(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_i4tjv75ce50h>`__.
"""
@ -60,7 +60,7 @@ class KillChainPhase(_STIXBase):
])
class GranularMarking(_STIXBase):
class GranularMarking(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_robezi5egfdr>`__.
"""
@ -76,14 +76,14 @@ class GranularMarking(_STIXBase):
self._check_at_least_one_property(['lang', 'marking_ref'])
class LanguageContent(_STIXBase):
class LanguageContent(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_nfwr8z9ax2bi>`__.
"""
_type = 'language-content'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -103,7 +103,7 @@ class LanguageContent(_STIXBase):
])
class TLPMarking(_STIXBase):
class TLPMarking(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_yd3ar14ekwrs>`__.
"""
@ -114,7 +114,7 @@ class TLPMarking(_STIXBase):
])
class StatementMarking(_STIXBase):
class StatementMarking(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_3ru8r05saera>`__.
"""
@ -144,14 +144,14 @@ class MarkingProperty(Property):
raise ValueError("must be a Statement, TLP Marking or a registered marking.")
class MarkingDefinition(_STIXBase, _MarkingsMixin):
class MarkingDefinition(_STIXBase21, _MarkingsMixin):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_hr5vgqxjk7ns>`__.
"""
_type = 'marking-definition'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type)),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -208,7 +208,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
@ -28,7 +28,7 @@ class Artifact(_Observable):
_type = 'artifact'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('mime_type', StringProperty()),
('payload_bin', BinaryProperty()),
@ -57,7 +57,7 @@ class AutonomousSystem(_Observable):
_type = 'autonomous-system'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('number', IntegerProperty(required=True)),
('name', StringProperty()),
@ -78,7 +78,7 @@ class Directory(_Observable):
_type = 'directory'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('path', StringProperty(required=True)),
('path_enc', StringProperty()),
@ -103,7 +103,7 @@ class DomainName(_Observable):
_type = 'domain-name'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'domain-name'], spec_version='2.1'))),
@ -123,7 +123,7 @@ class EmailAddress(_Observable):
_type = 'email-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('value', StringProperty(required=True)),
('display_name', StringProperty()),
@ -137,7 +137,7 @@ class EmailAddress(_Observable):
_id_contributing_properties = ["value"]
class EmailMIMEComponent(_STIXBase):
class EmailMIMEComponent(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_kzv52qqc0xw1>`__.
"""
@ -161,7 +161,7 @@ class EmailMessage(_Observable):
_type = 'email-message'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('is_multipart', BooleanProperty(required=True)),
('date', TimestampProperty()),
@ -206,7 +206,7 @@ class ArchiveExt(_Extension):
])
class AlternateDataStream(_STIXBase):
class AlternateDataStream(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_nbqgazg6fsma>`__.
"""
@ -259,7 +259,7 @@ class RasterImageExt(_Extension):
])
class WindowsPEOptionalHeaderType(_STIXBase):
class WindowsPEOptionalHeaderType(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_wyp5qdc2wugy>`__.
"""
@ -303,7 +303,7 @@ class WindowsPEOptionalHeaderType(_STIXBase):
self._check_at_least_one_property()
class WindowsPESection(_STIXBase):
class WindowsPESection(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_wiqw87xsov3t>`__.
"""
@ -345,7 +345,7 @@ class File(_Observable):
_type = 'file'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('hashes', HashesProperty(spec_version='2.1')),
('size', IntegerProperty(min=0)),
@ -380,7 +380,7 @@ class IPv4Address(_Observable):
_type = 'ipv4-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ReferenceProperty(valid_types='mac-addr', spec_version='2.1'))),
@ -401,7 +401,7 @@ class IPv6Address(_Observable):
_type = 'ipv6-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ReferenceProperty(valid_types='mac-addr', spec_version='2.1'))),
@ -422,7 +422,7 @@ class MACAddress(_Observable):
_type = 'mac-addr'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('value', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
@ -441,7 +441,7 @@ class Mutex(_Observable):
_type = 'mutex'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('name', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
@ -562,7 +562,7 @@ class NetworkTraffic(_Observable):
_type = 'network-traffic'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('start', TimestampProperty()),
('end', TimestampProperty()),
@ -684,7 +684,7 @@ class Process(_Observable):
_type = 'process'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('is_hidden', BooleanProperty()),
('pid', IntegerProperty()),
@ -728,7 +728,7 @@ class Software(_Observable):
_type = 'software'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('name', StringProperty(required=True)),
('cpe', StringProperty()),
@ -752,7 +752,7 @@ class URL(_Observable):
_type = 'url'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('value', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
@ -785,7 +785,7 @@ class UserAccount(_Observable):
_type = 'user-account'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('user_id', StringProperty()),
('credential', StringProperty()),
@ -810,7 +810,7 @@ class UserAccount(_Observable):
_id_contributing_properties = ["account_type", "user_id", "account_login"]
class WindowsRegistryValueType(_STIXBase):
class WindowsRegistryValueType(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_6jiqabgqp2hp>`__.
"""
@ -846,7 +846,7 @@ class WindowsRegistryKey(_Observable):
_type = 'windows-registry-key'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('key', StringProperty()),
('values', ListProperty(EmbeddedObjectProperty(type=WindowsRegistryValueType))),
@ -863,7 +863,7 @@ class WindowsRegistryKey(_Observable):
_id_contributing_properties = ["key", "values"]
class X509V3ExtenstionsType(_STIXBase):
class X509V3ExtenstionsType(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_c1kt4dheb6vz>`__.
"""
@ -896,7 +896,7 @@ class X509Certificate(_Observable):
_type = 'x509-certificate'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('is_self_signed', BooleanProperty()),
('hashes', HashesProperty(spec_version='2.1')),
@ -948,12 +948,12 @@ def CustomObservable(type='x-custom-observable', properties=None, id_contrib_pro
"""
def wrapper(cls):
_properties = list(itertools.chain.from_iterable([
[('type', TypeProperty(type))],
[('type', TypeProperty(type, spec_version='2.1'))],
[('id', IDProperty(type, spec_version='2.1'))],
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
@ -961,5 +961,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,17 +17,18 @@ from ..properties import (
StringProperty, TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import _DomainObject
from .common import ExternalReference, GranularMarking, KillChainPhase
class AttackPattern(STIXDomainObject):
class AttackPattern(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_4ohsa4pay4h4>`__.
"""
_type = 'attack-pattern'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -48,14 +48,14 @@ class AttackPattern(STIXDomainObject):
])
class Campaign(STIXDomainObject):
class Campaign(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_vvysvm8mt434>`__.
"""
_type = 'campaign'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -87,14 +87,14 @@ class Campaign(STIXDomainObject):
raise ValueError(msg.format(self))
class CourseOfAction(STIXDomainObject):
class CourseOfAction(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_d5yf99f0a230>`__.
"""
_type = 'course-of-action'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -112,14 +112,14 @@ class CourseOfAction(STIXDomainObject):
])
class Grouping(STIXDomainObject):
class Grouping(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_9e3uldaqqha2>`__.
"""
_type = 'grouping'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
@ -139,14 +139,14 @@ class Grouping(STIXDomainObject):
])
class Identity(STIXDomainObject):
class Identity(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ru8fmldl2p6w>`__.
"""
_type = 'identity'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -168,14 +168,14 @@ class Identity(STIXDomainObject):
])
class Indicator(STIXDomainObject):
class Indicator(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_wfiae74706sw>`__.
"""
_type = 'indicator'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -204,7 +204,7 @@ class Indicator(STIXDomainObject):
if kwargs.get('pattern') and kwargs.get('pattern_type') == 'stix' and not kwargs.get('pattern_version'):
kwargs['pattern_version'] = '2.1'
super(STIXDomainObject, self).__init__(*args, **kwargs)
super(_DomainObject, self).__init__(*args, **kwargs)
def _check_object_constraints(self):
super(Indicator, self)._check_object_constraints()
@ -227,14 +227,14 @@ class Indicator(STIXDomainObject):
raise InvalidValueError(self.__class__, 'pattern', str(errors[0]))
class Infrastructure(STIXDomainObject):
class Infrastructure(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_l2alfbbcmfep>`__.
"""
_type = 'infrastructure'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -267,14 +267,14 @@ class Infrastructure(STIXDomainObject):
raise ValueError(msg.format(self))
class IntrusionSet(STIXDomainObject):
class IntrusionSet(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ticprjb32bc4>`__.
"""
_type = 'intrusion-set'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -309,14 +309,14 @@ class IntrusionSet(STIXDomainObject):
raise ValueError(msg.format(self))
class Location(STIXDomainObject):
class Location(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_sqez6sri9vtz>`__.
"""
_type = 'location'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -416,14 +416,14 @@ class Location(STIXDomainObject):
return final_url
class Malware(STIXDomainObject):
class Malware(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_gc4ooz6oaz7y>`__.
"""
_type = 'malware'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -468,14 +468,14 @@ class Malware(STIXDomainObject):
)
class MalwareAnalysis(STIXDomainObject):
class MalwareAnalysis(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_dw67pa20zss5>`__.
"""
_type = 'malware-analysis'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
@ -512,14 +512,14 @@ class MalwareAnalysis(STIXDomainObject):
self._check_at_least_one_property(["result", "analysis_sco_refs"])
class Note(STIXDomainObject):
class Note(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_hr77jvcbs9jk>`__.
"""
_type = 'note'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -539,14 +539,14 @@ class Note(STIXDomainObject):
])
class ObservedData(STIXDomainObject):
class ObservedData(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_h1590esrzg5f>`__.
"""
_type = 'observed-data'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -594,14 +594,14 @@ class ObservedData(STIXDomainObject):
)
class Opinion(STIXDomainObject):
class Opinion(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_sr2hswmu5t1>`__.
"""
_type = 'opinion'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -631,14 +631,14 @@ class Opinion(STIXDomainObject):
])
class Report(STIXDomainObject):
class Report(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ha4fpad0r9pf>`__.
"""
_type = 'report'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -659,14 +659,14 @@ class Report(STIXDomainObject):
])
class ThreatActor(STIXDomainObject):
class ThreatActor(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_2wowmlcbkqst>`__.
"""
_type = 'threat-actor'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -705,14 +705,14 @@ class ThreatActor(STIXDomainObject):
raise ValueError(msg.format(self))
class Tool(STIXDomainObject):
class Tool(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_m21z3a1f3lou>`__.
"""
_type = 'tool'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -734,14 +734,14 @@ class Tool(STIXDomainObject):
])
class Vulnerability(STIXDomainObject):
class Vulnerability(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_d9f0iay06wtx>`__.
"""
_type = 'vulnerability'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -791,7 +791,7 @@ def CustomObject(type='x-custom-type', properties=None):
def wrapper(cls):
_properties = list(itertools.chain.from_iterable([
[
('type', TypeProperty(type)),
('type', TypeProperty(type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -810,6 +810,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', _DomainObject)
return wrapper

View File

@ -2,16 +2,16 @@
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 _RelationshipObject
from .common import ExternalReference, GranularMarking
class Relationship(STIXRelationshipObject):
class Relationship(_RelationshipObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_al0fb8fcd9e7>`__.
"""
@ -20,7 +20,7 @@ class Relationship(STIXRelationshipObject):
_type = 'relationship'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
@ -67,14 +67,14 @@ class Relationship(STIXRelationshipObject):
raise ValueError(msg.format(self))
class Sighting(STIXRelationshipObject):
class Sighting(_RelationshipObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_7p0n81ikux8f>`__.
"""
_type = 'sighting'
_properties = OrderedDict([
('type', TypeProperty(_type)),
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),