commit
41481139bf
|
@ -73,8 +73,7 @@ class _STIXBase(collections.Mapping):
|
|||
failed_dependency_pairs = []
|
||||
for p in list_of_properties:
|
||||
for dp in list_of_dependent_properties:
|
||||
if ((not hasattr(self, p) or (hasattr(self, p) and not self.__getattr__(p))) and
|
||||
hasattr(self, dp) and self.__getattr__(dp)):
|
||||
if not self.get(p) and self.get(dp):
|
||||
failed_dependency_pairs.append((p, dp))
|
||||
if failed_dependency_pairs:
|
||||
raise DependentPropertiesError(self.__class__, failed_dependency_pairs)
|
||||
|
@ -125,12 +124,10 @@ class _STIXBase(collections.Mapping):
|
|||
|
||||
# Handle attribute access just like key access
|
||||
def __getattr__(self, name):
|
||||
try:
|
||||
# Return attribute value.
|
||||
if name in self:
|
||||
return self.__getitem__(name)
|
||||
except KeyError:
|
||||
raise AttributeError("'%s' object has no attribute '%s'" %
|
||||
(self.__class__.__name__, name))
|
||||
raise AttributeError("'%s' object has no attribute '%s'" %
|
||||
(self.__class__.__name__, name))
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name != '_inner' and not name.startswith("_STIXBase__"):
|
||||
|
@ -160,7 +157,7 @@ class _STIXBase(collections.Mapping):
|
|||
|
||||
def new_version(self, **kwargs):
|
||||
unchangable_properties = []
|
||||
if hasattr(self, 'revoked') and self.revoked:
|
||||
if self.get("revoked"):
|
||||
raise RevokeError("new_version")
|
||||
new_obj_inner = copy.deepcopy(self._inner)
|
||||
properties_to_change = kwargs.keys()
|
||||
|
@ -180,7 +177,7 @@ class _STIXBase(collections.Mapping):
|
|||
return cls(**new_obj_inner)
|
||||
|
||||
def revoke(self):
|
||||
if hasattr(self, 'revoked') and self.revoked:
|
||||
if self.get("revoked"):
|
||||
raise RevokeError("revoke")
|
||||
return self.new_version(revoked=True)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ and do not have a '_type' attribute.
|
|||
"""
|
||||
|
||||
from .base import _Extension, _Observable, _STIXBase
|
||||
from .exceptions import AtLeastOnePropertyError
|
||||
from .exceptions import AtLeastOnePropertyError, DependentPropertiesError
|
||||
from .properties import (BinaryProperty, BooleanProperty, DictionaryProperty,
|
||||
EmbeddedObjectProperty, EnumProperty,
|
||||
ExtensionsProperty, FloatProperty, HashesProperty,
|
||||
|
@ -110,7 +110,9 @@ class EmailMessage(_Observable):
|
|||
def _check_object_constraints(self):
|
||||
super(EmailMessage, self)._check_object_constraints()
|
||||
self._check_properties_dependency(["is_multipart"], ["body_multipart"])
|
||||
# self._dependency(["is_multipart"], ["body"], [False])
|
||||
if self.get("is_multipart") is True and self.get("body"):
|
||||
# 'body' MAY only be used if is_multipart is false.
|
||||
raise DependentPropertiesError(self.__class__, [("is_multipart", "body")])
|
||||
|
||||
|
||||
class ArchiveExt(_Extension):
|
||||
|
@ -443,13 +445,13 @@ class Process(_Observable):
|
|||
super(Process, self)._check_object_constraints()
|
||||
try:
|
||||
self._check_at_least_one_property()
|
||||
if hasattr(self, 'extensions') and "windows-process-ext" in self.extensions:
|
||||
if "windows-process-ext" in self.get('extensions', {}):
|
||||
self.extensions["windows-process-ext"]._check_at_least_one_property()
|
||||
except AtLeastOnePropertyError as enclosing_exc:
|
||||
if not hasattr(self, 'extensions'):
|
||||
if 'extensions' not in self:
|
||||
raise enclosing_exc
|
||||
else:
|
||||
if "windows-process-ext" in self.extensions:
|
||||
if "windows-process-ext" in self.get('extensions', {}):
|
||||
self.extensions["windows-process-ext"]._check_at_least_one_property()
|
||||
|
||||
|
||||
|
|
|
@ -294,6 +294,31 @@ def test_parse_email_message(data):
|
|||
assert odata.body_multipart[0].content_disposition == "inline"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [
|
||||
"""
|
||||
{
|
||||
"type": "email-message",
|
||||
"from_ref": "0",
|
||||
"to_refs": ["1"],
|
||||
"is_multipart": true,
|
||||
"date": "1997-11-21T15:55:06.000Z",
|
||||
"subject": "Saying Hello",
|
||||
"body": "Cats are funny!"
|
||||
}
|
||||
"""
|
||||
])
|
||||
def test_parse_email_message_not_multipart(data):
|
||||
valid_refs = {
|
||||
"0": "email-addr",
|
||||
"1": "email-addr",
|
||||
}
|
||||
with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo:
|
||||
stix2.parse_observable(data, valid_refs)
|
||||
|
||||
assert excinfo.value.cls == stix2.EmailMessage
|
||||
assert excinfo.value.dependencies == [("is_multipart", "body")]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [
|
||||
""""0": {
|
||||
"type": "file",
|
||||
|
@ -913,6 +938,23 @@ def test_process_example_empty_with_extensions():
|
|||
assert excinfo.value.properties == sorted(properties_of_extension)
|
||||
|
||||
|
||||
def test_process_example_windows_process_ext():
|
||||
proc = stix2.Process(pid=314,
|
||||
name="foobar.exe",
|
||||
extensions={
|
||||
"windows-process-ext": {
|
||||
"aslr_enabled": True,
|
||||
"dep_enabled": True,
|
||||
"priority": "HIGH_PRIORITY_CLASS",
|
||||
"owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309"
|
||||
}
|
||||
})
|
||||
assert proc.extensions["windows-process-ext"].aslr_enabled
|
||||
assert proc.extensions["windows-process-ext"].dep_enabled
|
||||
assert proc.extensions["windows-process-ext"].priority == "HIGH_PRIORITY_CLASS"
|
||||
assert proc.extensions["windows-process-ext"].owner_sid == "S-1-5-21-186985262-1144665072-74031268-1309"
|
||||
|
||||
|
||||
def test_process_example_windows_process_ext_empty():
|
||||
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
|
||||
stix2.Process(pid=1221,
|
||||
|
|
Loading…
Reference in New Issue