encryption_algorithm was misspelled
uncomment test_file_example_encryption_error added _check_object_constrains and properties_populated to base class added ObjectConstraintError added _check_object_constrains for Filestix2.1
parent
5de2cfe6a8
commit
c3477b83bf
|
@ -49,6 +49,12 @@ class _STIXBase(collections.Mapping):
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
raise InvalidValueError(self.__class__, prop_name, reason=str(exc))
|
raise InvalidValueError(self.__class__, prop_name, reason=str(exc))
|
||||||
|
|
||||||
|
def _check_object_constaints(self):
|
||||||
|
if self.granular_markings:
|
||||||
|
for m in self.granular_markings:
|
||||||
|
# TODO: check selectors
|
||||||
|
pass
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
cls = self.__class__
|
cls = self.__class__
|
||||||
|
|
||||||
|
@ -77,10 +83,7 @@ class _STIXBase(collections.Mapping):
|
||||||
|
|
||||||
self._inner = setting_kwargs
|
self._inner = setting_kwargs
|
||||||
|
|
||||||
if self.granular_markings:
|
self._check_object_constaints()
|
||||||
for m in self.granular_markings:
|
|
||||||
# TODO: check selectors
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return self._inner[key]
|
return self._inner[key]
|
||||||
|
@ -116,6 +119,9 @@ class _STIXBase(collections.Mapping):
|
||||||
cls = type(self)
|
cls = type(self)
|
||||||
return cls(**new_inner)
|
return cls(**new_inner)
|
||||||
|
|
||||||
|
def properties_populated(self):
|
||||||
|
return list(self._inner.keys())
|
||||||
|
|
||||||
# Versioning API
|
# Versioning API
|
||||||
|
|
||||||
def new_version(self, **kwargs):
|
def new_version(self, **kwargs):
|
||||||
|
|
|
@ -60,7 +60,7 @@ class DictionaryKeyError(STIXError, ValueError):
|
||||||
self.reason = reason
|
self.reason = reason
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = "Invliad dictionary key {0.key}: ({0.reason})."
|
msg = "Invalid dictionary key {0.key}: ({0.reason})."
|
||||||
return msg.format(self)
|
return msg.format(self)
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,6 +90,20 @@ class UnmodifiablePropertyError(STIXError, ValueError):
|
||||||
return msg.format(", ".join(self.unchangable_properties))
|
return msg.format(", ".join(self.unchangable_properties))
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectConstraintError(STIXError, TypeError):
|
||||||
|
"""Violating some interproperty constraint of a STIX object type."""
|
||||||
|
|
||||||
|
def __init__(self, cls, fields):
|
||||||
|
super(ObjectConstraintError, self).__init__()
|
||||||
|
self.cls = cls
|
||||||
|
self.fields = sorted(list(fields))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
msg = "The field(s) for {0}: ({1}) are not consistent."
|
||||||
|
return msg.format(self.cls.__name__,
|
||||||
|
", ".join(x for x in self.fields))
|
||||||
|
|
||||||
|
|
||||||
class RevokeError(STIXError, ValueError):
|
class RevokeError(STIXError, ValueError):
|
||||||
"""Attempted to an operation on a revoked object"""
|
"""Attempted to an operation on a revoked object"""
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ and do not have a '_type' attribute.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .base import _STIXBase, Observable
|
from .base import _STIXBase, Observable
|
||||||
|
from .exceptions import ObjectConstraintError
|
||||||
from .properties import BinaryProperty, BooleanProperty, DictionaryProperty, \
|
from .properties import BinaryProperty, BooleanProperty, DictionaryProperty, \
|
||||||
EmbeddedObjectProperty, HashesProperty, HexProperty, IntegerProperty, \
|
EmbeddedObjectProperty, HashesProperty, HexProperty, IntegerProperty, \
|
||||||
ListProperty, ObjectReferenceProperty, Property, StringProperty, \
|
ListProperty, ObjectReferenceProperty, Property, StringProperty, \
|
||||||
|
@ -113,12 +114,24 @@ class File(Observable):
|
||||||
'accessed': TimestampProperty(),
|
'accessed': TimestampProperty(),
|
||||||
'parent_directory_ref': ObjectReferenceProperty(),
|
'parent_directory_ref': ObjectReferenceProperty(),
|
||||||
'is_encrypted': BooleanProperty(),
|
'is_encrypted': BooleanProperty(),
|
||||||
'encyption_algorithm': StringProperty(),
|
'encryption_algorithm': StringProperty(),
|
||||||
'decryption_key': StringProperty(),
|
'decryption_key': StringProperty(),
|
||||||
'contains_refs': ListProperty(ObjectReferenceProperty),
|
'contains_refs': ListProperty(ObjectReferenceProperty),
|
||||||
'content_ref': ObjectReferenceProperty(),
|
'content_ref': ObjectReferenceProperty(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _check_object_constaints(self):
|
||||||
|
super(File, self)._check_object_constaints()
|
||||||
|
illegal_properties = []
|
||||||
|
current_properties = self.properties_populated()
|
||||||
|
if not self.is_encrypted:
|
||||||
|
for p in ["encryption_algorithm", "decryption_key"]:
|
||||||
|
if p in current_properties:
|
||||||
|
illegal_properties.append(p)
|
||||||
|
if illegal_properties:
|
||||||
|
illegal_properties.append("is_encrypted")
|
||||||
|
raise ObjectConstraintError(self.__class__, illegal_properties)
|
||||||
|
|
||||||
|
|
||||||
class IPv4Address(Observable):
|
class IPv4Address(Observable):
|
||||||
_type = 'ipv4-addr'
|
_type = 'ipv4-addr'
|
||||||
|
@ -258,7 +271,7 @@ class WindowsRegistryKey(Observable):
|
||||||
_properties = {
|
_properties = {
|
||||||
'type': TypeProperty(_type),
|
'type': TypeProperty(_type),
|
||||||
'key': StringProperty(required=True),
|
'key': StringProperty(required=True),
|
||||||
'values': ListProperty(WindowsRegistryValueType),
|
'values': ListProperty(EmbeddedObjectProperty(type=WindowsRegistryValueType)),
|
||||||
# this is not the modified timestamps of the object itself
|
# this is not the modified timestamps of the object itself
|
||||||
'modified': TimestampProperty(),
|
'modified': TimestampProperty(),
|
||||||
'creator_user_ref': ObjectReferenceProperty(),
|
'creator_user_ref': ObjectReferenceProperty(),
|
||||||
|
|
|
@ -326,7 +326,7 @@ def test_file_example():
|
||||||
modified="2016-12-24T19:00:00Z",
|
modified="2016-12-24T19:00:00Z",
|
||||||
accessed="2016-12-21T20:00:00Z",
|
accessed="2016-12-21T20:00:00Z",
|
||||||
is_encrypted=True,
|
is_encrypted=True,
|
||||||
encyption_algorithm="AES128-CBC",
|
encryption_algorithm="AES128-CBC",
|
||||||
decryption_key="fred"
|
decryption_key="fred"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -339,19 +339,19 @@ def test_file_example():
|
||||||
assert f.modified == dt.datetime(2016, 12, 24, 19, 0, 0, tzinfo=pytz.utc)
|
assert f.modified == dt.datetime(2016, 12, 24, 19, 0, 0, tzinfo=pytz.utc)
|
||||||
assert f.accessed == dt.datetime(2016, 12, 21, 20, 0, 0, tzinfo=pytz.utc)
|
assert f.accessed == dt.datetime(2016, 12, 21, 20, 0, 0, tzinfo=pytz.utc)
|
||||||
assert f.is_encrypted
|
assert f.is_encrypted
|
||||||
assert f.encyption_algorithm == "AES128-CBC"
|
assert f.encryption_algorithm == "AES128-CBC"
|
||||||
assert f.decryption_key == "fred" # does the key have a format we can test for?
|
assert f.decryption_key == "fred" # does the key have a format we can test for?
|
||||||
|
|
||||||
|
|
||||||
# def test_file_example_encyption_error():
|
def test_file_example_encryption_error():
|
||||||
# f = stix2.File(name="qwerty.dll",
|
with pytest.raises(stix2.exceptions.ObjectConstraintError) as excinfo:
|
||||||
# is_encrypted=False,
|
stix2.File(name="qwerty.dll",
|
||||||
# encyption_algorithm="AES128-CBC"
|
is_encrypted=False,
|
||||||
# )
|
encryption_algorithm="AES128-CBC"
|
||||||
#
|
)
|
||||||
# assert f.name == "qwerty.dll"
|
|
||||||
# assert f.is_encrypted == False
|
assert excinfo.value.cls == stix2.File
|
||||||
# assert f.encyption_algorithm == "AES128-CBC"
|
assert excinfo.value.fields == ["encryption_algorithm", "is_encrypted"]
|
||||||
|
|
||||||
|
|
||||||
def test_ip4_address_example():
|
def test_ip4_address_example():
|
||||||
|
|
Loading…
Reference in New Issue