Extension decorators and registry don't support extensions with multiple 'extension_types'
I tried to use the extension decorators to reproduce the extension example from the standard: Adding two new STIX objects and properties to an existing STIX object instance.
The code is as follows:
from stix2.v21 import CustomExtension, CustomObject, CustomObservable, ExtensionDefinition
from stix2.properties import StringProperty, IntegerProperty
EXAMPLE_EXTENSION_ID = 'extension-definition--c5333451-c08c-4c48-be5e-9ad4c947776a'
EXAMPLE_EXTENSION_DEFINITION = ExtensionDefinition(id = EXAMPLE_EXTENSION_ID,
name = 'Extension My Favorite SDO and Sub-Comp',
description = 'This schema adds a new object my-favorite-sdo and some sub-component to existing objects',
created = '2014-02-20T09:16:08.989000Z',
modified = '2014-02-20T09:16:08.989000Z',
created_by_ref = 'identity--c1694394-c150-4f80-a69a-59ca5e850df4',
schema = 'https://www.example.com/schema-newobj-subcomp/v1/schema.json',
version = '1.2.1',
extension_types = ['new-sdo','new-sco','property-extension'])
@CustomExtension(
EXAMPLE_EXTENSION_ID,
[
('rank', IntegerProperty(required=True)),
('toxicity', IntegerProperty(required=True)),
]
)
class ExamplePropertyExtension:
extension_type = 'property-extension'
@CustomObject('my-favorite-sdo',
[
('some_field', StringProperty(required=True)),
],
extension_name = EXAMPLE_EXTENSION_ID
)
class MyFavoriteSdo:
pass
@CustomObject('my-favorite-sco',
[
('some_network_protocol_field', StringProperty(required=True)),
],
extension_name = EXAMPLE_EXTENSION_ID
)
class MyFavoriteSco:
pass
sdo = MyFavoriteSdo(id = 'my-favorite-sdo--a5461d2e-7ba9-43ef-9b3e-11471d1ad8da',
created = '2014-02-20T09:16:08.989000Z',
modified = '2014-02-20T09:16:08.989000Z',
name = 'This is the name of my favorite',
some_field = 'value')
print(sdo.serialize(pretty=True))
However, the library's extension registry does not support using the same extension id for multiple purposes and throws an exception
stix2.exceptions.DuplicateRegistrationError: A(n) Extension with type 'extension-definition--c5333451-c08c-4c48-be5e-9ad4c947776a' already exists and cannot be registered again.
I tried a few alternative approaches that also did not work:
-
Omitting
extension_nameforCustomObjectandCustomObservableand referencing the extension in the class usingwith_extension.This results in an exception building the SDO:
MissingPropertiesError: No values for required properties for ExamplePropertyExtension: (rank, toxicity). -
Omitting
extension_nameandwith_extensionwhile using__init__to populate the extension_type asnew-sdoornew-sco, as appropriate. This results in an exception building the SDO:InvalidValueError: Invalid value for ExamplePropertyExtension 'extension_type': must equal 'property-extension'.
As far as I have been able to discern, it is not possible to create these objects using any public API of the library.
Just an acknowledgement: yeah, the library doesn't currently support "hybrid" extensions. I think it was just a design oversight. For now, I don't know of an effort to fix/extend the design to cover that type of extension.