Merge pull request #354 from khdesai/fix_issue_351
Add _id_contributing_properties functionality to custom SCOs. Tests c…master
						commit
						57d24adea9
					
				|  | @ -53,7 +53,10 @@ def _custom_marking_builder(cls, type, properties, version): | |||
|     return _CustomMarking | ||||
| 
 | ||||
| 
 | ||||
| def _custom_observable_builder(cls, type, properties, version): | ||||
| def _custom_observable_builder(cls, type, properties, version, id_contrib_props=None): | ||||
|     if id_contrib_props is None: | ||||
|         id_contrib_props = [] | ||||
| 
 | ||||
|     class _CustomObservable(cls, _Observable): | ||||
| 
 | ||||
|         if not re.match(TYPE_REGEX, type): | ||||
|  | @ -98,6 +101,8 @@ def _custom_observable_builder(cls, type, properties, version): | |||
| 
 | ||||
|         _type = type | ||||
|         _properties = OrderedDict(properties) | ||||
|         if version != '2.0': | ||||
|             _id_contributing_properties = id_contrib_props | ||||
| 
 | ||||
|         def __init__(self, **kwargs): | ||||
|             _Observable.__init__(self, **kwargs) | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| import uuid | ||||
| 
 | ||||
| import pytest | ||||
| 
 | ||||
| import stix2 | ||||
|  | @ -665,6 +667,76 @@ def test_observed_data_with_custom_observable_object(): | |||
|     assert ob_data.objects['0'].property1 == 'something' | ||||
| 
 | ||||
| 
 | ||||
| def test_custom_observable_object_det_id_1(): | ||||
|     @stix2.v21.CustomObservable( | ||||
|         'x-det-id-observable-1', [ | ||||
|             ('property1', stix2.properties.StringProperty(required=True)), | ||||
|             ('property2', stix2.properties.IntegerProperty()), | ||||
|         ], [ | ||||
|             'property1', | ||||
|         ], | ||||
|     ) | ||||
|     class DetIdObs1(): | ||||
|         pass | ||||
| 
 | ||||
|     dio_1 = DetIdObs1(property1='I am property1!', property2=42) | ||||
|     dio_2 = DetIdObs1(property1='I am property1!', property2=24) | ||||
|     assert dio_1.property1 == dio_2.property1 == 'I am property1!' | ||||
|     assert dio_1.id == dio_2.id | ||||
| 
 | ||||
|     uuid_obj = uuid.UUID(dio_1.id[-36:]) | ||||
|     assert uuid_obj.variant == uuid.RFC_4122 | ||||
|     assert uuid_obj.version == 5 | ||||
| 
 | ||||
|     dio_3 = DetIdObs1(property1='I am property1!', property2=42) | ||||
|     dio_4 = DetIdObs1(property1='I am also property1!', property2=24) | ||||
|     assert dio_3.property1 == 'I am property1!' | ||||
|     assert dio_4.property1 == 'I am also property1!' | ||||
|     assert dio_3.id != dio_4.id | ||||
| 
 | ||||
| 
 | ||||
| def test_custom_observable_object_det_id_2(): | ||||
|     @stix2.v21.CustomObservable( | ||||
|         'x-det-id-observable-2', [ | ||||
|             ('property1', stix2.properties.StringProperty(required=True)), | ||||
|             ('property2', stix2.properties.IntegerProperty()), | ||||
|         ], [ | ||||
|             'property1', 'property2', | ||||
|         ], | ||||
|     ) | ||||
|     class DetIdObs2(): | ||||
|         pass | ||||
| 
 | ||||
|     dio_1 = DetIdObs2(property1='I am property1!', property2=42) | ||||
|     dio_2 = DetIdObs2(property1='I am property1!', property2=42) | ||||
|     assert dio_1.property1 == dio_2.property1 == 'I am property1!' | ||||
|     assert dio_1.property2 == dio_2.property2 == 42 | ||||
|     assert dio_1.id == dio_2.id | ||||
| 
 | ||||
|     dio_3 = DetIdObs2(property1='I am property1!', property2=42) | ||||
|     dio_4 = DetIdObs2(property1='I am also property1!', property2=42) | ||||
|     assert dio_3.property1 == 'I am property1!' | ||||
|     assert dio_4.property1 == 'I am also property1!' | ||||
|     assert dio_3.property2 == dio_4.property2 == 42 | ||||
|     assert dio_3.id != dio_4.id | ||||
| 
 | ||||
| 
 | ||||
| def test_custom_observable_object_no_id_contrib_props(): | ||||
|     @stix2.v21.CustomObservable( | ||||
|         'x-det-id-observable-3', [ | ||||
|             ('property1', stix2.properties.StringProperty(required=True)), | ||||
|         ], | ||||
|     ) | ||||
|     class DetIdObs3(): | ||||
|         pass | ||||
| 
 | ||||
|     dio = DetIdObs3(property1="I am property1!") | ||||
| 
 | ||||
|     uuid_obj = uuid.UUID(dio.id[-36:]) | ||||
|     assert uuid_obj.variant == uuid.RFC_4122 | ||||
|     assert uuid_obj.version == 4 | ||||
| 
 | ||||
| 
 | ||||
| @stix2.v21.CustomExtension( | ||||
|     stix2.v21.DomainName, 'x-new-ext', [ | ||||
|         ('property1', stix2.properties.StringProperty(required=True)), | ||||
|  |  | |||
|  | @ -966,7 +966,7 @@ class X509Certificate(_Observable): | |||
|         self._check_at_least_one_property(att_list) | ||||
| 
 | ||||
| 
 | ||||
| def CustomObservable(type='x-custom-observable', properties=None): | ||||
| def CustomObservable(type='x-custom-observable', properties=None, id_contrib_props=None): | ||||
|     """Custom STIX Cyber Observable Object type decorator. | ||||
| 
 | ||||
|     Example: | ||||
|  | @ -987,7 +987,7 @@ def CustomObservable(type='x-custom-observable', properties=None): | |||
|             properties, | ||||
|             [('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=type))], | ||||
|         ])) | ||||
|         return _custom_observable_builder(cls, type, _properties, '2.1') | ||||
|         return _custom_observable_builder(cls, type, _properties, '2.1', id_contrib_props) | ||||
|     return wrapper | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Chris Lenk
						Chris Lenk