chg: Move MISPTag to Abstract MISP.

pull/171/head
Raphaël Vinot 2018-01-08 11:59:32 +01:00
parent 96f75cba8a
commit c41281030b
4 changed files with 61 additions and 108 deletions

View File

@ -27,10 +27,10 @@ def deprecated(func):
try: 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 .api import PyMISP # noqa
from .abstract import AbstractMISP, MISPEncode # noqa from .abstract import AbstractMISP, MISPEncode, MISPTag # noqa
from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPTag, MISPUser, MISPOrganisation, MISPSighting # noqa from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPUser, MISPOrganisation, MISPSighting # noqa
from .tools import AbstractMISPObjectGenerator # noqa from .tools import AbstractMISPObjectGenerator # noqa
from .tools import Neo4j # noqa from .tools import Neo4j # noqa
from .tools import stix # noqa from .tools import stix # noqa

View File

@ -10,6 +10,9 @@ import collections
import six # Remove that import when discarding python2 support. import six # Remove that import when discarding python2 support.
import logging import logging
from .exceptions import PyMISPInvalidFormat
logger = logging.getLogger('pymisp') logger = logging.getLogger('pymisp')
if six.PY2: if six.PY2:
@ -49,6 +52,14 @@ class AbstractMISP(collections.MutableMapping):
super(AbstractMISP, self).__init__() super(AbstractMISP, self).__init__()
self.__edited = True # As we create a new object, we assume it is edited 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 @property
def properties(self): def properties(self):
"""All the class public properties that will be dumped in the dictionary, and the JSON export. """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()) return int(d.timestamp())
else: else:
return int((d - datetime.datetime.fromtimestamp(0, UTC())).total_seconds()) 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)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
@ -44,3 +43,7 @@ class InvalidMISPObject(MISPObjectException):
class UnknownMISPObjectTemplate(MISPObjectException): class UnknownMISPObjectTemplate(MISPObjectException):
"""Exception raised when the template is unknown""" """Exception raised when the template is unknown"""
pass pass
class PyMISPInvalidFormat(PyMISPError):
pass

View File

@ -114,19 +114,6 @@ class MISPAttribute(AbstractMISP):
return self._malware_binary return self._malware_binary
return None 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 @property
def shadow_attributes(self): def shadow_attributes(self):
return self.ShadowAttribute return self.ShadowAttribute
@ -143,24 +130,6 @@ class MISPAttribute(AbstractMISP):
"""Mark the attribute as deleted (soft delete)""" """Mark the attribute as deleted (soft delete)"""
self.deleted = True 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): def add_proposal(self, shadow_attribute=None, **kwargs):
"""Alias for add_shadow_attribute""" """Alias for add_shadow_attribute"""
self.add_shadow_attribute(shadow_attribute, **kwargs) self.add_shadow_attribute(shadow_attribute, **kwargs)
@ -428,17 +397,6 @@ class MISPEvent(AbstractMISP):
else: else:
raise PyMISPError('All the attributes have to be of type MISPObject.') 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): def load_file(self, event_path):
"""Load a JSON dump from a file on the disk""" """Load a JSON dump from a file on the disk"""
if not os.path.exists(event_path): if not os.path.exists(event_path):
@ -583,24 +541,6 @@ class MISPEvent(AbstractMISP):
self.shadow_attributes.append(misp_shadow_attribute) self.shadow_attributes.append(misp_shadow_attribute)
self.edited = True 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): def get_attribute_tag(self, attribute_identifier):
'''Return the tags associated to an attribute or an object attribute. '''Return the tags associated to an attribute or an object attribute.
:attribute_identifier: can be an ID, UUID, or the value. :attribute_identifier: can be an ID, UUID, or the value.
@ -768,20 +708,6 @@ class MISPEvent(AbstractMISP):
return self.to_dict() 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): class MISPObjectReference(AbstractMISP):
def __init__(self): def __init__(self):
@ -993,36 +919,6 @@ class MISPObject(AbstractMISP):
self.ObjectReference.append(reference) self.ObjectReference.append(reference)
self.edited = True 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): def get_attributes_by_relation(self, object_relation):
'''Returns the list of attributes with the given object relation in the object''' '''Returns the list of attributes with the given object relation in the object'''
return self.__fast_attribute_access.get(object_relation, []) return self.__fast_attribute_access.get(object_relation, [])