{\n",
" "type": "identity",\n",
- " "id": "identity--87aac643-341b-413a-b702-ea5820416155",\n",
- " "created": "2018-04-05T18:38:10.269Z",\n",
- " "modified": "2018-04-05T18:38:10.269Z",\n",
+ " "id": "identity--e7fd0fe0-25ff-4fcb-abe5-b6254a9d1a22",\n",
+ " "created": "2019-07-25T18:18:18.241Z",\n",
+ " "modified": "2019-07-25T18:18:18.241Z",\n",
" "name": "John Smith",\n",
" "identity_class": "individual",\n",
" "x_foo": "bar"\n",
@@ -194,8 +194,6 @@
}
],
"source": [
- "from stix2 import Identity\n",
- "\n",
"identity = Identity(name=\"John Smith\",\n",
" identity_class=\"individual\",\n",
" custom_properties={\n",
@@ -289,9 +287,9 @@
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */{\n",
" "type": "identity",\n",
- " "id": "identity--a1ad0a6f-39ab-4642-9a72-aaa198b1eee2",\n",
- " "created": "2018-04-05T18:38:12.270Z",\n",
- " "modified": "2018-04-05T18:38:12.270Z",\n",
+ " "id": "identity--033b5f42-c94f-488f-8efa-2b6a167f0d6f",\n",
+ " "created": "2019-07-25T18:18:21.352Z",\n",
+ " "modified": "2019-07-25T18:18:21.352Z",\n",
" "name": "John Smith",\n",
" "identity_class": "individual",\n",
" "x_foo": "bar"\n",
@@ -426,6 +424,113 @@
"print(identity3.x_foo)"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "To remove a custom properties, use `new_version()` and set it to `None`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "{\n",
+ " "type": "identity",\n",
+ " "id": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c",\n",
+ " "created": "2015-12-21T19:59:11.000Z",\n",
+ " "modified": "2019-07-25T18:18:25.927Z",\n",
+ " "name": "John Smith",\n",
+ " "identity_class": "individual"\n",
+ "}\n",
+ "
\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "identity4 = identity3.new_version(x_foo=None)\n",
+ "print(identity4)"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
diff --git a/docs/guide/versioning.ipynb b/docs/guide/versioning.ipynb
index 6074d00..eb0708a 100644
--- a/docs/guide/versioning.ipynb
+++ b/docs/guide/versioning.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 1,
"metadata": {
"nbsphinx": "hidden"
},
@@ -22,7 +22,7 @@
},
{
"cell_type": "code",
- "execution_count": 3,
+ "execution_count": 2,
"metadata": {
"nbsphinx": "hidden"
},
@@ -63,12 +63,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "To create a new version of an existing object, specify the property(ies) you want to change and their new values:"
+ "To create a new version of an existing object, specify the property(ies) you want to change and their new values. For example, here we change the label from \"anomalous-activity\" to \"malicious-activity\":"
]
},
{
"cell_type": "code",
- "execution_count": 4,
+ "execution_count": 3,
"metadata": {},
"outputs": [
{
@@ -144,12 +144,13 @@
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */{\n",
" "type": "indicator",\n",
- " "id": "indicator--dd052ff6-e404-444b-beb9-eae96d1e79ea",\n",
+ " "id": "indicator--8ad18fc7-457c-475d-b292-1ec44febe0fd",\n",
" "created": "2016-01-01T08:00:00.000Z",\n",
- " "modified": "2018-04-05T20:02:51.161Z",\n",
+ " "modified": "2019-07-25T17:59:34.815Z",\n",
" "name": "File hash for Foobar malware",\n",
+ " "description": "A file indicator",\n",
" "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
- " "valid_from": "2018-04-05T20:02:51.138312Z",\n",
+ " "valid_from": "2019-07-25T17:59:34.779826Z",\n",
" "labels": [\n",
" "malicious-activity"\n",
" ]\n",
@@ -160,7 +161,7 @@
""
]
},
- "execution_count": 4,
+ "execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
@@ -170,6 +171,7 @@
"\n",
"indicator = Indicator(created=\"2016-01-01T08:00:00.000Z\",\n",
" name=\"File hash for suspicious file\",\n",
+ " description=\"A file indicator\",\n",
" labels=[\"anomalous-activity\"],\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"\n",
@@ -187,7 +189,7 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 4,
"metadata": {
"scrolled": true
},
@@ -205,6 +207,117 @@
"indicator.new_version(id=\"indicator--cc42e358-8b9b-493c-9646-6ecd73b41c21\")"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You can remove optional or custom properties by setting them to `None` when you call `new_version()`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "{\n",
+ " "type": "indicator",\n",
+ " "id": "indicator--8ad18fc7-457c-475d-b292-1ec44febe0fd",\n",
+ " "created": "2016-01-01T08:00:00.000Z",\n",
+ " "modified": "2019-07-25T17:59:42.648Z",\n",
+ " "name": "File hash for suspicious file",\n",
+ " "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
+ " "valid_from": "2019-07-25T17:59:34.779826Z",\n",
+ " "labels": [\n",
+ " "anomalous-activity"\n",
+ " ]\n",
+ "}\n",
+ "
\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "indicator3 = indicator.new_version(description=None)\n",
+ "print(indicator3)"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -292,15 +405,15 @@
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */{\n",
" "type": "indicator",\n",
- " "id": "indicator--dd052ff6-e404-444b-beb9-eae96d1e79ea",\n",
+ " "id": "indicator--8ad18fc7-457c-475d-b292-1ec44febe0fd",\n",
" "created": "2016-01-01T08:00:00.000Z",\n",
- " "modified": "2018-04-05T20:02:54.704Z",\n",
- " "name": "File hash for Foobar malware",\n",
+ " "modified": "2019-07-25T17:59:52.198Z",\n",
+ " "name": "File hash for suspicious file",\n",
" "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
- " "valid_from": "2018-04-05T20:02:51.138312Z",\n",
+ " "valid_from": "2019-07-25T17:59:34.779826Z",\n",
" "revoked": true,\n",
" "labels": [\n",
- " "malicious-activity"\n",
+ " "anomalous-activity"\n",
" ]\n",
"}\n",
"
\n"
@@ -315,8 +428,8 @@
}
],
"source": [
- "indicator2 = indicator2.revoke()\n",
- "print(indicator2)"
+ "indicator4 = indicator3.revoke()\n",
+ "print(indicator4)"
]
}
],
diff --git a/setup.cfg b/setup.cfg
index ae45560..b012bb9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 1.1.2
+current_version = 1.1.3
commit = True
tag = True
diff --git a/setup.py b/setup.py
index 07de2a4..497bf01 100644
--- a/setup.py
+++ b/setup.py
@@ -27,6 +27,7 @@ setup(
version=get_version(),
description='Produce and consume STIX 2 JSON content',
long_description=get_long_description(),
+ long_description_content_type='text/x-rst',
url='https://oasis-open.github.io/cti-documentation/',
author='OASIS Cyber Threat Intelligence Technical Committee',
author_email='cti-users@lists.oasis-open.org',
@@ -47,7 +48,7 @@ setup(
'Programming Language :: Python :: 3.7',
],
keywords='stix stix2 json cti cyber threat intelligence',
- packages=find_packages(exclude=['*.test']),
+ packages=find_packages(exclude=['*.test', '*.test.*']),
install_requires=[
'python-dateutil',
'pytz',
diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py
index bd247e6..1f9f5e8 100644
--- a/stix2/test/v21/test_markings.py
+++ b/stix2/test/v21/test_markings.py
@@ -25,7 +25,7 @@ EXPECTED_STATEMENT_MARKING_DEFINITION = """{
"type": "marking-definition",
"spec_version": "2.1",
"id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
- "created": "2017-01-20T00:00:00Z",
+ "created": "2017-01-20T00:00:00.000Z",
"definition_type": "statement",
"definition": {
"statement": "Copyright 2016, Example Corp"
diff --git a/stix2/v20/bundle.py b/stix2/v20/bundle.py
index 9e0b313..1383757 100644
--- a/stix2/v20/bundle.py
+++ b/stix2/v20/bundle.py
@@ -38,7 +38,7 @@ class Bundle(_STIXBase):
def get_obj(self, obj_uuid):
if "objects" in self._inner:
- found_objs = [elem for elem in self.objects if elem.id == obj_uuid]
+ found_objs = [elem for elem in self.objects if elem['id'] == obj_uuid]
if found_objs == []:
raise KeyError("'%s' does not match the id property of any of the bundle's objects" % obj_uuid)
return found_objs
diff --git a/stix2/v20/common.py b/stix2/v20/common.py
index 377d992..a1ffa60 100644
--- a/stix2/v20/common.py
+++ b/stix2/v20/common.py
@@ -3,6 +3,8 @@
from collections import OrderedDict
import copy
+import six
+
from ..base import _STIXBase
from ..custom import _custom_marking_builder
from ..markings import _MarkingsMixin
@@ -14,6 +16,21 @@ from ..properties import (
from ..utils import NOW, _get_dict
+def _should_set_millisecond(cr, marking_type):
+ # TLP instances in the 2.0 spec have millisecond precision unlike other markings
+ if marking_type == TLPMarking:
+ return True
+ # otherwise, precision is kept from how it was given
+ if isinstance(cr, six.string_types):
+ if '.' in cr:
+ return True
+ else:
+ return False
+ if cr.precision == 'millisecond':
+ return True
+ return False
+
+
class ExternalReference(_STIXBase):
"""For more detailed information on this object's properties, see
`the STIX 2.0 specification `__.
@@ -122,12 +139,12 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
except KeyError:
raise ValueError("definition_type must be a valid marking type")
- if marking_type == TLPMarking:
- # TLP instances in the spec have millisecond precision unlike other markings
- self._properties = copy.deepcopy(self._properties)
- self._properties.update([
- ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
- ])
+ if 'created' in kwargs:
+ if _should_set_millisecond(kwargs['created'], marking_type):
+ self._properties = copy.deepcopy(self._properties)
+ self._properties.update([
+ ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
+ ])
if not isinstance(kwargs['definition'], marking_type):
defn = _get_dict(kwargs['definition'])
diff --git a/stix2/v21/bundle.py b/stix2/v21/bundle.py
index 4ebd96c..fb35be2 100644
--- a/stix2/v21/bundle.py
+++ b/stix2/v21/bundle.py
@@ -36,7 +36,7 @@ class Bundle(_STIXBase):
def get_obj(self, obj_uuid):
if "objects" in self._inner:
- found_objs = [elem for elem in self.objects if elem.id == obj_uuid]
+ found_objs = [elem for elem in self.objects if elem['id'] == obj_uuid]
if found_objs == []:
raise KeyError("'%s' does not match the id property of any of the bundle's objects" % obj_uuid)
return found_objs
diff --git a/stix2/v21/common.py b/stix2/v21/common.py
index 44d3675..a31e710 100644
--- a/stix2/v21/common.py
+++ b/stix2/v21/common.py
@@ -1,7 +1,6 @@
"""STIX 2.1 Common Data Types and Properties."""
from collections import OrderedDict
-import copy
from ..base import _STIXBase
from ..custom import _custom_marking_builder
@@ -146,7 +145,7 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type)),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
- ('created', TimestampProperty(default=lambda: NOW)),
+ ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
@@ -162,13 +161,6 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
except KeyError:
raise ValueError("definition_type must be a valid marking type")
- if marking_type == TLPMarking:
- # TLP instances in the spec have millisecond precision unlike other markings
- self._properties = copy.deepcopy(self._properties)
- self._properties.update([
- ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
- ])
-
if not isinstance(kwargs['definition'], marking_type):
defn = _get_dict(kwargs['definition'])
kwargs['definition'] = marking_type(**defn)
diff --git a/stix2/version.py b/stix2/version.py
index 72f26f5..0b2f79d 100644
--- a/stix2/version.py
+++ b/stix2/version.py
@@ -1 +1 @@
-__version__ = "1.1.2"
+__version__ = "1.1.3"
diff --git a/tox.ini b/tox.ini
index d4ab42c..2225bae 100644
--- a/tox.ini
+++ b/tox.ini
@@ -32,9 +32,10 @@ commands =
[testenv:packaging]
deps =
- readme_renderer
+ twine
commands =
- python setup.py check -r -s
+ python setup.py bdist_wheel --universal
+ twine check dist/*
[travis]
python =