Skip to content

Commit

Permalink
Merge branch 'release/1.4.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
nadouani committed Feb 7, 2018
2 parents 5714276 + 88e17a0 commit d19f419
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 18 deletions.
24 changes: 21 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
# Change Log

## [1.4.2](https://github.com/TheHive-Project/TheHive4py/tree/1.4.2) (2017-12-27)
## [1.4.3](https://github.com/TheHive-Project/TheHive4py/tree/1.4.3)

[Full Changelog](https://github.com/TheHive-Project/TheHive4py/compare/1.4.2...1.4.3)

**Implemented enhancements:**

- add update\_alert to allow updating an alert [\#61](https://github.com/TheHive-Project/TheHive4py/pull/61) ([Rolinh](https://github.com/Rolinh))

**Fixed bugs:**

- How to close a case via API [\#67](https://github.com/TheHive-Project/TheHive4py/issues/67)
- CustomFields are not updated in update\_case [\#66](https://github.com/TheHive-Project/TheHive4py/issues/66)
- Correction in update\_case usage [\#57](https://github.com/TheHive-Project/TheHive4py/issues/57)

**Merged pull requests:**

- created get\_linked\_cases method in api [\#60](https://github.com/TheHive-Project/TheHive4py/pull/60) ([billmurrin](https://github.com/billmurrin))
- fix spelling of exception [\#58](https://github.com/TheHive-Project/TheHive4py/pull/58) ([billmurrin](https://github.com/billmurrin))

[1.4.2](https://github.com/TheHive-Project/TheHive4py/compare/1.4.1...1.4.2)
## [1.4.2](https://github.com/TheHive-Project/TheHive4py/tree/1.4.2) (2017-12-27)
[Full Changelog](https://github.com/TheHive-Project/TheHive4py/compare/1.4.1...1.4.2)

**Implemented enhancements:**

Expand Down Expand Up @@ -148,4 +166,4 @@



\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
2 changes: 1 addition & 1 deletion samples/test-alert-create.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from thehive4py.api import TheHiveApi
from thehive4py.models import Alert, AlertArtifact

api = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')

artifacts = [
AlertArtifact(dataType='ip', data='8.8.8.8'),
Expand Down
2 changes: 1 addition & 1 deletion samples/test-case-create.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from thehive4py.api import TheHiveApi
from thehive4py.models import Case, CaseTask, CustomFieldHelper

api = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')

# Prepare the sample case
tasks = [
Expand Down
2 changes: 1 addition & 1 deletion samples/test-case-create__case-helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from thehive4py.exceptions import CaseException
from thehive4py.models import CaseTask

thehive = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')


# Prepare the sample case
Expand Down
2 changes: 1 addition & 1 deletion samples/test-case-observable.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from thehive4py.api import TheHiveApi
from thehive4py.models import Case, CaseObservable

api = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')

print('Create case')
print('-----------------------------')
Expand Down
2 changes: 1 addition & 1 deletion samples/test-case-search.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from thehive4py.api import TheHiveApi
from thehive4py.query import *

api = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')


def search(title, query, range, sort):
Expand Down
2 changes: 1 addition & 1 deletion samples/test-case-template.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from thehive4py.api import TheHiveApi
from thehive4py.models import Case, CaseTemplate

api = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')

print('Create case from template')
print('-----------------------------')
Expand Down
2 changes: 1 addition & 1 deletion samples/test-case-update.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from thehive4py.api import TheHiveApi


thehive = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')

# Create a new case
case = thehive.case.create(title='From TheHive4Py', description='N/A', tlp=3, flag=True,
Expand Down
27 changes: 27 additions & 0 deletions samples/test-case-update__case-helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
from __future__ import unicode_literals

from thehive4py.api import TheHiveApi
import json

api = TheHiveApi('http://localhost:9000', '**YOUR_API_KEY**')

# Update the case by ID
print('Update Case')
print('-----------------------------')

try:
updated_case = api.case.update('AWFTw7pcX9h1rajWeETC',
status='Resolved',
resolutionStatus='TruePositive',
impactStatus='NoImpact',
summary='closed by api',
tags=['test'])

# Print the details of the updated case
print(updated_case.jsonify())
except CaseException as e:
print("Error updating case. {}".format(e))
2 changes: 1 addition & 1 deletion samples/test-get-template.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from thehive4py.models import CaseTemplate
from thehive4py.exceptions import CaseTemplateException

api = TheHiveApi('http://127.0.0.1:9000', 'username', 'password', {'http': '', 'https': ''})
api = TheHiveApi('http://127.0.0.1:9000', '**YOUR_API_KEY**')

print('Find existing case template')
print('-----------------------------')
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

setup(
name='thehive4py',
version='1.4.2',
version='1.4.3',
description='Python API client for TheHive.',
long_description=read_md('README.md'),
author='TheHive-Project',
Expand Down
52 changes: 46 additions & 6 deletions thehive4py/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ def __find_rows(self, find_url, **attributes):
except requests.exceptions.RequestException as e:
raise TheHiveException("Error: {}".format(e))

def do_patch(self, api_url, **attributes):
return requests.patch(self.url + api_url, headers={'Content-Type': 'application/json'}, json=attributes,
proxies=self.proxies, auth=self.auth, verify=self.cert)

def create_case(self, case):

"""
Expand All @@ -99,21 +103,21 @@ def create_case(self, case):
except requests.exceptions.RequestException as e:
raise CaseException("Case create error: {}".format(e))

def update_case(self, case):
def update_case(self, case, fields=[]):
"""
Update a case.
:param case: The case to update. The case's `id` determines which case to update.
:param fields: Optional parameter, an array of fields names, the ones we want to update
:return:
"""
req = self.url + "/api/case/{}".format(case.id)

# Choose which attributes to send
update_keys = [
'title', 'description', 'severity', 'startDate', 'owner', 'flag', 'tlp', 'tags', 'resolutionStatus',
'impactStatus', 'summary', 'endDate', 'metrics'
'impactStatus', 'summary', 'endDate', 'metrics', 'customFields'
]
data = {k: v for k, v in case.__dict__.items() if k in update_keys}

data = {k: v for k, v in case.__dict__.items() if (len(fields) > 0 and k in fields) or (len(fields) == 0 and k in update_keys)}
try:
return requests.patch(req, headers={'Content-Type': 'application/json'}, json=data, proxies=self.proxies, auth=self.auth, verify=self.cert)
except requests.exceptions.RequestException:
Expand Down Expand Up @@ -248,7 +252,7 @@ def get_case_observables(self, case_id, **attributes):
try:
return requests.post(req, params=params, json=data, proxies=self.proxies, auth=self.auth, verify=self.cert)
except requests.exceptions.RequestException as e:
raise CaseObserableException("Case observables search error: {}".format(e))
raise CaseObservableException("Case observables search error: {}".format(e))

def get_case_tasks(self, case_id, **attributes):
req = self.url + "/api/case/task/_search"
Expand Down Expand Up @@ -277,6 +281,19 @@ def get_case_tasks(self, case_id, **attributes):
except requests.exceptions.RequestException as e:
raise CaseTaskException("Case tasks search error: {}".format(e))

def get_linked_cases(self, case_id):
"""
:param case_id: Case identifier
:return: TheHive case(s)
:rtype: json
"""
req = self.url + "/api/case/{}/links".format(case_id)

try:
return requests.get(req, proxies=self.proxies, auth=self.auth, verify=self.cert)
except requests.exceptions.RequestException as e:
raise CaseException("Linked cases fetch error: {}".format(e))

def get_case_template(self, name):

"""
Expand Down Expand Up @@ -333,6 +350,29 @@ def create_alert(self, alert):
except requests.exceptions.RequestException as e:
raise AlertException("Alert create error: {}".format(e))

def update_alert(self, alert_id, alert, fields=[]):
"""
Update an alert.
:param alert_id: The ID of the alert to update.
:param data: The alert to update.
:param fields: Optional parameter, an array of fields names, the ones we want to update
:return:
"""
req = self.url + "/api/alert/{}".format(alert_id)

# update only the alert attributes that are not read-only
update_keys = ['tlp', 'severity', 'tags', 'caseTemplate', 'title', 'description']

data = {k: v for k, v in alert.__dict__.items() if
(len(fields) > 0 and k in fields) or (len(fields) == 0 and k in update_keys)}

if hasattr(alert, 'artifacts'):
data['artifacts'] = [a.__dict__ for a in alert.artifacts]
try:
return requests.patch(req, headers={'Content-Type': 'application/json'}, json=data, proxies=self.proxies, auth=self.auth, verify=self.cert)
except requests.exceptions.RequestException:
raise AlertException("Alert update error: {}".format(e))

def get_alert(self, alert_id):
"""
:param alert_id: Alert identifier
Expand All @@ -342,7 +382,7 @@ def get_alert(self, alert_id):
req = self.url + "/api/alert/{}".format(alert_id)

try:
return requests.get(req, proxies=self.proxies, auth=self.auth,verify=self.cert)
return requests.get(req, proxies=self.proxies, auth=self.auth, verify=self.cert)
except requests.exceptions.RequestException as e:
raise AlertException("Alert fetch error: {}".format(e))

Expand Down
19 changes: 19 additions & 0 deletions thehive4py/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,25 @@ def create(self, title, description, **kwargs):
else:
raise CaseException("Server returned {}: {}".format(response.status_code, response.text))

def update(self, case_id, **attributes):
"""
Update a case.
:param case_id: The ID of the case to update
:param attributes: key=value pairs of case attributes to update (field=new_value)
:return: The created instance.
"""

response = self._thehive.do_patch("/api/case/{}".format(case_id), **attributes)

if response.status_code == requests.codes.unauthorized:
raise TheHiveException("Authentication failed")

if self.status_ok(response.status_code):
return self(response.json()['id'])
else:
raise CaseException("Server returned {}: {}".format(response.status_code, response.text))

@staticmethod
def status_ok(status_code):
"""Check whether a status code is OK"""
Expand Down

0 comments on commit d19f419

Please sign in to comment.