Merge pull request #165 from oasis-open/161-dictionaryproperty-fixes
Allow dictionaries in a ListPropertystix2.0
commit
a8b8bfe88b
|
@ -129,6 +129,8 @@ class ListProperty(Property):
|
||||||
# constructor again
|
# constructor again
|
||||||
result.append(valid)
|
result.append(valid)
|
||||||
continue
|
continue
|
||||||
|
elif type(self.contained) is DictionaryProperty:
|
||||||
|
obj_type = dict
|
||||||
else:
|
else:
|
||||||
obj_type = self.contained
|
obj_type = self.contained
|
||||||
|
|
||||||
|
|
|
@ -516,6 +516,27 @@ def test_custom_extension_wrong_observable_type():
|
||||||
assert 'Cannot determine extension type' in excinfo.value.reason
|
assert 'Cannot determine extension type' in excinfo.value.reason
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("data", [
|
||||||
|
"""{
|
||||||
|
"keys": [
|
||||||
|
{
|
||||||
|
"test123": 123,
|
||||||
|
"test345": "aaaa"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}""",
|
||||||
|
])
|
||||||
|
def test_custom_extension_with_list_and_dict_properties_observable_type(data):
|
||||||
|
@stix2.observables.CustomExtension(stix2.UserAccount, 'some-extension', [
|
||||||
|
('keys', stix2.properties.ListProperty(stix2.properties.DictionaryProperty, required=True))
|
||||||
|
])
|
||||||
|
class SomeCustomExtension:
|
||||||
|
pass
|
||||||
|
|
||||||
|
example = SomeCustomExtension(keys=[{'test123': 123, 'test345': 'aaaa'}])
|
||||||
|
assert data == str(example)
|
||||||
|
|
||||||
|
|
||||||
def test_custom_extension_invalid_observable():
|
def test_custom_extension_invalid_observable():
|
||||||
# These extensions are being applied to improperly-created Observables.
|
# These extensions are being applied to improperly-created Observables.
|
||||||
# The Observable classes should have been created with the CustomObservable decorator.
|
# The Observable classes should have been created with the CustomObservable decorator.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from stix2 import EmailMIMEComponent, ExtensionsProperty, TCPExt
|
from stix2 import CustomObject, EmailMIMEComponent, ExtensionsProperty, TCPExt
|
||||||
from stix2.exceptions import AtLeastOnePropertyError, DictionaryKeyError
|
from stix2.exceptions import AtLeastOnePropertyError, DictionaryKeyError
|
||||||
from stix2.properties import (BinaryProperty, BooleanProperty,
|
from stix2.properties import (BinaryProperty, BooleanProperty,
|
||||||
DictionaryProperty, EmbeddedObjectProperty,
|
DictionaryProperty, EmbeddedObjectProperty,
|
||||||
|
@ -266,6 +266,17 @@ def test_dictionary_property_invalid(d):
|
||||||
assert str(excinfo.value) == d[1]
|
assert str(excinfo.value) == d[1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_property_list_of_dictionary():
|
||||||
|
@CustomObject('x-new-obj', [
|
||||||
|
('property1', ListProperty(DictionaryProperty(), required=True)),
|
||||||
|
])
|
||||||
|
class NewObj():
|
||||||
|
pass
|
||||||
|
|
||||||
|
test_obj = NewObj(property1=[{'foo': 'bar'}])
|
||||||
|
assert test_obj.property1[0]['foo'] == 'bar'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("value", [
|
@pytest.mark.parametrize("value", [
|
||||||
{"sha256": "6db12788c37247f2316052e142f42f4b259d6561751e5f401a1ae2a6df9c674b"},
|
{"sha256": "6db12788c37247f2316052e142f42f4b259d6561751e5f401a1ae2a6df9c674b"},
|
||||||
[('MD5', '2dfb1bcc980200c6706feee399d41b3f'), ('RIPEMD-160', 'b3a8cd8a27c90af79b3c81754f267780f443dfef')],
|
[('MD5', '2dfb1bcc980200c6706feee399d41b3f'), ('RIPEMD-160', 'b3a8cd8a27c90af79b3c81754f267780f443dfef')],
|
||||||
|
|
|
@ -166,7 +166,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 it's a list look for
|
according to the _properties OrderedDict. If it's a list look for
|
||||||
individual objects.
|
individual objects. Returns and integer indicating its location
|
||||||
"""
|
"""
|
||||||
from .base import _STIXBase
|
from .base import _STIXBase
|
||||||
try:
|
try:
|
||||||
|
@ -183,6 +183,11 @@ def find_property_index(obj, properties, tuple_to_find):
|
||||||
tuple_to_find)
|
tuple_to_find)
|
||||||
if val is not None:
|
if val is not None:
|
||||||
return val
|
return val
|
||||||
|
elif isinstance(item, dict):
|
||||||
|
for idx, val in enumerate(sorted(item)):
|
||||||
|
if (tuple_to_find[0] == val and
|
||||||
|
item.get(val) == tuple_to_find[1]):
|
||||||
|
return idx
|
||||||
elif isinstance(pv, dict):
|
elif isinstance(pv, dict):
|
||||||
if pv.get(tuple_to_find[0]) is not None:
|
if pv.get(tuple_to_find[0]) is not None:
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue