mirror of https://github.com/MISP/PyMISP
chg: Add support for rapidjson, refactoring and code cleanup.
parent
898bc96ea6
commit
02659a5782
|
@ -5,7 +5,7 @@ import argparse
|
||||||
import json
|
import json
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from pymisp import MISPEncode, AbstractMISP
|
from pymisp import pymisp_json_default, AbstractMISP
|
||||||
from pymisp.tools import make_binary_objects
|
from pymisp.tools import make_binary_objects
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
@ -51,7 +51,8 @@ def make_objects(path):
|
||||||
to_return['objects'].append(fo)
|
to_return['objects'].append(fo)
|
||||||
if fo.ObjectReference:
|
if fo.ObjectReference:
|
||||||
to_return['references'] += fo.ObjectReference
|
to_return['references'] += fo.ObjectReference
|
||||||
return json.dumps(to_return, cls=MISPEncode)
|
return json.dumps(to_return, default=pymisp_json_default)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description='Extract indicators out of binaries and returns MISP objects.')
|
parser = argparse.ArgumentParser(description='Extract indicators out of binaries and returns MISP objects.')
|
||||||
|
|
|
@ -31,7 +31,7 @@ try:
|
||||||
warning_2020()
|
warning_2020()
|
||||||
from .exceptions import PyMISPError, NewEventError, NewAttributeError, MissingDependency, NoURL, NoKey, InvalidMISPObject, UnknownMISPObjectTemplate, PyMISPInvalidFormat, MISPServerError, PyMISPNotImplementedYet, PyMISPUnexpectedResponse, PyMISPEmptyResponse # noqa
|
from .exceptions import PyMISPError, NewEventError, NewAttributeError, MissingDependency, NoURL, NoKey, InvalidMISPObject, UnknownMISPObjectTemplate, PyMISPInvalidFormat, MISPServerError, PyMISPNotImplementedYet, PyMISPUnexpectedResponse, PyMISPEmptyResponse # noqa
|
||||||
from .api import PyMISP # noqa
|
from .api import PyMISP # noqa
|
||||||
from .abstract import AbstractMISP, MISPEncode, MISPTag, Distribution, ThreatLevel, Analysis # noqa
|
from .abstract import AbstractMISP, MISPEncode, pymisp_json_default, MISPTag, Distribution, ThreatLevel, Analysis # noqa
|
||||||
from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPUser, MISPOrganisation, MISPSighting, MISPLog, MISPShadowAttribute, MISPWarninglist, MISPTaxonomy, MISPNoticelist, MISPObjectTemplate, MISPSharingGroup, MISPRole, MISPServer, MISPFeed, MISPEventDelegation # noqa
|
from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPUser, MISPOrganisation, MISPSighting, MISPLog, MISPShadowAttribute, MISPWarninglist, MISPTaxonomy, MISPNoticelist, MISPObjectTemplate, MISPSharingGroup, MISPRole, MISPServer, MISPFeed, MISPEventDelegation # noqa
|
||||||
from .tools import AbstractMISPObjectGenerator # noqa
|
from .tools import AbstractMISPObjectGenerator # noqa
|
||||||
from .tools import Neo4j # noqa
|
from .tools import Neo4j # noqa
|
||||||
|
|
|
@ -3,8 +3,23 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
|
||||||
|
from deprecated import deprecated
|
||||||
from json import JSONEncoder
|
from json import JSONEncoder
|
||||||
|
|
||||||
|
try:
|
||||||
|
from rapidjson import load
|
||||||
|
from rapidjson import loads
|
||||||
|
from rapidjson import dumps
|
||||||
|
import rapidjson
|
||||||
|
HAS_RAPIDJSON = True
|
||||||
|
except ImportError:
|
||||||
|
from json import load
|
||||||
|
from json import loads
|
||||||
|
from json import dumps
|
||||||
|
import json
|
||||||
|
HAS_RAPIDJSON = False
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
@ -13,7 +28,6 @@ from .exceptions import PyMISPInvalidFormat
|
||||||
|
|
||||||
logger = logging.getLogger('pymisp')
|
logger = logging.getLogger('pymisp')
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info < (3, 0):
|
if sys.version_info < (3, 0):
|
||||||
from collections import MutableMapping
|
from collections import MutableMapping
|
||||||
import os
|
import os
|
||||||
|
@ -22,7 +36,7 @@ if sys.version_info < (3, 0):
|
||||||
resources_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data')
|
resources_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data')
|
||||||
misp_objects_path = os.path.join(resources_path, 'misp-objects', 'objects')
|
misp_objects_path = os.path.join(resources_path, 'misp-objects', 'objects')
|
||||||
with open(os.path.join(resources_path, 'describeTypes.json'), 'r') as f:
|
with open(os.path.join(resources_path, 'describeTypes.json'), 'r') as f:
|
||||||
describe_types = json.load(f)['result']
|
describe_types = load(f)['result']
|
||||||
|
|
||||||
# This is required because Python 2 is a pain.
|
# This is required because Python 2 is a pain.
|
||||||
from datetime import tzinfo, timedelta
|
from datetime import tzinfo, timedelta
|
||||||
|
@ -55,9 +69,9 @@ if sys.version_info < (3, 0):
|
||||||
return data
|
return data
|
||||||
with open(path, 'rb') as f:
|
with open(path, 'rb') as f:
|
||||||
if OLD_PY3:
|
if OLD_PY3:
|
||||||
data = json.loads(f.read().decode())
|
data = loads(f.read().decode())
|
||||||
else:
|
else:
|
||||||
data = json.load(f)
|
data = load(f)
|
||||||
file_cache[path] = (mtime, data)
|
file_cache[path] = (mtime, data)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -69,7 +83,7 @@ else:
|
||||||
resources_path = Path(__file__).parent / 'data'
|
resources_path = Path(__file__).parent / 'data'
|
||||||
misp_objects_path = resources_path / 'misp-objects' / 'objects'
|
misp_objects_path = resources_path / 'misp-objects' / 'objects'
|
||||||
with (resources_path / 'describeTypes.json').open('r') as f:
|
with (resources_path / 'describeTypes.json').open('r') as f:
|
||||||
describe_types = json.load(f)['result']
|
describe_types = load(f)['result']
|
||||||
|
|
||||||
class MISPFileCache(object):
|
class MISPFileCache(object):
|
||||||
# cache up to 150 JSON structures in class attribute
|
# cache up to 150 JSON structures in class attribute
|
||||||
|
@ -78,7 +92,7 @@ else:
|
||||||
@lru_cache(maxsize=150)
|
@lru_cache(maxsize=150)
|
||||||
def _load_json(path):
|
def _load_json(path):
|
||||||
with path.open('rb') as f:
|
with path.open('rb') as f:
|
||||||
data = json.load(f)
|
data = load(f)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
if (3, 0) <= sys.version_info < (3, 6):
|
if (3, 0) <= sys.version_info < (3, 6):
|
||||||
|
@ -117,8 +131,8 @@ def _int_to_str(d):
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
@deprecated(reason=" Use method default=pymisp_json_default instead of cls=MISPEncode", version='2.4.117', action='default')
|
||||||
class MISPEncode(JSONEncoder):
|
class MISPEncode(JSONEncoder):
|
||||||
|
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
if isinstance(obj, AbstractMISP):
|
if isinstance(obj, AbstractMISP):
|
||||||
return obj.jsonable()
|
return obj.jsonable()
|
||||||
|
@ -129,6 +143,26 @@ class MISPEncode(JSONEncoder):
|
||||||
return JSONEncoder.default(self, obj)
|
return JSONEncoder.default(self, obj)
|
||||||
|
|
||||||
|
|
||||||
|
if HAS_RAPIDJSON:
|
||||||
|
def pymisp_json_default(obj):
|
||||||
|
if isinstance(obj, AbstractMISP):
|
||||||
|
return obj.jsonable()
|
||||||
|
elif isinstance(obj, (datetime.datetime, datetime.date)):
|
||||||
|
return obj.isoformat()
|
||||||
|
elif isinstance(obj, Enum):
|
||||||
|
return obj.value
|
||||||
|
return rapidjson.default(obj)
|
||||||
|
else:
|
||||||
|
def pymisp_json_default(obj):
|
||||||
|
if isinstance(obj, AbstractMISP):
|
||||||
|
return obj.jsonable()
|
||||||
|
elif isinstance(obj, (datetime.datetime, datetime.date)):
|
||||||
|
return obj.isoformat()
|
||||||
|
elif isinstance(obj, Enum):
|
||||||
|
return obj.value
|
||||||
|
return json.default(obj)
|
||||||
|
|
||||||
|
|
||||||
class AbstractMISP(MutableMapping, MISPFileCache):
|
class AbstractMISP(MutableMapping, MISPFileCache):
|
||||||
__resources_path = resources_path
|
__resources_path = resources_path
|
||||||
__misp_objects_path = misp_objects_path
|
__misp_objects_path = misp_objects_path
|
||||||
|
@ -179,13 +213,6 @@ class AbstractMISP(MutableMapping, MISPFileCache):
|
||||||
misp_objects_path = Path(misp_objects_path)
|
misp_objects_path = Path(misp_objects_path)
|
||||||
self.__misp_objects_path = misp_objects_path
|
self.__misp_objects_path = misp_objects_path
|
||||||
|
|
||||||
@property
|
|
||||||
def properties(self):
|
|
||||||
"""All the class public properties that will be dumped in the dictionary, and the JSON export.
|
|
||||||
Note: all the properties starting with a `_` (private), or listed in __not_jsonable will be skipped.
|
|
||||||
"""
|
|
||||||
return [k for k in vars(self).keys() if not (k[0] == '_' or k in self.__not_jsonable)]
|
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
"""Loading all the parameters as class properties, if they aren't `None`.
|
"""Loading all the parameters as class properties, if they aren't `None`.
|
||||||
This method aims to be called when all the properties requiring a special
|
This method aims to be called when all the properties requiring a special
|
||||||
|
@ -209,21 +236,21 @@ class AbstractMISP(MutableMapping, MISPFileCache):
|
||||||
|
|
||||||
def from_json(self, json_string):
|
def from_json(self, json_string):
|
||||||
"""Load a JSON string"""
|
"""Load a JSON string"""
|
||||||
self.from_dict(**json.loads(json_string))
|
self.from_dict(**loads(json_string))
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
"""Dump the lass to a dictionary.
|
"""Dump the class to a dictionary.
|
||||||
This method automatically removes the timestamp recursively in every object
|
This method automatically removes the timestamp recursively in every object
|
||||||
that has been edited is order to let MISP update the event accordingly."""
|
that has been edited is order to let MISP update the event accordingly."""
|
||||||
|
is_edited = self.edited
|
||||||
to_return = {}
|
to_return = {}
|
||||||
for attribute in self.properties:
|
for attribute, val in self.items():
|
||||||
val = getattr(self, attribute, None)
|
|
||||||
if val is None:
|
if val is None:
|
||||||
continue
|
continue
|
||||||
elif isinstance(val, list) and len(val) == 0:
|
elif isinstance(val, list) and len(val) == 0:
|
||||||
continue
|
continue
|
||||||
if attribute == 'timestamp':
|
if attribute == 'timestamp':
|
||||||
if not self.__force_timestamps and self.edited:
|
if not self.__force_timestamps and is_edited:
|
||||||
# In order to be accepted by MISP, the timestamp of an object
|
# In order to be accepted by MISP, the timestamp of an object
|
||||||
# needs to be either newer, or None.
|
# needs to be either newer, or None.
|
||||||
# If the current object is marked as edited, the easiest is to
|
# If the current object is marked as edited, the easiest is to
|
||||||
|
@ -239,13 +266,15 @@ class AbstractMISP(MutableMapping, MISPFileCache):
|
||||||
"""This method is used by the JSON encoder"""
|
"""This method is used by the JSON encoder"""
|
||||||
return self.to_dict()
|
return self.to_dict()
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self, sort_keys=False, indent=None):
|
||||||
"""Dump recursively any class of type MISPAbstract to a json string"""
|
"""Dump recursively any class of type MISPAbstract to a json string"""
|
||||||
return json.dumps(self, cls=MISPEncode, sort_keys=True, indent=2)
|
return dumps(self, default=pymisp_json_default, sort_keys=sort_keys, indent=indent)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
try:
|
try:
|
||||||
return getattr(self, key)
|
if key[0] != '_' and key not in self.__not_jsonable:
|
||||||
|
return self.__dict__[key]
|
||||||
|
raise KeyError
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Expected by pop and other dict-related methods
|
# Expected by pop and other dict-related methods
|
||||||
raise KeyError
|
raise KeyError
|
||||||
|
@ -257,10 +286,10 @@ class AbstractMISP(MutableMapping, MISPFileCache):
|
||||||
delattr(self, key)
|
delattr(self, key)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self.to_dict())
|
return iter({k: v for k, v in self.__dict__.items() if not (k[0] == '_' or k in self.__not_jsonable)})
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.to_dict())
|
return len([k for k in self.__dict__.keys() if not (k[0] == '_' or k in self.__not_jsonable)])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def edited(self):
|
def edited(self):
|
||||||
|
@ -268,15 +297,14 @@ class AbstractMISP(MutableMapping, MISPFileCache):
|
||||||
to the parent objects"""
|
to the parent objects"""
|
||||||
if self.__edited:
|
if self.__edited:
|
||||||
return self.__edited
|
return self.__edited
|
||||||
for p in self.properties:
|
for p, val in self.items():
|
||||||
if self.__edited:
|
|
||||||
break
|
|
||||||
val = getattr(self, p)
|
|
||||||
if isinstance(val, AbstractMISP) and val.edited:
|
if isinstance(val, AbstractMISP) and val.edited:
|
||||||
self.__edited = True
|
self.__edited = True
|
||||||
|
break
|
||||||
elif isinstance(val, list) and all(isinstance(a, AbstractMISP) for a in val):
|
elif isinstance(val, list) and all(isinstance(a, AbstractMISP) for a in val):
|
||||||
if any(a.edited for a in val):
|
if any(a.edited for a in val):
|
||||||
self.__edited = True
|
self.__edited = True
|
||||||
|
break
|
||||||
return self.__edited
|
return self.__edited
|
||||||
|
|
||||||
@edited.setter
|
@edited.setter
|
||||||
|
@ -288,9 +316,10 @@ class AbstractMISP(MutableMapping, MISPFileCache):
|
||||||
raise Exception('edited can only be True or False')
|
raise Exception('edited can only be True or False')
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
if name != '_AbstractMISP__edited':
|
if name[0] != '_' and not self.__edited and name in self.keys():
|
||||||
if not self.__edited and name in self.properties:
|
# The private members don't matter
|
||||||
self.__edited = True
|
# If we already have a key with that name, we're modifying it.
|
||||||
|
self.__edited = True
|
||||||
super(AbstractMISP, self).__setattr__(name, value)
|
super(AbstractMISP, self).__setattr__(name, value)
|
||||||
|
|
||||||
def _datetime_to_timestamp(self, d):
|
def _datetime_to_timestamp(self, d):
|
||||||
|
|
|
@ -19,7 +19,7 @@ from deprecated import deprecated
|
||||||
from . import __version__, warning_2020
|
from . import __version__, warning_2020
|
||||||
from .exceptions import PyMISPError, SearchError, NoURL, NoKey, PyMISPEmptyResponse
|
from .exceptions import PyMISPError, SearchError, NoURL, NoKey, PyMISPEmptyResponse
|
||||||
from .mispevent import MISPEvent, MISPAttribute, MISPUser, MISPOrganisation, MISPSighting, MISPFeed, MISPObject, MISPSharingGroup
|
from .mispevent import MISPEvent, MISPAttribute, MISPUser, MISPOrganisation, MISPSighting, MISPFeed, MISPObject, MISPSharingGroup
|
||||||
from .abstract import AbstractMISP, MISPEncode, MISPFileCache, describe_types
|
from .abstract import AbstractMISP, pymisp_json_default, MISPFileCache, describe_types
|
||||||
|
|
||||||
logger = logging.getLogger('pymisp')
|
logger = logging.getLogger('pymisp')
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ class PyMISP(MISPFileCache): # pragma: no cover
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
# Remove None values.
|
# Remove None values.
|
||||||
data = {k: v for k, v in data.items() if v is not None}
|
data = {k: v for k, v in data.items() if v is not None}
|
||||||
data = json.dumps(data, cls=MISPEncode)
|
data = json.dumps(data, default=pymisp_json_default)
|
||||||
req = requests.Request(request_type, url, data=data)
|
req = requests.Request(request_type, url, data=data)
|
||||||
if self.asynch and background_callback is not None:
|
if self.asynch and background_callback is not None:
|
||||||
local_session = FuturesSession
|
local_session = FuturesSession
|
||||||
|
@ -604,7 +604,7 @@ class PyMISP(MISPFileCache): # pragma: no cover
|
||||||
else:
|
else:
|
||||||
data = attributes.to_json()
|
data = attributes.to_json()
|
||||||
# _prepare_request(...) returns a requests.Response Object
|
# _prepare_request(...) returns a requests.Response Object
|
||||||
resp = self._prepare_request('POST', url, json.dumps(data, cls=MISPEncode))
|
resp = self._prepare_request('POST', url, json.dumps(data, default=pymisp_json_default))
|
||||||
try:
|
try:
|
||||||
responses.append(resp.json())
|
responses.append(resp.json())
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -1058,7 +1058,7 @@ class PyMISP(MISPFileCache): # pragma: no cover
|
||||||
url = urljoin(self.root_url, 'shadow_attributes/{}/{}'.format(path, id))
|
url = urljoin(self.root_url, 'shadow_attributes/{}/{}'.format(path, id))
|
||||||
if path in ['add', 'edit']:
|
if path in ['add', 'edit']:
|
||||||
query = {'request': {'ShadowAttribute': attribute}}
|
query = {'request': {'ShadowAttribute': attribute}}
|
||||||
response = self._prepare_request('POST', url, json.dumps(query, cls=MISPEncode))
|
response = self._prepare_request('POST', url, json.dumps(query, default=pymisp_json_default))
|
||||||
elif path == 'view':
|
elif path == 'view':
|
||||||
response = self._prepare_request('GET', url)
|
response = self._prepare_request('GET', url)
|
||||||
else: # accept or discard
|
else: # accept or discard
|
||||||
|
|
|
@ -19,7 +19,7 @@ from . import __version__
|
||||||
from .exceptions import MISPServerError, PyMISPUnexpectedResponse, PyMISPNotImplementedYet, PyMISPError, NoURL, NoKey
|
from .exceptions import MISPServerError, PyMISPUnexpectedResponse, PyMISPNotImplementedYet, PyMISPError, NoURL, NoKey
|
||||||
from .api import everything_broken, PyMISP
|
from .api import everything_broken, PyMISP
|
||||||
from .mispevent import MISPEvent, MISPAttribute, MISPSighting, MISPLog, MISPObject, MISPUser, MISPOrganisation, MISPShadowAttribute, MISPWarninglist, MISPTaxonomy, MISPGalaxy, MISPNoticelist, MISPObjectReference, MISPObjectTemplate, MISPSharingGroup, MISPRole, MISPServer, MISPFeed, MISPEventDelegation, MISPCommunity
|
from .mispevent import MISPEvent, MISPAttribute, MISPSighting, MISPLog, MISPObject, MISPUser, MISPOrganisation, MISPShadowAttribute, MISPWarninglist, MISPTaxonomy, MISPGalaxy, MISPNoticelist, MISPObjectReference, MISPObjectTemplate, MISPSharingGroup, MISPRole, MISPServer, MISPFeed, MISPEventDelegation, MISPCommunity
|
||||||
from .abstract import MISPEncode, MISPTag, AbstractMISP, describe_types
|
from .abstract import pymisp_json_default, MISPTag, AbstractMISP, describe_types
|
||||||
|
|
||||||
SearchType = TypeVar('SearchType', str, int)
|
SearchType = TypeVar('SearchType', str, int)
|
||||||
# str: string to search / list: values to search (OR) / dict: {'OR': [list], 'NOT': [list], 'AND': [list]}
|
# str: string to search / list: values to search (OR) / dict: {'OR': [list], 'NOT': [list], 'AND': [list]}
|
||||||
|
@ -2109,7 +2109,7 @@ class ExpandedPyMISP(PyMISP):
|
||||||
if isinstance(data, dict): # Else, we can directly json encode.
|
if isinstance(data, dict): # Else, we can directly json encode.
|
||||||
# Remove None values.
|
# Remove None values.
|
||||||
data = {k: v for k, v in data.items() if v is not None}
|
data = {k: v for k, v in data.items() if v is not None}
|
||||||
data = json.dumps(data, cls=MISPEncode)
|
data = json.dumps(data, default=pymisp_json_default)
|
||||||
|
|
||||||
if kw_params:
|
if kw_params:
|
||||||
# CakePHP params in URL
|
# CakePHP params in URL
|
||||||
|
|
|
@ -198,8 +198,8 @@ class MISPAttribute(AbstractMISP):
|
||||||
return misp_sighting
|
return misp_sighting
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Attribute'):
|
if 'Attribute' in kwargs:
|
||||||
kwargs = kwargs.get('Attribute')
|
kwargs = kwargs['Attribute']
|
||||||
if kwargs.get('type') and kwargs.get('category'):
|
if kwargs.get('type') and kwargs.get('category'):
|
||||||
if kwargs['type'] not in self.__category_type_mapping[kwargs['category']]:
|
if kwargs['type'] not in self.__category_type_mapping[kwargs['category']]:
|
||||||
if self.__strict:
|
if self.__strict:
|
||||||
|
@ -272,14 +272,11 @@ class MISPAttribute(AbstractMISP):
|
||||||
raise NewAttributeError('If the distribution is set to sharing group, a sharing group ID is required (cannot be {}).'.format(self.sharing_group_id))
|
raise NewAttributeError('If the distribution is set to sharing group, a sharing group ID is required (cannot be {}).'.format(self.sharing_group_id))
|
||||||
|
|
||||||
if kwargs.get('Tag'):
|
if kwargs.get('Tag'):
|
||||||
for tag in kwargs.pop('Tag'):
|
[self.add_tag(tag) for tag in kwargs.pop('Tag')]
|
||||||
self.add_tag(tag)
|
|
||||||
if kwargs.get('Sighting'):
|
if kwargs.get('Sighting'):
|
||||||
for sighting in kwargs.pop('Sighting'):
|
[self.add_sighting(sighting) for sighting in kwargs.pop('Sighting')]
|
||||||
self.add_sighting(sighting)
|
|
||||||
if kwargs.get('ShadowAttribute'):
|
if kwargs.get('ShadowAttribute'):
|
||||||
for s_attr in kwargs.pop('ShadowAttribute'):
|
[self.add_shadow_attribute(s_attr) for s_attr in kwargs.pop('ShadowAttribute')]
|
||||||
self.add_shadow_attribute(s_attr)
|
|
||||||
|
|
||||||
# If the user wants to disable correlation, let them. Defaults to False.
|
# If the user wants to disable correlation, let them. Defaults to False.
|
||||||
self.disable_correlation = kwargs.pop("disable_correlation", False)
|
self.disable_correlation = kwargs.pop("disable_correlation", False)
|
||||||
|
@ -535,8 +532,8 @@ class MISPEvent(AbstractMISP):
|
||||||
raise NewEventError('Invalid format for the date: {} - {}'.format(date, type(date)))
|
raise NewEventError('Invalid format for the date: {} - {}'.format(date, type(date)))
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Event'):
|
if 'Event' in kwargs:
|
||||||
kwargs = kwargs.get('Event')
|
kwargs = kwargs['Event']
|
||||||
# Required value
|
# Required value
|
||||||
self.info = kwargs.pop('info', None)
|
self.info = kwargs.pop('info', None)
|
||||||
if self.info is None:
|
if self.info is None:
|
||||||
|
@ -568,8 +565,7 @@ class MISPEvent(AbstractMISP):
|
||||||
if kwargs.get('date'):
|
if kwargs.get('date'):
|
||||||
self.set_date(kwargs.pop('date'))
|
self.set_date(kwargs.pop('date'))
|
||||||
if kwargs.get('Attribute'):
|
if kwargs.get('Attribute'):
|
||||||
for a in kwargs.pop('Attribute'):
|
[self.add_attribute(**a) for a in kwargs.pop('Attribute')]
|
||||||
self.add_attribute(**a)
|
|
||||||
|
|
||||||
# All other keys
|
# All other keys
|
||||||
if kwargs.get('id'):
|
if kwargs.get('id'):
|
||||||
|
@ -596,11 +592,9 @@ class MISPEvent(AbstractMISP):
|
||||||
sub_event.load(rel_event)
|
sub_event.load(rel_event)
|
||||||
self.RelatedEvent.append({'Event': sub_event})
|
self.RelatedEvent.append({'Event': sub_event})
|
||||||
if kwargs.get('Tag'):
|
if kwargs.get('Tag'):
|
||||||
for tag in kwargs.pop('Tag'):
|
[self.add_tag(tag) for tag in kwargs.pop('Tag')]
|
||||||
self.add_tag(tag)
|
|
||||||
if kwargs.get('Object'):
|
if kwargs.get('Object'):
|
||||||
for obj in kwargs.pop('Object'):
|
[self.add_object(obj) for obj in kwargs.pop('Object')]
|
||||||
self.add_object(obj)
|
|
||||||
if kwargs.get('Org'):
|
if kwargs.get('Org'):
|
||||||
self.Org = MISPOrganisation()
|
self.Org = MISPOrganisation()
|
||||||
self.Org.from_dict(**kwargs.pop('Org'))
|
self.Org.from_dict(**kwargs.pop('Org'))
|
||||||
|
@ -860,8 +854,8 @@ class MISPObjectReference(AbstractMISP):
|
||||||
super(MISPObjectReference, self).__init__()
|
super(MISPObjectReference, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('ObjectReference'):
|
if 'ObjectReference' in kwargs:
|
||||||
kwargs = kwargs.get('ObjectReference')
|
kwargs = kwargs['ObjectReference']
|
||||||
super(MISPObjectReference, self).from_dict(**kwargs)
|
super(MISPObjectReference, self).from_dict(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -876,8 +870,8 @@ class MISPObjectTemplate(AbstractMISP):
|
||||||
super(MISPObjectTemplate, self).__init__()
|
super(MISPObjectTemplate, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('ObjectTemplate'):
|
if 'ObjectTemplate' in kwargs:
|
||||||
kwargs = kwargs.get('ObjectTemplate')
|
kwargs = kwargs['ObjectTemplate']
|
||||||
super(MISPObjectTemplate, self).from_dict(**kwargs)
|
super(MISPObjectTemplate, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -887,8 +881,8 @@ class MISPUser(AbstractMISP):
|
||||||
super(MISPUser, self).__init__()
|
super(MISPUser, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('User'):
|
if 'User' in kwargs:
|
||||||
kwargs = kwargs.get('User')
|
kwargs = kwargs['User']
|
||||||
super(MISPUser, self).from_dict(**kwargs)
|
super(MISPUser, self).from_dict(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -903,8 +897,8 @@ class MISPOrganisation(AbstractMISP):
|
||||||
super(MISPOrganisation, self).__init__()
|
super(MISPOrganisation, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Organisation'):
|
if 'Organisation' in kwargs:
|
||||||
kwargs = kwargs.get('Organisation')
|
kwargs = kwargs['Organisation']
|
||||||
super(MISPOrganisation, self).from_dict(**kwargs)
|
super(MISPOrganisation, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -914,8 +908,8 @@ class MISPFeed(AbstractMISP):
|
||||||
super(MISPFeed, self).__init__()
|
super(MISPFeed, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Feed'):
|
if 'Feed' in kwargs:
|
||||||
kwargs = kwargs.get('Feed')
|
kwargs = kwargs['Feed']
|
||||||
super(MISPFeed, self).from_dict(**kwargs)
|
super(MISPFeed, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -925,8 +919,8 @@ class MISPWarninglist(AbstractMISP):
|
||||||
super(MISPWarninglist, self).__init__()
|
super(MISPWarninglist, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Warninglist'):
|
if 'Warninglist' in kwargs:
|
||||||
kwargs = kwargs.get('Warninglist')
|
kwargs = kwargs['Warninglist']
|
||||||
super(MISPWarninglist, self).from_dict(**kwargs)
|
super(MISPWarninglist, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -936,8 +930,8 @@ class MISPTaxonomy(AbstractMISP):
|
||||||
super(MISPTaxonomy, self).__init__()
|
super(MISPTaxonomy, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Taxonomy'):
|
if 'Taxonomy' in kwargs:
|
||||||
kwargs = kwargs.get('Taxonomy')
|
kwargs = kwargs['Taxonomy']
|
||||||
super(MISPTaxonomy, self).from_dict(**kwargs)
|
super(MISPTaxonomy, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -947,8 +941,8 @@ class MISPGalaxy(AbstractMISP):
|
||||||
super(MISPGalaxy, self).__init__()
|
super(MISPGalaxy, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Galaxy'):
|
if 'Galaxy' in kwargs:
|
||||||
kwargs = kwargs.get('Galaxy')
|
kwargs = kwargs['Galaxy']
|
||||||
super(MISPGalaxy, self).from_dict(**kwargs)
|
super(MISPGalaxy, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -958,8 +952,8 @@ class MISPNoticelist(AbstractMISP):
|
||||||
super(MISPNoticelist, self).__init__()
|
super(MISPNoticelist, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Noticelist'):
|
if 'Noticelist' in kwargs:
|
||||||
kwargs = kwargs.get('Noticelist')
|
kwargs = kwargs['Noticelist']
|
||||||
super(MISPNoticelist, self).from_dict(**kwargs)
|
super(MISPNoticelist, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -969,8 +963,8 @@ class MISPRole(AbstractMISP):
|
||||||
super(MISPRole, self).__init__()
|
super(MISPRole, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Role'):
|
if 'Role' in kwargs:
|
||||||
kwargs = kwargs.get('Role')
|
kwargs = kwargs['Role']
|
||||||
super(MISPRole, self).from_dict(**kwargs)
|
super(MISPRole, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -980,8 +974,8 @@ class MISPServer(AbstractMISP):
|
||||||
super(MISPServer, self).__init__()
|
super(MISPServer, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Server'):
|
if 'Server' in kwargs:
|
||||||
kwargs = kwargs.get('Server')
|
kwargs = kwargs['Server']
|
||||||
super(MISPServer, self).from_dict(**kwargs)
|
super(MISPServer, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -991,8 +985,8 @@ class MISPSharingGroup(AbstractMISP):
|
||||||
super(MISPSharingGroup, self).__init__()
|
super(MISPSharingGroup, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('SharingGroup'):
|
if 'SharingGroup' in kwargs:
|
||||||
kwargs = kwargs.get('SharingGroup')
|
kwargs = kwargs['SharingGroup']
|
||||||
super(MISPSharingGroup, self).from_dict(**kwargs)
|
super(MISPSharingGroup, self).from_dict(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1002,8 +996,8 @@ class MISPLog(AbstractMISP):
|
||||||
super(MISPLog, self).__init__()
|
super(MISPLog, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Log'):
|
if 'Log' in kwargs:
|
||||||
kwargs = kwargs.get('Log')
|
kwargs = kwargs['Log']
|
||||||
super(MISPLog, self).from_dict(**kwargs)
|
super(MISPLog, self).from_dict(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -1016,8 +1010,8 @@ class MISPEventDelegation(AbstractMISP):
|
||||||
super(MISPEventDelegation, self).__init__()
|
super(MISPEventDelegation, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('EventDelegation'):
|
if 'EventDelegation' in kwargs:
|
||||||
kwargs = kwargs.get('EventDelegation')
|
kwargs = kwargs['EventDelegation']
|
||||||
super(MISPEventDelegation, self).from_dict(**kwargs)
|
super(MISPEventDelegation, self).from_dict(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -1039,8 +1033,8 @@ class MISPSighting(AbstractMISP):
|
||||||
:type: Type of the sighting
|
:type: Type of the sighting
|
||||||
:timestamp: Timestamp associated to the sighting
|
:timestamp: Timestamp associated to the sighting
|
||||||
"""
|
"""
|
||||||
if kwargs.get('Sighting'):
|
if 'Sighting' in kwargs:
|
||||||
kwargs = kwargs.get('Sighting')
|
kwargs = kwargs['Sighting']
|
||||||
super(MISPSighting, self).from_dict(**kwargs)
|
super(MISPSighting, self).from_dict(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -1062,6 +1056,8 @@ class MISPObjectAttribute(MISPAttribute):
|
||||||
def from_dict(self, object_relation, value, **kwargs):
|
def from_dict(self, object_relation, value, **kwargs):
|
||||||
self.object_relation = object_relation
|
self.object_relation = object_relation
|
||||||
self.value = value
|
self.value = value
|
||||||
|
if 'Attribute' in kwargs:
|
||||||
|
kwargs = kwargs['Attribute']
|
||||||
# Initialize the new MISPAttribute
|
# Initialize the new MISPAttribute
|
||||||
# Get the misp attribute type from the definition
|
# Get the misp attribute type from the definition
|
||||||
self.type = kwargs.pop('type', None)
|
self.type = kwargs.pop('type', None)
|
||||||
|
@ -1078,7 +1074,10 @@ class MISPObjectAttribute(MISPAttribute):
|
||||||
self.to_ids = self._definition.get('to_ids')
|
self.to_ids = self._definition.get('to_ids')
|
||||||
if not self.type:
|
if not self.type:
|
||||||
raise NewAttributeError("The type of the attribute is required. Is the object template missing?")
|
raise NewAttributeError("The type of the attribute is required. Is the object template missing?")
|
||||||
super(MISPObjectAttribute, self).from_dict(**dict(self, **kwargs))
|
if sys.version_info < (3, 5):
|
||||||
|
super(MISPObjectAttribute, self).from_dict(**dict(self, **kwargs))
|
||||||
|
else:
|
||||||
|
super(MISPObjectAttribute, self).from_dict(**{**self, **kwargs})
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if hasattr(self, 'value'):
|
if hasattr(self, 'value'):
|
||||||
|
@ -1092,8 +1091,8 @@ class MISPShadowAttribute(AbstractMISP):
|
||||||
super(MISPShadowAttribute, self).__init__()
|
super(MISPShadowAttribute, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('ShadowAttribute'):
|
if 'ShadowAttribute' in kwargs:
|
||||||
kwargs = kwargs.get('ShadowAttribute')
|
kwargs = kwargs['ShadowAttribute']
|
||||||
super(MISPShadowAttribute, self).from_dict(**kwargs)
|
super(MISPShadowAttribute, self).from_dict(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -1108,8 +1107,8 @@ class MISPCommunity(AbstractMISP):
|
||||||
super(MISPCommunity, self).__init__()
|
super(MISPCommunity, self).__init__()
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Community'):
|
if 'Community' in kwargs:
|
||||||
kwargs = kwargs.get('Community')
|
kwargs = kwargs['Community']
|
||||||
super(MISPCommunity, self).from_dict(**kwargs)
|
super(MISPCommunity, self).from_dict(**kwargs)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -1231,8 +1230,8 @@ class MISPObject(AbstractMISP):
|
||||||
raise PyMISPError('All the attributes have to be of type MISPObjectReference.')
|
raise PyMISPError('All the attributes have to be of type MISPObjectReference.')
|
||||||
|
|
||||||
def from_dict(self, **kwargs):
|
def from_dict(self, **kwargs):
|
||||||
if kwargs.get('Object'):
|
if 'Object' in kwargs:
|
||||||
kwargs = kwargs.get('Object')
|
kwargs = kwargs['Object']
|
||||||
if self._known_template:
|
if self._known_template:
|
||||||
if kwargs.get('template_uuid') and kwargs['template_uuid'] != self.template_uuid:
|
if kwargs.get('template_uuid') and kwargs['template_uuid'] != self.template_uuid:
|
||||||
if self._strict:
|
if self._strict:
|
||||||
|
@ -1260,11 +1259,9 @@ class MISPObject(AbstractMISP):
|
||||||
else:
|
else:
|
||||||
self.timestamp = datetime.datetime.fromtimestamp(int(ts), UTC())
|
self.timestamp = datetime.datetime.fromtimestamp(int(ts), UTC())
|
||||||
if kwargs.get('Attribute'):
|
if kwargs.get('Attribute'):
|
||||||
for a in kwargs.pop('Attribute'):
|
[self.add_attribute(**a) for a in kwargs.pop('Attribute')]
|
||||||
self.add_attribute(**a)
|
|
||||||
if kwargs.get('ObjectReference'):
|
if kwargs.get('ObjectReference'):
|
||||||
for r in kwargs.pop('ObjectReference'):
|
[self.add_reference(**r) for r in kwargs.pop('ObjectReference')]
|
||||||
self.add_reference(**r)
|
|
||||||
|
|
||||||
# Not supported yet - https://github.com/MISP/PyMISP/issues/168
|
# Not supported yet - https://github.com/MISP/PyMISP/issues/168
|
||||||
# if kwargs.get('Tag'):
|
# if kwargs.get('Tag'):
|
||||||
|
@ -1323,7 +1320,10 @@ class MISPObject(AbstractMISP):
|
||||||
else:
|
else:
|
||||||
attribute = MISPObjectAttribute({})
|
attribute = MISPObjectAttribute({})
|
||||||
# Overwrite the parameters of self._default_attributes_parameters with the ones of value
|
# Overwrite the parameters of self._default_attributes_parameters with the ones of value
|
||||||
attribute.from_dict(object_relation=object_relation, **dict(self._default_attributes_parameters, **value))
|
if sys.version_info < (3, 5):
|
||||||
|
attribute.from_dict(object_relation=object_relation, **dict(self._default_attributes_parameters, **value))
|
||||||
|
else:
|
||||||
|
attribute.from_dict(object_relation=object_relation, **{**self._default_attributes_parameters, **value})
|
||||||
self.__fast_attribute_access[object_relation].append(attribute)
|
self.__fast_attribute_access[object_relation].append(attribute)
|
||||||
self.Attribute.append(attribute)
|
self.Attribute.append(attribute)
|
||||||
self.edited = True
|
self.edited = True
|
||||||
|
|
|
@ -3919,7 +3919,7 @@
|
||||||
"date": "2017-12-14",
|
"date": "2017-12-14",
|
||||||
"distribution": "3",
|
"distribution": "3",
|
||||||
"id": "9616",
|
"id": "9616",
|
||||||
"info": "OSINT - Attackers Deploy New ICS Attack Framework “TRITON” and Cause Operational Disruption to Critical Infrastructure",
|
"info": "OSINT - Attackers Deploy New ICS Attack Framework \"TRITON\" and Cause Operational Disruption to Critical Infrastructure",
|
||||||
"org_id": "2",
|
"org_id": "2",
|
||||||
"orgc_id": "2",
|
"orgc_id": "2",
|
||||||
"published": false,
|
"published": false,
|
||||||
|
@ -4019,7 +4019,7 @@
|
||||||
"date": "2017-10-23",
|
"date": "2017-10-23",
|
||||||
"distribution": "3",
|
"distribution": "3",
|
||||||
"id": "9208",
|
"id": "9208",
|
||||||
"info": "Talos: “Cyber Conflict” Decoy Document Used In Real Cyber Conflict",
|
"info": "Talos: \"Cyber Conflict\" Decoy Document Used In Real Cyber Conflict",
|
||||||
"org_id": "291",
|
"org_id": "291",
|
||||||
"orgc_id": "291",
|
"orgc_id": "291",
|
||||||
"published": true,
|
"published": true,
|
||||||
|
|
|
@ -3922,7 +3922,7 @@
|
||||||
"date": "2017-12-14",
|
"date": "2017-12-14",
|
||||||
"distribution": "3",
|
"distribution": "3",
|
||||||
"id": "9616",
|
"id": "9616",
|
||||||
"info": "OSINT - Attackers Deploy New ICS Attack Framework “TRITON” and Cause Operational Disruption to Critical Infrastructure",
|
"info": "OSINT - Attackers Deploy New ICS Attack Framework \"TRITON\" and Cause Operational Disruption to Critical Infrastructure",
|
||||||
"org_id": "2",
|
"org_id": "2",
|
||||||
"orgc_id": "2",
|
"orgc_id": "2",
|
||||||
"published": false,
|
"published": false,
|
||||||
|
@ -4022,7 +4022,7 @@
|
||||||
"date": "2017-10-23",
|
"date": "2017-10-23",
|
||||||
"distribution": "3",
|
"distribution": "3",
|
||||||
"id": "9208",
|
"id": "9208",
|
||||||
"info": "Talos: “Cyber Conflict” Decoy Document Used In Real Cyber Conflict",
|
"info": "Talos: \"Cyber Conflict\" Decoy Document Used In Real Cyber Conflict",
|
||||||
"org_id": "291",
|
"org_id": "291",
|
||||||
"orgc_id": "291",
|
"orgc_id": "291",
|
||||||
"published": true,
|
"published": true,
|
||||||
|
|
|
@ -26,20 +26,20 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
with open('tests/mispevent_testfiles/simple.json', 'r') as f:
|
with open('tests/mispevent_testfiles/simple.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_event(self):
|
def test_event(self):
|
||||||
self.init_event()
|
self.init_event()
|
||||||
self.mispevent.publish()
|
self.mispevent.publish()
|
||||||
with open('tests/mispevent_testfiles/event.json', 'r') as f:
|
with open('tests/mispevent_testfiles/event.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_loadfile(self):
|
def test_loadfile(self):
|
||||||
self.mispevent.load_file('tests/mispevent_testfiles/event.json')
|
self.mispevent.load_file('tests/mispevent_testfiles/event.json')
|
||||||
with open('tests/mispevent_testfiles/event.json', 'r') as f:
|
with open('tests/mispevent_testfiles/event.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_event_tag(self):
|
def test_event_tag(self):
|
||||||
self.init_event()
|
self.init_event()
|
||||||
|
@ -50,7 +50,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.mispevent.add_tag(new_tag)
|
self.mispevent.add_tag(new_tag)
|
||||||
with open('tests/mispevent_testfiles/event_tags.json', 'r') as f:
|
with open('tests/mispevent_testfiles/event_tags.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_attribute(self):
|
def test_attribute(self):
|
||||||
self.init_event()
|
self.init_event()
|
||||||
|
@ -62,13 +62,13 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.assertEqual(attr_tags[0].name, 'osint')
|
self.assertEqual(attr_tags[0].name, 'osint')
|
||||||
with open('tests/mispevent_testfiles/attribute.json', 'r') as f:
|
with open('tests/mispevent_testfiles/attribute.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
# Fake setting an attribute ID for testing
|
# Fake setting an attribute ID for testing
|
||||||
self.mispevent.attributes[0].id = 42
|
self.mispevent.attributes[0].id = 42
|
||||||
self.mispevent.delete_attribute(42)
|
self.mispevent.delete_attribute(42)
|
||||||
with open('tests/mispevent_testfiles/attribute_del.json', 'r') as f:
|
with open('tests/mispevent_testfiles/attribute_del.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_object_tag(self):
|
def test_object_tag(self):
|
||||||
self.mispevent.add_object(name='file', strict=True)
|
self.mispevent.add_object(name='file', strict=True)
|
||||||
|
@ -90,7 +90,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.assertEqual(self.mispevent.objects[0].references[0].relationship_type, 'baz')
|
self.assertEqual(self.mispevent.objects[0].references[0].relationship_type, 'baz')
|
||||||
with open('tests/mispevent_testfiles/event_obj_attr_tag.json', 'r') as f:
|
with open('tests/mispevent_testfiles/event_obj_attr_tag.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
@unittest.skip("Not supported on MISP: https://github.com/MISP/MISP/issues/2638 - https://github.com/MISP/PyMISP/issues/168")
|
@unittest.skip("Not supported on MISP: https://github.com/MISP/MISP/issues/2638 - https://github.com/MISP/PyMISP/issues/168")
|
||||||
def test_object_level_tag(self):
|
def test_object_level_tag(self):
|
||||||
|
@ -100,7 +100,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.mispevent.objects[0].uuid = 'a'
|
self.mispevent.objects[0].uuid = 'a'
|
||||||
with open('tests/mispevent_testfiles/event_obj_tag.json', 'r') as f:
|
with open('tests/mispevent_testfiles/event_obj_tag.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_malware(self):
|
def test_malware(self):
|
||||||
with open('tests/mispevent_testfiles/simple.json', 'rb') as f:
|
with open('tests/mispevent_testfiles/simple.json', 'rb') as f:
|
||||||
|
@ -112,7 +112,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.assertEqual(attribute.malware_binary, pseudofile)
|
self.assertEqual(attribute.malware_binary, pseudofile)
|
||||||
with open('tests/mispevent_testfiles/malware.json', 'r') as f:
|
with open('tests/mispevent_testfiles/malware.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_existing_malware(self):
|
def test_existing_malware(self):
|
||||||
self.mispevent.load_file('tests/mispevent_testfiles/malware_exist.json')
|
self.mispevent.load_file('tests/mispevent_testfiles/malware_exist.json')
|
||||||
|
@ -127,19 +127,20 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
sighting.from_dict(value='1', type='bar', timestamp=11111111)
|
sighting.from_dict(value='1', type='bar', timestamp=11111111)
|
||||||
with open('tests/mispevent_testfiles/sighting.json', 'r') as f:
|
with open('tests/mispevent_testfiles/sighting.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(sighting.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(sighting.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_existing_event(self):
|
def test_existing_event(self):
|
||||||
self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
|
self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
|
||||||
with open('tests/mispevent_testfiles/existing_event.json', 'r') as f:
|
with open('tests/mispevent_testfiles/existing_event.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
|
||||||
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_shadow_attributes_existing(self):
|
def test_shadow_attributes_existing(self):
|
||||||
self.mispevent.load_file('tests/mispevent_testfiles/shadow.json')
|
self.mispevent.load_file('tests/mispevent_testfiles/shadow.json')
|
||||||
with open('tests/mispevent_testfiles/shadow.json', 'r') as f:
|
with open('tests/mispevent_testfiles/shadow.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
@unittest.skip("Not supported on MISP.")
|
@unittest.skip("Not supported on MISP.")
|
||||||
def test_shadow_attributes(self):
|
def test_shadow_attributes(self):
|
||||||
|
@ -152,7 +153,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
del p.uuid
|
del p.uuid
|
||||||
with open('tests/mispevent_testfiles/proposals.json', 'r') as f:
|
with open('tests/mispevent_testfiles/proposals.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_default_attributes(self):
|
def test_default_attributes(self):
|
||||||
self.mispevent.add_object(name='file', strict=True)
|
self.mispevent.add_object(name='file', strict=True)
|
||||||
|
@ -165,7 +166,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.mispevent.objects[1].uuid = 'b'
|
self.mispevent.objects[1].uuid = 'b'
|
||||||
with open('tests/mispevent_testfiles/event_obj_def_param.json', 'r') as f:
|
with open('tests/mispevent_testfiles/event_obj_def_param.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_obj_default_values(self):
|
def test_obj_default_values(self):
|
||||||
self.init_event()
|
self.init_event()
|
||||||
|
@ -181,7 +182,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.mispevent.objects[0].uuid = 'a'
|
self.mispevent.objects[0].uuid = 'a'
|
||||||
with open('tests/mispevent_testfiles/def_param.json', 'r') as f:
|
with open('tests/mispevent_testfiles/def_param.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_event_not_edited(self):
|
def test_event_not_edited(self):
|
||||||
self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
|
self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
|
||||||
|
@ -246,7 +247,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.assertTrue(self.mispevent.edited)
|
self.assertTrue(self.mispevent.edited)
|
||||||
with open('tests/mispevent_testfiles/existing_event_edited.json', 'r') as f:
|
with open('tests/mispevent_testfiles/existing_event_edited.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
def test_obj_by_id(self):
|
def test_obj_by_id(self):
|
||||||
self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
|
self.mispevent.load_file('tests/mispevent_testfiles/existing_event.json')
|
||||||
|
@ -258,7 +259,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
self.mispevent.add_object(name='test_object_template', strict=True, misp_objects_path_custom='tests/mispevent_testfiles')
|
self.mispevent.add_object(name='test_object_template', strict=True, misp_objects_path_custom='tests/mispevent_testfiles')
|
||||||
with self.assertRaises(InvalidMISPObject) as e:
|
with self.assertRaises(InvalidMISPObject) as e:
|
||||||
# Fail on required
|
# Fail on required
|
||||||
self.mispevent.to_json()
|
self.mispevent.to_json(sort_keys=True, indent=2)
|
||||||
if sys.version_info >= (3, ):
|
if sys.version_info >= (3, ):
|
||||||
self.assertEqual(e.exception.message, '{\'member3\'} are required.')
|
self.assertEqual(e.exception.message, '{\'member3\'} are required.')
|
||||||
else:
|
else:
|
||||||
|
@ -269,7 +270,7 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
del a.uuid
|
del a.uuid
|
||||||
with self.assertRaises(InvalidMISPObject) as e:
|
with self.assertRaises(InvalidMISPObject) as e:
|
||||||
# Fail on requiredOneOf
|
# Fail on requiredOneOf
|
||||||
self.mispevent.to_json()
|
self.mispevent.to_json(sort_keys=True, indent=2)
|
||||||
self.assertEqual(e.exception.message, 'At least one of the following attributes is required: member1, member2')
|
self.assertEqual(e.exception.message, 'At least one of the following attributes is required: member1, member2')
|
||||||
|
|
||||||
a = self.mispevent.objects[0].add_attribute('member1', value='bar')
|
a = self.mispevent.objects[0].add_attribute('member1', value='bar')
|
||||||
|
@ -278,14 +279,14 @@ class TestMISPEvent(unittest.TestCase):
|
||||||
del a.uuid
|
del a.uuid
|
||||||
with self.assertRaises(InvalidMISPObject) as e:
|
with self.assertRaises(InvalidMISPObject) as e:
|
||||||
# member1 is not a multiple
|
# member1 is not a multiple
|
||||||
self.mispevent.to_json()
|
self.mispevent.to_json(sort_keys=True, indent=2)
|
||||||
self.assertEqual(e.exception.message, 'Multiple occurrences of member1 is not allowed')
|
self.assertEqual(e.exception.message, 'Multiple occurrences of member1 is not allowed')
|
||||||
|
|
||||||
self.mispevent.objects[0].attributes = self.mispevent.objects[0].attributes[:2]
|
self.mispevent.objects[0].attributes = self.mispevent.objects[0].attributes[:2]
|
||||||
self.mispevent.objects[0].uuid = 'a'
|
self.mispevent.objects[0].uuid = 'a'
|
||||||
with open('tests/mispevent_testfiles/misp_custom_obj.json', 'r') as f:
|
with open('tests/mispevent_testfiles/misp_custom_obj.json', 'r') as f:
|
||||||
ref_json = json.load(f)
|
ref_json = json.load(f)
|
||||||
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
|
self.assertEqual(self.mispevent.to_json(sort_keys=True, indent=2), json.dumps(ref_json, sort_keys=True, indent=2))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue