From c41281030bc73f3e9fa0e5fa0214e1c4cb180b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vinot?= Date: Mon, 8 Jan 2018 11:59:32 +0100 Subject: [PATCH] chg: Move MISPTag to Abstract MISP. --- pymisp/__init__.py | 6 +-- pymisp/abstract.py | 54 ++++++++++++++++++++++ pymisp/exceptions.py | 5 ++- pymisp/mispevent.py | 104 ------------------------------------------- 4 files changed, 61 insertions(+), 108 deletions(-) diff --git a/pymisp/__init__.py b/pymisp/__init__.py index a0e8c5f..8dc23fe 100644 --- a/pymisp/__init__.py +++ b/pymisp/__init__.py @@ -27,10 +27,10 @@ def deprecated(func): try: - from .exceptions import PyMISPError, NewEventError, NewAttributeError, MissingDependency, NoURL, NoKey, InvalidMISPObject, UnknownMISPObjectTemplate # noqa + from .exceptions import PyMISPError, NewEventError, NewAttributeError, MissingDependency, NoURL, NoKey, InvalidMISPObject, UnknownMISPObjectTemplate, PyMISPInvalidFormat # noqa from .api import PyMISP # noqa - from .abstract import AbstractMISP, MISPEncode # noqa - from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPTag, MISPUser, MISPOrganisation, MISPSighting # noqa + from .abstract import AbstractMISP, MISPEncode, MISPTag # noqa + from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPUser, MISPOrganisation, MISPSighting # noqa from .tools import AbstractMISPObjectGenerator # noqa from .tools import Neo4j # noqa from .tools import stix # noqa diff --git a/pymisp/abstract.py b/pymisp/abstract.py index 702df34..957f22a 100644 --- a/pymisp/abstract.py +++ b/pymisp/abstract.py @@ -10,6 +10,9 @@ import collections import six # Remove that import when discarding python2 support. import logging +from .exceptions import PyMISPInvalidFormat + + logger = logging.getLogger('pymisp') if six.PY2: @@ -49,6 +52,14 @@ class AbstractMISP(collections.MutableMapping): super(AbstractMISP, self).__init__() self.__edited = True # As we create a new object, we assume it is edited + # List of classes having tags + from .mispevent import MISPAttribute, MISPEvent + self.__has_tags = (MISPAttribute, MISPEvent) + if isinstance(self, self.__has_tags): + self.Tag = [] + setattr(AbstractMISP, 'add_tag', AbstractMISP.__add_tag) + setattr(AbstractMISP, 'tags', property(AbstractMISP.__get_tags, AbstractMISP.__set_tags)) + @property def properties(self): """All the class public properties that will be dumped in the dictionary, and the JSON export. @@ -175,3 +186,46 @@ class AbstractMISP(collections.MutableMapping): return int(d.timestamp()) else: return int((d - datetime.datetime.fromtimestamp(0, UTC())).total_seconds()) + + def __add_tag(self, tag=None, **kwargs): + """Add a tag to the attribute (by name or a MISPTag object)""" + if isinstance(tag, str): + misp_tag = MISPTag() + misp_tag.from_dict(name=tag) + elif isinstance(tag, MISPTag): + misp_tag = tag + elif isinstance(tag, dict): + misp_tag = MISPTag() + misp_tag.from_dict(**tag) + elif kwargs: + misp_tag = MISPTag() + misp_tag.from_dict(**kwargs) + else: + raise PyMISPInvalidFormat("The tag is in an invalid format (can be either string, MISPTag, or an expanded dict): {}".format(tag)) + self.Tag.append(misp_tag) + self.edited = True + + def __get_tags(self): + """Returns a lost of tags associated to this Attribute""" + return self.Tag + + def __set_tags(self, tags): + """Set a list of prepared MISPTag.""" + if all(isinstance(x, MISPTag) for x in tags): + self.Tag = tags + else: + raise PyMISPInvalidFormat('All the attributes have to be of type MISPTag.') + + +class MISPTag(AbstractMISP): + def __init__(self): + super(MISPTag, self).__init__() + + def from_dict(self, name, **kwargs): + self.name = name + super(MISPTag, self).from_dict(**kwargs) + + def __repr__(self): + if hasattr(self, 'name'): + return '<{self.__class__.__name__}(name={self.name})'.format(self=self) + return '<{self.__class__.__name__}(NotInitialized)'.format(self=self) diff --git a/pymisp/exceptions.py b/pymisp/exceptions.py index d828e74..967e9b7 100644 --- a/pymisp/exceptions.py +++ b/pymisp/exceptions.py @@ -1,4 +1,3 @@ - # -*- coding: utf-8 -*- @@ -44,3 +43,7 @@ class InvalidMISPObject(MISPObjectException): class UnknownMISPObjectTemplate(MISPObjectException): """Exception raised when the template is unknown""" pass + + +class PyMISPInvalidFormat(PyMISPError): + pass diff --git a/pymisp/mispevent.py b/pymisp/mispevent.py index b44bdaf..9c7805a 100644 --- a/pymisp/mispevent.py +++ b/pymisp/mispevent.py @@ -114,19 +114,6 @@ class MISPAttribute(AbstractMISP): return self._malware_binary return None - @property - def tags(self): - """Returns a lost of tags associated to this Attribute""" - return self.Tag - - @tags.setter - def tags(self, tags): - """Set a list of prepared MISPTag.""" - if all(isinstance(x, MISPTag) for x in tags): - self.Tag = tags - else: - raise PyMISPError('All the attributes have to be of type MISPTag.') - @property def shadow_attributes(self): return self.ShadowAttribute @@ -143,24 +130,6 @@ class MISPAttribute(AbstractMISP): """Mark the attribute as deleted (soft delete)""" self.deleted = True - def add_tag(self, tag=None, **kwargs): - """Add a tag to the attribute (by name or a MISPTag object)""" - if isinstance(tag, str): - misp_tag = MISPTag() - misp_tag.from_dict(name=tag) - elif isinstance(tag, MISPTag): - misp_tag = tag - elif isinstance(tag, dict): - misp_tag = MISPTag() - misp_tag.from_dict(**tag) - elif kwargs: - misp_tag = MISPTag() - misp_tag.from_dict(**kwargs) - else: - raise PyMISPError("The tag is in an invalid format (can be either string, MISPTag, or an expanded dict): {}".format(tag)) - self.tags.append(misp_tag) - self.edited = True - def add_proposal(self, shadow_attribute=None, **kwargs): """Alias for add_shadow_attribute""" self.add_shadow_attribute(shadow_attribute, **kwargs) @@ -428,17 +397,6 @@ class MISPEvent(AbstractMISP): else: raise PyMISPError('All the attributes have to be of type MISPObject.') - @property - def tags(self): - return self.Tag - - @tags.setter - def tags(self, tags): - if all(isinstance(x, MISPTag) for x in tags): - self.Tag = tags - else: - raise PyMISPError('All the attributes have to be of type MISPTag.') - def load_file(self, event_path): """Load a JSON dump from a file on the disk""" if not os.path.exists(event_path): @@ -583,24 +541,6 @@ class MISPEvent(AbstractMISP): self.shadow_attributes.append(misp_shadow_attribute) self.edited = True - def add_tag(self, tag=None, **kwargs): - """Add a tag to the attribute (by name or a MISPTag object)""" - if isinstance(tag, str): - misp_tag = MISPTag() - misp_tag.from_dict(name=tag) - elif isinstance(tag, MISPTag): - misp_tag = tag - elif isinstance(tag, dict): - misp_tag = MISPTag() - misp_tag.from_dict(**tag) - elif kwargs: - misp_tag = MISPTag() - misp_tag.from_dict(**kwargs) - else: - raise PyMISPError("The tag is in an invalid format (can be either string, MISPTag, or an expanded dict): {}".format(tag)) - self.tags.append(misp_tag) - self.edited = True - def get_attribute_tag(self, attribute_identifier): '''Return the tags associated to an attribute or an object attribute. :attribute_identifier: can be an ID, UUID, or the value. @@ -768,20 +708,6 @@ class MISPEvent(AbstractMISP): return self.to_dict() -class MISPTag(AbstractMISP): - def __init__(self): - super(MISPTag, self).__init__() - - def from_dict(self, name, **kwargs): - self.name = name - super(MISPTag, self).from_dict(**kwargs) - - def __repr__(self): - if hasattr(self, 'name'): - return '<{self.__class__.__name__}(name={self.name})'.format(self=self) - return '<{self.__class__.__name__}(NotInitialized)'.format(self=self) - - class MISPObjectReference(AbstractMISP): def __init__(self): @@ -993,36 +919,6 @@ class MISPObject(AbstractMISP): self.ObjectReference.append(reference) self.edited = True - # Not supported yet - https://github.com/MISP/PyMISP/issues/168 - # @property - # def tags(self): - # return self.Tag - - # @tags.setter - # def tags(self, tags): - # if all(isinstance(x, MISPTag) for x in tags): - # self.Tag = tags - # else: - # raise PyMISPError('All the attributes have to be of type MISPTag.') - - # def add_tag(self, tag=None, **kwargs): - # """Add a tag to the attribute (by name or a MISPTag object)""" - # if isinstance(tag, str): - # misp_tag = MISPTag() - # misp_tag.from_dict(name=tag) - # elif isinstance(tag, MISPTag): - # misp_tag = tag - # elif isinstance(tag, dict): - # misp_tag = MISPTag() - # misp_tag.from_dict(**tag) - # elif kwargs: - # misp_tag = MISPTag() - # misp_tag.from_dict(**kwargs) - # else: - # raise PyMISPError("The tag is in an invalid format (can be either string, MISPTag, or an expanded dict): {}".format(tag)) - # self.tags.append(misp_tag) - # self.edited = True - def get_attributes_by_relation(self, object_relation): '''Returns the list of attributes with the given object relation in the object''' return self.__fast_attribute_access.get(object_relation, [])