mirror of https://github.com/MISP/PyMISP
chg: Move MISPTag to Abstract MISP.
parent
96f75cba8a
commit
c41281030b
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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, [])
|
||||||
|
|
Loading…
Reference in New Issue