add new-sdo or new-sro option in CustomObject decorator, add a test, and example in guide

pull/1/head
Emmanuelle Vargas-Gonzalez 2021-03-31 18:46:37 -04:00
parent 08d5781f54
commit af046beeb5
3 changed files with 191 additions and 7 deletions

View File

@ -57,10 +57,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"STIX Extensions\n",
"## STIX Extensions\n",
"\n",
"This page is specific for the STIX Extensions mechanism defined in STIX 2.1 CS 02, for the deprecated STIX Customization mechanisms see the [Custom](custom.ipynb) section.\n",
"\n",
"### Top Level Property Extensions\n",
"\n",
"The example below shows how to create an `indicator` object with a `top-level-property-extension`. "
]
},
@ -332,6 +334,8 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using CustomExtension decorator\n",
"\n",
"However, in order to prevent repetitive instantiation of the same extension, the `@CustomExtension` when used in a class for registering the `extension-definition` with stix2, it allows passing the id. Use the `extension_type` class variable to define what kind of extension it is."
]
},
@ -490,7 +494,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Similarly, now when registering new objects `@CustomObject` now supports passing an `extension-definition` id. \n",
"### Using CustomObservable for Extension Definition\n",
"\n",
"Similarly, when registering new objects via `@CustomObservable` you can pass the `extension-definition` id that defines this new SCO. \n",
"\n",
"---\n",
"**Note:**\n",
@ -501,7 +507,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 3,
"metadata": {},
"outputs": [
{
@ -598,7 +604,7 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 15,
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
@ -626,6 +632,8 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using CustomMarking for Extension Definition\n",
"\n",
"The example below shows the use for MarkingDefinition extensions. Currently this is only supported as a `property-extension`. Now, as another option to building the `extensions` as a dictionary, it can also be built with objects as shown below by extracting the registered class."
]
},
@ -757,10 +765,148 @@
"\n",
"print(my_favorite_marking.serialize(pretty=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using CustomObject for Extension Definition\n",
"\n",
"Similar to the examples above, the same can be done for SDOs and SROs."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">pre { line-height: 125%; margin: 0; }\n",
"td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
".highlight .o { color: #666666 } /* Operator */\n",
".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
".highlight .ge { font-style: italic } /* Generic.Emph */\n",
".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
".highlight .go { color: #888888 } /* Generic.Output */\n",
".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
".highlight .m { color: #666666 } /* Literal.Number */\n",
".highlight .s { color: #BA2121 } /* Literal.String */\n",
".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
".highlight .nb { color: #008000 } /* Name.Builtin */\n",
".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
".highlight .no { color: #880000 } /* Name.Constant */\n",
".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
".highlight .nf { color: #0000FF } /* Name.Function */\n",
".highlight .nl { color: #A0A000 } /* Name.Label */\n",
".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
".highlight .nv { color: #19177C } /* Name.Variable */\n",
".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;my-favorite-sro&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;my-favorite-sro--d6306d62-c08d-4d78-baf7-11e7a4c9bc36&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-03-31T22:43:42.807698Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-03-31T22:43:42.807698Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;My First SRO&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;some_source_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;some_target_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;extensions&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;new-sro&quot;</span>\n",
" <span class=\"p\">}</span>\n",
" <span class=\"p\">}</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"invalid_refs = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting', 'foobar']\n",
"\n",
"@stix2.v21.CustomObject(\n",
" 'my-favorite-sro', [\n",
" ('name', stix2.properties.StringProperty(required=False)),\n",
" ('some_source_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n",
" ('some_target_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n",
" ], extension_name='extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce', is_sdo=False,\n",
")\n",
"class MyFavSRO:\n",
" pass\n",
"\n",
"\n",
"my_favorite_sro = MyFavSRO(\n",
" name=\"My First SRO\",\n",
" some_source_ref=\"identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d\",\n",
" some_target_ref=\"identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685\",\n",
")\n",
"\n",
"print(my_favorite_sro.serialize(pretty=True))"
]
}
],
"metadata": {
"celltoolbar": "Edit Metadata",
"kernelspec": {
"display_name": "Python 3",
"language": "python",

View File

@ -1462,6 +1462,41 @@ def test_registered_new_extension_sdo_allow_custom_false():
assert '"extensions": {"extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e9999": {"extension_type": "new-sdo"}}' in sdo_serialized
def test_registered_new_extension_sro_allow_custom_false():
@stix2.v21.CustomObject(
'my-favorite-sro', [
('name', stix2.properties.StringProperty(required=True)),
('some_property_name1', stix2.properties.StringProperty(required=True)),
('some_property_name2', stix2.properties.StringProperty()),
], 'extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce', False,
)
class MyFavSRO:
pass
my_favorite_sro = {
'type': 'my-favorite-sro',
'spec_version': '2.1',
'id': 'my-favorite-sro--c5ba9dba-5ad9-4bbe-9825-df4cb8675774',
'created': '2014-02-20T09:16:08.989000Z',
'modified': '2014-02-20T09:16:08.989000Z',
'name': 'This is the name of my favorite',
'some_property_name1': 'value1',
'some_property_name2': 'value2',
# 'extensions': {
# 'extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce': ExtensionDefinitiond83fce45ef584c6ca3f41fbc32e98c6e()
# }
}
sro_object = stix2.parse(my_favorite_sro)
assert isinstance(sro_object, MyFavSRO)
assert isinstance(
sro_object.extensions['extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce'],
stix2.v21.EXT_MAP['extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce'],
)
sdo_serialized = sro_object.serialize()
assert '"extensions": {"extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce": {"extension_type": "new-sro"}}' in sdo_serialized
def test_registered_new_extension_sco_allow_custom_false():
@stix2.v21.CustomObservable(
'my-favorite-sco', [

View File

@ -806,7 +806,7 @@ class Vulnerability(_DomainObject):
])
def CustomObject(type='x-custom-type', properties=None, extension_name=None):
def CustomObject(type='x-custom-type', properties=None, extension_name=None, is_sdo=True):
"""Custom STIX Object type decorator.
Example:
@ -864,7 +864,10 @@ def CustomObject(type='x-custom-type', properties=None, extension_name=None):
if extension_name:
@observables.CustomExtension(type=extension_name, properties=extension_properties)
class NameExtension:
extension_type = 'new-sdo'
if is_sdo:
extension_type = 'new-sdo'
else:
extension_type = 'new-sro'
extension = extension_name.split('--')[1]
extension = extension.replace('-', '')