Merge branch 'documentation' of https://github.com/oasis-open/cti-python-stix2 into documentation
commit
54e917110e
|
@ -1,5 +0,0 @@
|
||||||
base
|
|
||||||
==========
|
|
||||||
|
|
||||||
.. automodule:: stix2.base
|
|
||||||
:members:
|
|
|
@ -19,6 +19,7 @@ autodoc_member_order = 'groupwise'
|
||||||
autosummary_generate = True
|
autosummary_generate = True
|
||||||
napoleon_numpy_docstring = False # Force consistency, leave only Google
|
napoleon_numpy_docstring = False # Force consistency, leave only Google
|
||||||
napoleon_use_rtype = False
|
napoleon_use_rtype = False
|
||||||
|
add_module_names = False
|
||||||
|
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
source_suffix = '.rst'
|
source_suffix = '.rst'
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
:toctree: api
|
:toctree: api
|
||||||
|
|
||||||
base
|
|
||||||
common
|
common
|
||||||
core
|
core
|
||||||
environment
|
environment
|
||||||
|
|
|
@ -65,7 +65,7 @@ class StatementMarking(_STIXBase):
|
||||||
|
|
||||||
|
|
||||||
class MarkingProperty(Property):
|
class MarkingProperty(Property):
|
||||||
"""Represent the marking objects in the `definition` property of
|
"""Represent the marking objects in the ``definition`` property of
|
||||||
marking-definition objects.
|
marking-definition objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -120,17 +120,15 @@ def _register_marking(cls):
|
||||||
|
|
||||||
|
|
||||||
def CustomMarking(type='x-custom-marking', properties=None):
|
def CustomMarking(type='x-custom-marking', properties=None):
|
||||||
"""
|
"""Custom STIX Marking decorator.
|
||||||
Custom STIX Marking decorator.
|
|
||||||
|
|
||||||
Examples:
|
Example:
|
||||||
|
>>> @CustomMarking('x-custom-marking', [
|
||||||
@CustomMarking('x-custom-marking', [
|
... ('property1', StringProperty(required=True)),
|
||||||
('property1', StringProperty(required=True)),
|
... ('property2', IntegerProperty()),
|
||||||
('property2', IntegerProperty()),
|
... ])
|
||||||
])
|
... class MyNewMarkingObjectType():
|
||||||
class MyNewMarkingObjectType():
|
... pass
|
||||||
pass
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def custom_builder(cls):
|
def custom_builder(cls):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
"""STIX 2.0 Objects that are neither SDOs nor SROs"""
|
"""STIX 2.0 Objects that are neither SDOs nor SROs."""
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ class STIXError(Exception):
|
||||||
|
|
||||||
|
|
||||||
class InvalidValueError(STIXError, ValueError):
|
class InvalidValueError(STIXError, ValueError):
|
||||||
"""An invalid value was provided to a STIX object's __init__."""
|
"""An invalid value was provided to a STIX object's ``__init__``."""
|
||||||
|
|
||||||
def __init__(self, cls, prop_name, reason):
|
def __init__(self, cls, prop_name, reason):
|
||||||
super(InvalidValueError, self).__init__()
|
super(InvalidValueError, self).__init__()
|
||||||
|
@ -45,7 +45,7 @@ class ExtraPropertiesError(STIXError, TypeError):
|
||||||
|
|
||||||
|
|
||||||
class ImmutableError(STIXError, ValueError):
|
class ImmutableError(STIXError, ValueError):
|
||||||
"""Attempted to modify an object after creation"""
|
"""Attempted to modify an object after creation."""
|
||||||
|
|
||||||
def __init__(self, cls, key):
|
def __init__(self, cls, key):
|
||||||
super(ImmutableError, self).__init__()
|
super(ImmutableError, self).__init__()
|
||||||
|
@ -85,7 +85,7 @@ class InvalidObjRefError(STIXError, ValueError):
|
||||||
|
|
||||||
|
|
||||||
class UnmodifiablePropertyError(STIXError, ValueError):
|
class UnmodifiablePropertyError(STIXError, ValueError):
|
||||||
"""Attempted to modify an unmodifiable property of object when creating a new version"""
|
"""Attempted to modify an unmodifiable property of object when creating a new version."""
|
||||||
|
|
||||||
def __init__(self, unchangable_properties):
|
def __init__(self, unchangable_properties):
|
||||||
super(UnmodifiablePropertyError, self).__init__()
|
super(UnmodifiablePropertyError, self).__init__()
|
||||||
|
@ -139,7 +139,7 @@ class AtLeastOnePropertyError(STIXError, TypeError):
|
||||||
|
|
||||||
|
|
||||||
class RevokeError(STIXError, ValueError):
|
class RevokeError(STIXError, ValueError):
|
||||||
"""Attempted to an operation on a revoked object"""
|
"""Attempted to an operation on a revoked object."""
|
||||||
|
|
||||||
def __init__(self, called_by):
|
def __init__(self, called_by):
|
||||||
super(RevokeError, self).__init__()
|
super(RevokeError, self).__init__()
|
||||||
|
@ -153,7 +153,7 @@ class RevokeError(STIXError, ValueError):
|
||||||
|
|
||||||
|
|
||||||
class ParseError(STIXError, ValueError):
|
class ParseError(STIXError, ValueError):
|
||||||
"""Could not parse object"""
|
"""Could not parse object."""
|
||||||
|
|
||||||
def __init__(self, msg):
|
def __init__(self, msg):
|
||||||
super(ParseError, self).__init__(msg)
|
super(ParseError, self).__init__(msg)
|
||||||
|
|
|
@ -6,7 +6,7 @@ granular markings unless otherwise noted in each of the functions.
|
||||||
|
|
||||||
|
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
:toctree: api
|
:toctree: markings
|
||||||
|
|
||||||
granular_markings
|
granular_markings
|
||||||
object_markings
|
object_markings
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Functions for working with STIX 2.0 granular markings.
|
||||||
|
"""
|
||||||
|
|
||||||
from stix2 import exceptions
|
from stix2 import exceptions
|
||||||
from stix2.markings import utils
|
from stix2.markings import utils
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Functions for working with STIX 2.0 object markings.
|
||||||
|
"""
|
||||||
|
|
||||||
from stix2 import exceptions
|
from stix2 import exceptions
|
||||||
from stix2.markings import utils
|
from stix2.markings import utils
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Utility functions for STIX 2.0 data markings.
|
||||||
|
"""
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"""STIX 2.0 Cyber Observable Objects
|
"""STIX 2.0 Cyber Observable Objects.
|
||||||
|
|
||||||
Embedded observable object types, such as Email MIME Component, which is
|
Embedded observable object types, such as Email MIME Component, which is
|
||||||
embedded in Email Message objects, inherit from _STIXBase instead of Observable
|
embedded in Email Message objects, inherit from ``_STIXBase`` instead of
|
||||||
and do not have a '_type' attribute.
|
Observable and do not have a ``_type`` attribute.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
@ -19,6 +19,8 @@ from .utils import get_dict
|
||||||
|
|
||||||
|
|
||||||
class ObservableProperty(Property):
|
class ObservableProperty(Property):
|
||||||
|
"""Property for holding Cyber Observable Objects.
|
||||||
|
"""
|
||||||
|
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
try:
|
try:
|
||||||
|
@ -39,7 +41,7 @@ class ObservableProperty(Property):
|
||||||
|
|
||||||
|
|
||||||
class ExtensionsProperty(DictionaryProperty):
|
class ExtensionsProperty(DictionaryProperty):
|
||||||
""" Property for representing extensions on Observable objects
|
"""Property for representing extensions on Observable objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, enclosing_type=None, required=False):
|
def __init__(self, enclosing_type=None, required=False):
|
||||||
|
@ -138,7 +140,6 @@ class EmailAddress(_Observable):
|
||||||
('display_name', StringProperty()),
|
('display_name', StringProperty()),
|
||||||
('belongs_to_ref', ObjectReferenceProperty(valid_types='user-account')),
|
('belongs_to_ref', ObjectReferenceProperty(valid_types='user-account')),
|
||||||
('extensions', ExtensionsProperty(enclosing_type=_type)),
|
('extensions', ExtensionsProperty(enclosing_type=_type)),
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@ -798,16 +799,15 @@ def _register_observable(new_observable):
|
||||||
|
|
||||||
|
|
||||||
def CustomObservable(type='x-custom-observable', properties=None):
|
def CustomObservable(type='x-custom-observable', properties=None):
|
||||||
"""Custom STIX Cyber Observable type decorator
|
"""Custom STIX Cyber Observable Object type decorator.
|
||||||
|
|
||||||
Example 1:
|
Example:
|
||||||
|
>>> @CustomObservable('x-custom-observable', [
|
||||||
@CustomObservable('x-custom-observable', [
|
... ('property1', StringProperty(required=True)),
|
||||||
('property1', StringProperty(required=True)),
|
... ('property2', IntegerProperty()),
|
||||||
('property2', IntegerProperty()),
|
... ])
|
||||||
])
|
... class MyNewObservableType():
|
||||||
class MyNewObservableType():
|
... pass
|
||||||
pass
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def custom_builder(cls):
|
def custom_builder(cls):
|
||||||
|
@ -873,7 +873,7 @@ def _register_extension(observable, new_extension):
|
||||||
|
|
||||||
|
|
||||||
def CustomExtension(observable=None, type='x-custom-observable', properties={}):
|
def CustomExtension(observable=None, type='x-custom-observable', properties={}):
|
||||||
"""Decorator for custom extensions to STIX Cyber Observables
|
"""Decorator for custom extensions to STIX Cyber Observables.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not observable or not issubclass(observable, _Observable):
|
if not observable or not issubclass(observable, _Observable):
|
||||||
|
|
|
@ -19,43 +19,44 @@ class Property(object):
|
||||||
"""Represent a property of STIX data type.
|
"""Represent a property of STIX data type.
|
||||||
|
|
||||||
Subclasses can define the following attributes as keyword arguments to
|
Subclasses can define the following attributes as keyword arguments to
|
||||||
__init__():
|
``__init__()``.
|
||||||
|
|
||||||
- `required` - If `True`, the property must be provided when creating an
|
Args:
|
||||||
object with that property. No default value exists for these properties.
|
required (bool): If ``True``, the property must be provided when creating an
|
||||||
(Default: `False`)
|
object with that property. No default value exists for these properties.
|
||||||
- `fixed` - This provides a constant default value. Users are free to
|
(Default: ``False``)
|
||||||
provide this value explicity when constructing an object (which allows
|
fixed: This provides a constant default value. Users are free to
|
||||||
you to copy *all* values from an existing object to a new object), but
|
provide this value explicity when constructing an object (which allows
|
||||||
if the user provides a value other than the `fixed` value, it will raise
|
you to copy **all** values from an existing object to a new object), but
|
||||||
an error. This is semantically equivalent to defining both:
|
if the user provides a value other than the ``fixed`` value, it will raise
|
||||||
- a `clean()` function that checks if the value matches the fixed
|
an error. This is semantically equivalent to defining both:
|
||||||
value, and
|
|
||||||
- a `default()` function that returns the fixed value.
|
|
||||||
(Default: `None`)
|
|
||||||
|
|
||||||
Subclasses can also define the following functions.
|
- a ``clean()`` function that checks if the value matches the fixed
|
||||||
|
value, and
|
||||||
|
- a ``default()`` function that returns the fixed value.
|
||||||
|
|
||||||
- `def clean(self, value) -> any:`
|
Subclasses can also define the following functions:
|
||||||
- Return a value that is valid for this property. If `value` is not
|
|
||||||
|
- ``def clean(self, value) -> any:``
|
||||||
|
- Return a value that is valid for this property. If ``value`` is not
|
||||||
valid for this property, this will attempt to transform it first. If
|
valid for this property, this will attempt to transform it first. If
|
||||||
`value` is not valid and no such transformation is possible, it should
|
``value`` is not valid and no such transformation is possible, it should
|
||||||
raise a ValueError.
|
raise a ValueError.
|
||||||
- `def default(self):`
|
- ``def default(self):``
|
||||||
- provide a default value for this property.
|
- provide a default value for this property.
|
||||||
- `default()` can return the special value `NOW` to use the current
|
- ``default()`` can return the special value ``NOW`` to use the current
|
||||||
time. This is useful when several timestamps in the same object need
|
time. This is useful when several timestamps in the same object need
|
||||||
to use the same default value, so calling now() for each property--
|
to use the same default value, so calling now() for each property--
|
||||||
likely several microseconds apart-- does not work.
|
likely several microseconds apart-- does not work.
|
||||||
|
|
||||||
Subclasses can instead provide a lambda function for `default` as a keyword
|
Subclasses can instead provide a lambda function for ``default`` as a keyword
|
||||||
argument. `clean` should not be provided as a lambda since lambdas cannot
|
argument. ``clean`` should not be provided as a lambda since lambdas cannot
|
||||||
raise their own exceptions.
|
raise their own exceptions.
|
||||||
|
|
||||||
When instantiating Properties, `required` and `default` should not be used
|
When instantiating Properties, ``required`` and ``default`` should not be used
|
||||||
together. `default` implies that the property is required in the specification
|
together. ``default`` implies that the property is required in the specification
|
||||||
so this function will be used to supply a value if none is provided.
|
so this function will be used to supply a value if none is provided.
|
||||||
`required` means that the user must provide this; it is required in the
|
``required`` means that the user must provide this; it is required in the
|
||||||
specification and we can't or don't want to create a default value.
|
specification and we can't or don't want to create a default value.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -88,7 +89,7 @@ class ListProperty(Property):
|
||||||
|
|
||||||
def __init__(self, contained, **kwargs):
|
def __init__(self, contained, **kwargs):
|
||||||
"""
|
"""
|
||||||
Contained should be a function which returns an object from the value.
|
``contained`` should be a function which returns an object from the value.
|
||||||
"""
|
"""
|
||||||
if inspect.isclass(contained) and issubclass(contained, Property):
|
if inspect.isclass(contained) and issubclass(contained, Property):
|
||||||
# If it's a class and not an instance, instantiate it so that
|
# If it's a class and not an instance, instantiate it so that
|
||||||
|
|
|
@ -298,8 +298,8 @@ def CustomObject(type='x-custom-type', properties=None):
|
||||||
... class MyNewObjectType():
|
... class MyNewObjectType():
|
||||||
... pass
|
... pass
|
||||||
|
|
||||||
Supply an __init__() function to add any special validations to the custom
|
Supply an ``__init__()`` function to add any special validations to the custom
|
||||||
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:
|
||||||
>>> @CustomObject('x-type-name', [
|
>>> @CustomObject('x-type-name', [
|
||||||
|
|
|
@ -16,7 +16,7 @@ Note:
|
||||||
|
|
||||||
|
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
:toctree: api
|
:toctree: sources
|
||||||
|
|
||||||
filters
|
filters
|
||||||
filesystem
|
filesystem
|
||||||
|
|
|
@ -34,16 +34,21 @@ class STIXdatetime(dt.datetime):
|
||||||
|
|
||||||
|
|
||||||
def get_timestamp():
|
def get_timestamp():
|
||||||
|
"""Return a STIX timestamp of the current date and time."""
|
||||||
return STIXdatetime.now(tz=pytz.UTC)
|
return STIXdatetime.now(tz=pytz.UTC)
|
||||||
|
|
||||||
|
|
||||||
def format_datetime(dttm):
|
def format_datetime(dttm):
|
||||||
# 1. Convert to timezone-aware
|
"""Convert a datetime object into a valid STIX timestamp string.
|
||||||
# 2. Convert to UTC
|
|
||||||
# 3. Format in ISO format
|
1. Convert to timezone-aware
|
||||||
# 4. Ensure correct precision
|
2. Convert to UTC
|
||||||
# 4a. Add subsecond value if non-zero and precision not defined
|
3. Format in ISO format
|
||||||
# 5. Add "Z"
|
4. Ensure correct precision
|
||||||
|
a. Add subsecond value if non-zero and precision not defined
|
||||||
|
5. Add "Z"
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
if dttm.tzinfo is None or dttm.tzinfo.utcoffset(dttm) is None:
|
if dttm.tzinfo is None or dttm.tzinfo.utcoffset(dttm) is None:
|
||||||
# dttm is timezone-naive; assume UTC
|
# dttm is timezone-naive; assume UTC
|
||||||
|
@ -63,6 +68,8 @@ def format_datetime(dttm):
|
||||||
|
|
||||||
|
|
||||||
def parse_into_datetime(value, precision=None):
|
def parse_into_datetime(value, precision=None):
|
||||||
|
"""Parse a value into a valid STIX timestamp object.
|
||||||
|
"""
|
||||||
if isinstance(value, dt.date):
|
if isinstance(value, dt.date):
|
||||||
if hasattr(value, 'hour'):
|
if hasattr(value, 'hour'):
|
||||||
ts = value
|
ts = value
|
||||||
|
@ -102,6 +109,7 @@ def parse_into_datetime(value, precision=None):
|
||||||
|
|
||||||
def get_dict(data):
|
def get_dict(data):
|
||||||
"""Return data as a dictionary.
|
"""Return data as a dictionary.
|
||||||
|
|
||||||
Input can be a dictionary, string, or file-like object.
|
Input can be a dictionary, string, or file-like object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -124,7 +132,7 @@ def get_dict(data):
|
||||||
|
|
||||||
def find_property_index(obj, properties, tuple_to_find):
|
def find_property_index(obj, properties, tuple_to_find):
|
||||||
"""Recursively find the property in the object model, return the index
|
"""Recursively find the property in the object model, return the index
|
||||||
according to the _properties OrderedDict. If its a list look for
|
according to the _properties OrderedDict. If it's a list look for
|
||||||
individual objects.
|
individual objects.
|
||||||
"""
|
"""
|
||||||
from .base import _STIXBase
|
from .base import _STIXBase
|
||||||
|
@ -159,7 +167,7 @@ def find_property_index(obj, properties, tuple_to_find):
|
||||||
|
|
||||||
def new_version(data, **kwargs):
|
def new_version(data, **kwargs):
|
||||||
"""Create a new version of a STIX object, by modifying properties and
|
"""Create a new version of a STIX object, by modifying properties and
|
||||||
updating the `modified` property.
|
updating the ``modified`` property.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not isinstance(data, Mapping):
|
if not isinstance(data, Mapping):
|
||||||
|
@ -196,6 +204,11 @@ def new_version(data, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def revoke(data):
|
def revoke(data):
|
||||||
|
"""Revoke a STIX object.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A new version of the object with ``revoked`` set to ``True``.
|
||||||
|
"""
|
||||||
if not isinstance(data, Mapping):
|
if not isinstance(data, Mapping):
|
||||||
raise ValueError('cannot revoke object of this type! Try a dictionary '
|
raise ValueError('cannot revoke object of this type! Try a dictionary '
|
||||||
'or instance of an SDO or SRO class.')
|
'or instance of an SDO or SRO class.')
|
||||||
|
|
Loading…
Reference in New Issue