new: Improve python3.6+ lib

pull/382/head
Raphaël Vinot 2019-04-11 23:13:15 +02:00
parent e8334be9ca
commit 633f75db24
5 changed files with 83 additions and 4 deletions

View File

@ -35,7 +35,7 @@ try:
from .exceptions import PyMISPError, NewEventError, NewAttributeError, MissingDependency, NoURL, NoKey, InvalidMISPObject, UnknownMISPObjectTemplate, PyMISPInvalidFormat, MISPServerError, PyMISPNotImplementedYet, PyMISPUnexpectedResponse, PyMISPEmptyResponse # noqa
from .api import PyMISP # noqa
from .abstract import AbstractMISP, MISPEncode, MISPTag, Distribution, ThreatLevel, Analysis # noqa
from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPUser, MISPOrganisation, MISPSighting, MISPLog # noqa
from .mispevent import MISPEvent, MISPAttribute, MISPObjectReference, MISPObjectAttribute, MISPObject, MISPUser, MISPOrganisation, MISPSighting, MISPLog, MISPShadowAttribute # noqa
from .tools import AbstractMISPObjectGenerator # noqa
from .tools import Neo4j # noqa
from .tools import stix # noqa

View File

@ -164,7 +164,7 @@ class PyMISP(object):
if isinstance(data, dict):
# Remove None values.
data = {k: v for k, v in data.items() if v is not None}
data = json.dumps(data)
data = json.dumps(data, cls=MISPEncode)
req = requests.Request(request_type, url, data=data)
if self.asynch and background_callback is not None:
local_session = FuturesSession

View File

@ -3,7 +3,7 @@
from .exceptions import MISPServerError, PyMISPUnexpectedResponse, PyMISPNotImplementedYet
from .api import PyMISP, everything_broken
from .mispevent import MISPEvent, MISPAttribute, MISPSighting, MISPLog, MISPObject, MISPUser, MISPOrganisation
from .mispevent import MISPEvent, MISPAttribute, MISPSighting, MISPLog, MISPObject, MISPUser, MISPOrganisation, MISPShadowAttribute
from typing import TypeVar, Optional, Tuple, List, Dict, Union
from datetime import date, datetime
import csv
@ -151,6 +151,36 @@ class ExpandedPyMISP(PyMISP):
e.load(updated_event)
return e
def get_attribute(self, attribute_id: int):
attribute = super().get_attribute(attribute_id)
a = MISPAttribute()
a.from_dict(**attribute)
return a
def add_attribute(self, event_id: int, attribute: MISPAttribute):
url = urljoin(self.root_url, 'attributes/add/{}'.format(event_id))
response = self._prepare_request('POST', url, data=attribute)
new_attribute = self._check_response(response)
if isinstance(new_attribute, str):
raise PyMISPUnexpectedResponse(f'Unexpected response from server: {new_attribute}')
elif 'errors' in new_attribute:
return new_attribute
a = MISPAttribute()
a.from_dict(**new_attribute)
return a
def add_attribute_proposal(self, event_id: int, attribute: MISPAttribute):
url = urljoin(self.root_url, 'shadow_attributes/add/{}'.format(event_id))
response = self._prepare_request('POST', url, attribute)
new_attribute_proposal = self._check_response(response)
if isinstance(new_attribute_proposal, str):
raise PyMISPUnexpectedResponse(f'Unexpected response from server: {new_attribute_proposal}')
elif 'errors' in new_attribute_proposal:
return new_attribute_proposal
a = MISPShadowAttribute()
a.from_dict(**new_attribute_proposal)
return a
def update_attribute(self, attribute: MISPAttribute):
updated_attribute = super().update_attribute(attribute.uuid, attribute)
if isinstance(updated_attribute, str):
@ -161,6 +191,48 @@ class ExpandedPyMISP(PyMISP):
a.from_dict(**updated_attribute)
return a
def update_attribute_proposal(self, attribute_id: int, attribute: MISPAttribute):
url = urljoin(self.root_url, 'shadow_attributes/edit/{}'.format(attribute_id))
# FIXME: Inconsistency on MISP side
attribute = {'ShadowAttribute': attribute}
response = self._prepare_request('POST', url, attribute)
attribute_proposal = self._check_response(response)
if isinstance(attribute_proposal, str):
raise PyMISPUnexpectedResponse(f'Unexpected response from server: {attribute_proposal}')
elif 'errors' in attribute_proposal:
return attribute_proposal
a = MISPShadowAttribute()
a.from_dict(**attribute_proposal)
return a
def get_attribute_proposal(self, proposal_id: int):
url = urljoin(self.root_url, 'shadow_attributes/view/{}'.format(proposal_id))
response = self._prepare_request('GET', url)
attribute_proposal = self._check_response(response)
if isinstance(attribute_proposal, str):
raise PyMISPUnexpectedResponse(f'Unexpected response from server: {attribute_proposal}')
elif 'errors' in attribute_proposal:
return attribute_proposal
a = MISPShadowAttribute()
a.from_dict(**attribute_proposal)
return a
def accept_attribute_proposal(self, proposal_id: int):
url = urljoin(self.root_url, 'shadow_attributes/accept/{}'.format(proposal_id))
response = self._prepare_request('POST', url)
r = self._check_response(response)
if isinstance(r, str):
raise PyMISPUnexpectedResponse(f'Unexpected response from server: {r}')
return r
def discard_attribute_proposal(self, proposal_id: int):
url = urljoin(self.root_url, 'shadow_attributes/discard/{}'.format(proposal_id))
response = self._prepare_request('POST', url)
r = self._check_response(response)
if isinstance(r, str):
raise PyMISPUnexpectedResponse(f'Unexpected response from server: {r}')
return r
def add_user(self, user: MISPUser):
user = super().add_user(user)
if isinstance(user, str):

View File

@ -916,11 +916,17 @@ class MISPObjectAttribute(MISPAttribute):
return '<{self.__class__.__name__}(NotInitialized)'.format(self=self)
class MISPShadowAttribute(MISPAttribute):
class MISPShadowAttribute(AbstractMISP):
# NOTE: Kindof a MISPAttribute, but can be lot more lightweight (just one key for example)
def __init__(self):
super(MISPShadowAttribute, self).__init__()
def from_dict(self, **kwargs):
if kwargs.get('ShadowAttribute'):
kwargs = kwargs.get('ShadowAttribute')
super(MISPShadowAttribute, self).from_dict(**kwargs)
class MISPObject(AbstractMISP):

View File

@ -137,6 +137,7 @@ class TestMISPEvent(unittest.TestCase):
ref_json = json.load(f)
self.assertEqual(self.mispevent.to_json(), json.dumps(ref_json, sort_keys=True, indent=2))
@unittest.skip("Not supported on MISP.")
def test_shadow_attributes(self):
self.init_event()
p = self.mispevent.add_proposal(type='filename', value='baz.jpg')