Remove duplicate code from 'sdo.py', removed STIXDomainObject
Apply proper 'spec_version' constraints to v21 objectsstix2.1
parent
54268ae7dd
commit
023603d86f
|
@ -2,21 +2,16 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import re
|
import itertools
|
||||||
|
|
||||||
from ..base import _STIXBase
|
from ..core import STIXDomainObject
|
||||||
from ..core import _register_type
|
from ..custom import custom_object_builder
|
||||||
from ..markings import _MarkingsMixin
|
from ..properties import (BooleanProperty, IDProperty, IntegerProperty,
|
||||||
from ..utils import NOW, TYPE_REGEX
|
ListProperty, ObservableProperty, PatternProperty,
|
||||||
|
ReferenceProperty, StringProperty, TimestampProperty,
|
||||||
|
TypeProperty)
|
||||||
|
from ..utils import NOW
|
||||||
from .common import ExternalReference, GranularMarking, KillChainPhase
|
from .common import ExternalReference, GranularMarking, KillChainPhase
|
||||||
from .observables import ObservableProperty
|
|
||||||
from .properties import (BooleanProperty, IDProperty, IntegerProperty,
|
|
||||||
ListProperty, PatternProperty, ReferenceProperty,
|
|
||||||
StringProperty, TimestampProperty, TypeProperty)
|
|
||||||
|
|
||||||
|
|
||||||
class STIXDomainObject(_STIXBase, _MarkingsMixin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AttackPattern(STIXDomainObject):
|
class AttackPattern(STIXDomainObject):
|
||||||
|
@ -327,6 +322,8 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
"""Custom STIX Object type decorator.
|
"""Custom STIX Object type decorator.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
>>> from stix2.v20 import CustomObject
|
||||||
|
>>> from stix2.properties import IntegerProperty, StringProperty
|
||||||
>>> @CustomObject('x-type-name', [
|
>>> @CustomObject('x-type-name', [
|
||||||
... ('property1', StringProperty(required=True)),
|
... ('property1', StringProperty(required=True)),
|
||||||
... ('property2', IntegerProperty()),
|
... ('property2', IntegerProperty()),
|
||||||
|
@ -338,6 +335,8 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
type. Don't call ``super().__init__()`` though - doing so will cause an error.
|
type. Don't call ``super().__init__()`` though - doing so will cause an error.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
>>> from stix2.v20 import CustomObject
|
||||||
|
>>> from stix2.properties import IntegerProperty, StringProperty
|
||||||
>>> @CustomObject('x-type-name', [
|
>>> @CustomObject('x-type-name', [
|
||||||
... ('property1', StringProperty(required=True)),
|
... ('property1', StringProperty(required=True)),
|
||||||
... ('property2', IntegerProperty()),
|
... ('property2', IntegerProperty()),
|
||||||
|
@ -346,56 +345,27 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
... def __init__(self, property2=None, **kwargs):
|
... def __init__(self, property2=None, **kwargs):
|
||||||
... if property2 and property2 < 10:
|
... if property2 and property2 < 10:
|
||||||
... raise ValueError("'property2' is too small.")
|
... raise ValueError("'property2' is too small.")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
def wrapper(cls):
|
||||||
def custom_builder(cls):
|
_properties = list(itertools.chain.from_iterable([
|
||||||
|
[
|
||||||
class _Custom(cls, STIXDomainObject):
|
('type', TypeProperty(type)),
|
||||||
|
('id', IDProperty(type)),
|
||||||
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)
|
|
||||||
|
|
||||||
_type = type
|
|
||||||
_properties = OrderedDict([
|
|
||||||
('type', TypeProperty(_type)),
|
|
||||||
('id', IDProperty(_type)),
|
|
||||||
('created_by_ref', ReferenceProperty(type='identity')),
|
('created_by_ref', ReferenceProperty(type='identity')),
|
||||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond'))
|
||||||
])
|
],
|
||||||
|
[x for x in properties if not x[0].startswith('x_')],
|
||||||
if not properties or not isinstance(properties, list):
|
[
|
||||||
raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]")
|
|
||||||
|
|
||||||
_properties.update([x for x in properties if not x[0].startswith('x_')])
|
|
||||||
|
|
||||||
# This is to follow the general properties structure.
|
|
||||||
_properties.update([
|
|
||||||
('revoked', BooleanProperty(default=lambda: False)),
|
('revoked', BooleanProperty(default=lambda: False)),
|
||||||
('labels', ListProperty(StringProperty)),
|
('labels', ListProperty(StringProperty)),
|
||||||
('external_references', ListProperty(ExternalReference)),
|
('external_references', ListProperty(ExternalReference)),
|
||||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))),
|
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))),
|
||||||
('granular_markings', ListProperty(GranularMarking)),
|
('granular_markings', ListProperty(GranularMarking)),
|
||||||
])
|
],
|
||||||
|
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')
|
||||||
|
|
||||||
# Put all custom properties at the bottom, sorted alphabetically.
|
return wrapper
|
||||||
_properties.update(sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]))
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
_STIXBase.__init__(self, **kwargs)
|
|
||||||
try:
|
|
||||||
cls.__init__(self, **kwargs)
|
|
||||||
except (AttributeError, TypeError) as e:
|
|
||||||
# Don't accidentally catch errors raised in a custom __init__()
|
|
||||||
if ("has no attribute '__init__'" in str(e) or
|
|
||||||
str(e) == "object.__init__() takes no parameters"):
|
|
||||||
return
|
|
||||||
raise e
|
|
||||||
|
|
||||||
_register_type(_Custom, version='2.0')
|
|
||||||
return _Custom
|
|
||||||
|
|
||||||
return custom_builder
|
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
"""STIX 2.1 Domain Objects"""
|
"""STIX 2.1 Domain Objects"""
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import re
|
import itertools
|
||||||
|
|
||||||
from ..base import _STIXBase
|
from ..base import _STIXBase
|
||||||
from ..core import _register_type
|
from ..core import STIXDomainObject
|
||||||
from ..markings import _MarkingsMixin
|
from ..custom import custom_object_builder
|
||||||
from ..utils import NOW, TYPE_REGEX
|
from ..properties import (BooleanProperty, DictionaryProperty,
|
||||||
|
EmbeddedObjectProperty, EnumProperty, FloatProperty,
|
||||||
|
IDProperty, IntegerProperty, ListProperty,
|
||||||
|
ObservableProperty, PatternProperty,
|
||||||
|
ReferenceProperty, StringProperty, TimestampProperty,
|
||||||
|
TypeProperty)
|
||||||
|
from ..utils import NOW
|
||||||
from .common import ExternalReference, GranularMarking, KillChainPhase
|
from .common import ExternalReference, GranularMarking, KillChainPhase
|
||||||
from .observables import ObservableProperty
|
|
||||||
from .properties import (BooleanProperty, DictionaryProperty,
|
|
||||||
EmbeddedObjectProperty, EnumProperty, FloatProperty,
|
|
||||||
IDProperty, IntegerProperty, ListProperty,
|
|
||||||
PatternProperty, ReferenceProperty, StringProperty,
|
|
||||||
TimestampProperty, TypeProperty)
|
|
||||||
|
|
||||||
|
|
||||||
class STIXDomainObject(_STIXBase, _MarkingsMixin):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class AttackPattern(STIXDomainObject):
|
class AttackPattern(STIXDomainObject):
|
||||||
|
@ -234,9 +230,9 @@ class AnalysisType(_STIXBase):
|
||||||
_properties = OrderedDict([
|
_properties = OrderedDict([
|
||||||
('start_time', TimestampProperty()),
|
('start_time', TimestampProperty()),
|
||||||
('end_time', TimestampProperty()),
|
('end_time', TimestampProperty()),
|
||||||
('analysis_tools', ObservableProperty()),
|
('analysis_tools', ObservableProperty(spec_version='2.1')),
|
||||||
('analysis_environment', DictionaryProperty()),
|
('analysis_environment', DictionaryProperty(spec_version='2.1')),
|
||||||
('results', DictionaryProperty(required=True))
|
('results', DictionaryProperty(spec_version='2.1', required=True))
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,7 +279,7 @@ class Malware(STIXDomainObject):
|
||||||
('os_execution_envs', ListProperty(StringProperty)),
|
('os_execution_envs', ListProperty(StringProperty)),
|
||||||
('architecture_execution_envs', ListProperty(StringProperty)),
|
('architecture_execution_envs', ListProperty(StringProperty)),
|
||||||
('implementation_languages', ListProperty(StringProperty)),
|
('implementation_languages', ListProperty(StringProperty)),
|
||||||
('samples', ObservableProperty()),
|
('samples', ObservableProperty(spec_version='2.1')),
|
||||||
('static_analysis_results', ListProperty(EmbeddedObjectProperty(AnalysisType))),
|
('static_analysis_results', ListProperty(EmbeddedObjectProperty(AnalysisType))),
|
||||||
('dynamic_analysis_results', ListProperty(EmbeddedObjectProperty(AnalysisType))),
|
('dynamic_analysis_results', ListProperty(EmbeddedObjectProperty(AnalysisType))),
|
||||||
('av_results', ListProperty(EmbeddedObjectProperty(AVResultsType))),
|
('av_results', ListProperty(EmbeddedObjectProperty(AVResultsType))),
|
||||||
|
@ -336,7 +332,7 @@ class ObservedData(STIXDomainObject):
|
||||||
('first_observed', TimestampProperty(required=True)),
|
('first_observed', TimestampProperty(required=True)),
|
||||||
('last_observed', TimestampProperty(required=True)),
|
('last_observed', TimestampProperty(required=True)),
|
||||||
('number_observed', IntegerProperty(required=True)),
|
('number_observed', IntegerProperty(required=True)),
|
||||||
('objects', ObservableProperty(required=True)),
|
('objects', ObservableProperty(spec_version='2.1', required=True)),
|
||||||
('revoked', BooleanProperty(default=lambda: False)),
|
('revoked', BooleanProperty(default=lambda: False)),
|
||||||
('labels', ListProperty(StringProperty)),
|
('labels', ListProperty(StringProperty)),
|
||||||
('confidence', IntegerProperty()),
|
('confidence', IntegerProperty()),
|
||||||
|
@ -507,6 +503,8 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
"""Custom STIX Object type decorator.
|
"""Custom STIX Object type decorator.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
>>> from stix2.v21 import CustomObject
|
||||||
|
>>> from stix2.properties import IntegerProperty, StringProperty
|
||||||
>>> @CustomObject('x-type-name', [
|
>>> @CustomObject('x-type-name', [
|
||||||
... ('property1', StringProperty(required=True)),
|
... ('property1', StringProperty(required=True)),
|
||||||
... ('property2', IntegerProperty()),
|
... ('property2', IntegerProperty()),
|
||||||
|
@ -518,6 +516,8 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
type. Don't call ``super().__init__()`` though - doing so will cause an error.
|
type. Don't call ``super().__init__()`` though - doing so will cause an error.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
>>> from stix2.v21 import CustomObject
|
||||||
|
>>> from stix2.properties import IntegerProperty, StringProperty
|
||||||
>>> @CustomObject('x-type-name', [
|
>>> @CustomObject('x-type-name', [
|
||||||
... ('property1', StringProperty(required=True)),
|
... ('property1', StringProperty(required=True)),
|
||||||
... ('property2', IntegerProperty()),
|
... ('property2', IntegerProperty()),
|
||||||
|
@ -526,35 +526,20 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
... def __init__(self, property2=None, **kwargs):
|
... def __init__(self, property2=None, **kwargs):
|
||||||
... if property2 and property2 < 10:
|
... if property2 and property2 < 10:
|
||||||
... raise ValueError("'property2' is too small.")
|
... raise ValueError("'property2' is too small.")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
def wrapper(cls):
|
||||||
def custom_builder(cls):
|
_properties = list(itertools.chain.from_iterable([
|
||||||
|
[
|
||||||
class _Custom(cls, STIXDomainObject):
|
('type', TypeProperty(type)),
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
_type = type
|
|
||||||
_properties = OrderedDict([
|
|
||||||
('type', TypeProperty(_type)),
|
|
||||||
('spec_version', StringProperty(fixed='2.1')),
|
('spec_version', StringProperty(fixed='2.1')),
|
||||||
('id', IDProperty(_type)),
|
('id', IDProperty(type)),
|
||||||
('created_by_ref', ReferenceProperty(type='identity')),
|
('created_by_ref', ReferenceProperty(type='identity')),
|
||||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||||
])
|
],
|
||||||
|
[x for x in properties if not x[0].startswith('x_')],
|
||||||
if not properties or not isinstance(properties, list):
|
[
|
||||||
raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]")
|
|
||||||
|
|
||||||
_properties.update([x for x in properties if not x[0].startswith('x_')])
|
|
||||||
|
|
||||||
# This is to follow the general properties structure.
|
|
||||||
_properties.update([
|
|
||||||
('revoked', BooleanProperty(default=lambda: False)),
|
('revoked', BooleanProperty(default=lambda: False)),
|
||||||
('labels', ListProperty(StringProperty)),
|
('labels', ListProperty(StringProperty)),
|
||||||
('confidence', IntegerProperty()),
|
('confidence', IntegerProperty()),
|
||||||
|
@ -562,23 +547,9 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
('external_references', ListProperty(ExternalReference)),
|
('external_references', ListProperty(ExternalReference)),
|
||||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))),
|
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))),
|
||||||
('granular_markings', ListProperty(GranularMarking)),
|
('granular_markings', ListProperty(GranularMarking)),
|
||||||
])
|
],
|
||||||
|
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')
|
||||||
|
|
||||||
# Put all custom properties at the bottom, sorted alphabetically.
|
return wrapper
|
||||||
_properties.update(sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]))
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
_STIXBase.__init__(self, **kwargs)
|
|
||||||
try:
|
|
||||||
cls.__init__(self, **kwargs)
|
|
||||||
except (AttributeError, TypeError) as e:
|
|
||||||
# Don't accidentally catch errors raised in a custom __init__()
|
|
||||||
if ("has no attribute '__init__'" in str(e) or
|
|
||||||
str(e) == "object.__init__() takes no parameters"):
|
|
||||||
return
|
|
||||||
raise e
|
|
||||||
|
|
||||||
_register_type(_Custom, version='2.1')
|
|
||||||
return _Custom
|
|
||||||
|
|
||||||
return custom_builder
|
|
||||||
|
|
Loading…
Reference in New Issue