Skip to content

Commit fd990cc

Browse files
authored
Merge pull request #451 from TheHive-Project/438-review-task-log-endpoints
#438 - Review task log endpoints
2 parents 217b1db + f7d4915 commit fd990cc

File tree

3 files changed

+165
-16
lines changed

3 files changed

+165
-16
lines changed

tests/test_task_log_endpoint.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pathlib import Path
22

33
import pytest
4+
45
from thehive4py.client import TheHiveApi
56
from thehive4py.errors import TheHiveError
67
from thehive4py.helpers import now_to_ts
@@ -23,6 +24,29 @@ def test_create_and_get(self, thehive: TheHiveApi, test_task: OutputTask):
2324

2425
assert created_log == fetched_log
2526

27+
def test_create_with_attachment(
28+
self, thehive: TheHiveApi, test_task: OutputTask, tmp_path: Path
29+
):
30+
31+
attachment_paths = [str(tmp_path / f"attachment-{i}.txt") for i in range(2)]
32+
33+
for path in attachment_paths:
34+
with open(path, "w") as attachment_fp:
35+
attachment_fp.write(f"content of {path}")
36+
37+
log_with_attachment = thehive.task_log.create(
38+
task_id=test_task["_id"],
39+
task_log={
40+
"message": "My test log",
41+
"includeInTimeline": now_to_ts(),
42+
"startDate": now_to_ts(),
43+
"attachments": attachment_paths,
44+
},
45+
)
46+
47+
assert "attachments" in log_with_attachment
48+
assert len(log_with_attachment["attachments"]) == len(attachment_paths)
49+
2650
def test_delete(self, thehive: TheHiveApi, test_task_log: OutputTaskLog):
2751
thehive.task_log.delete(task_log_id=test_task_log["_id"])
2852

@@ -45,7 +69,7 @@ def test_add_and_delete_attachment(
4569
with open(attachment_path, "w") as attachment_fp:
4670
attachment_fp.write("some content...")
4771

48-
thehive.task_log.add_attachments(
72+
thehive.task_log.add_attachment(
4973
task_log_id=test_task_log["_id"], attachment_paths=[attachment_path]
5074
)
5175

@@ -63,3 +87,30 @@ def test_add_and_delete_attachment(
6387
)
6488

6589
assert attachments == []
90+
91+
def test_add_and_delete_attachments(
92+
self, thehive: TheHiveApi, test_task_log: OutputTaskLog, tmp_path: Path
93+
):
94+
attachment_path = str(tmp_path / "my-attachment.txt")
95+
with open(attachment_path, "w") as attachment_fp:
96+
attachment_fp.write("some content...")
97+
98+
with pytest.deprecated_call():
99+
thehive.task_log.add_attachments(
100+
task_log_id=test_task_log["_id"], attachment_paths=[attachment_path]
101+
)
102+
103+
attachments = thehive.task_log.get(task_log_id=test_task_log["_id"]).get(
104+
"attachments", []
105+
)
106+
107+
for attachment in attachments:
108+
thehive.task_log.delete_attachment(
109+
task_log_id=test_task_log["_id"], attachment_id=attachment["_id"]
110+
)
111+
112+
attachments = thehive.task_log.get(task_log_id=test_task_log["_id"]).get(
113+
"attachments", []
114+
)
115+
116+
assert attachments == []

thehive4py/endpoints/task_log.py

Lines changed: 109 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import json as jsonlib
2+
import warnings
13
from typing import List
24

35
from thehive4py.endpoints._base import EndpointBase
@@ -6,33 +8,96 @@
68

79

810
class TaskLogEndpoint(EndpointBase):
9-
def create(self, task_id: str, task_log: InputTaskLog) -> OutputTaskLog:
11+
def create(
12+
self,
13+
task_id: str,
14+
task_log: InputTaskLog,
15+
) -> OutputTaskLog:
16+
"""Create a task log.
17+
18+
Args:
19+
task_id: The id of the task to create the log in.
20+
task_log: The body of the task log.
21+
22+
Returns:
23+
The created task_log.
24+
"""
25+
if "attachments" in task_log:
26+
files: List[tuple] = [
27+
("attachments", self._fileinfo_from_filepath(attachment_path))
28+
for attachment_path in task_log["attachments"]
29+
]
30+
files.append(("_json", jsonlib.dumps(task_log)))
31+
kwargs: dict = {"files": files}
32+
else:
33+
kwargs = {"json": task_log}
1034
return self._session.make_request(
11-
"POST", path=f"/api/v1/task/{task_id}/log", json=task_log
35+
"POST", path=f"/api/v1/task/{task_id}/log", **kwargs
1236
)
1337

14-
def get(self, task_log_id: str) -> OutputTaskLog:
15-
# TODO: temp implementation until a dedicated get endpoint
16-
logs = self._session.make_request(
17-
"POST",
18-
path="/api/v1/query",
19-
json={"query": [{"_name": "getLog", "idOrName": task_log_id}]},
20-
)
38+
def delete(self, task_log_id: str) -> None:
39+
"""Delete a task log.
2140
22-
try:
23-
return logs[0]
24-
except IndexError:
25-
raise TheHiveError("404 - Task Log Not Found")
41+
Args:
42+
task_log_id: The id of the task log.
2643
27-
def delete(self, task_log_id: str) -> None:
44+
Returns:
45+
N/A
46+
"""
2847
return self._session.make_request("DELETE", path=f"/api/v1/log/{task_log_id}")
2948

3049
def update(self, task_log_id: str, fields: InputUpdateTaskLog) -> None:
50+
"""Update a task log.
51+
52+
Args:
53+
task_log_id: The id of the task log.
54+
fields: The fields of the task log to update.
55+
56+
Returns:
57+
N/A
58+
"""
3159
return self._session.make_request(
3260
"PATCH", path=f"/api/v1/log/{task_log_id}", json=fields
3361
)
3462

63+
def add_attachment(self, task_log_id: str, attachment_paths: List[str]) -> None:
64+
"""Add attachments to a task log.
65+
66+
Args:
67+
task_log_id: The id of the task log.
68+
attachment_paths: List of paths to the attachments to create.
69+
70+
Returns:
71+
The created task log attachments.
72+
"""
73+
files = [
74+
("attachments", self._fileinfo_from_filepath(attachment_path))
75+
for attachment_path in attachment_paths
76+
]
77+
return self._session.make_request(
78+
"POST", f"/api/v1/log/{task_log_id}/attachments", files=files
79+
)
80+
3581
def add_attachments(self, task_log_id: str, attachment_paths: List[str]) -> None:
82+
"""Add attachments to a task log.
83+
84+
!!! warning
85+
Deprecated: use [task_log.add_attachment]
86+
[thehive4py.endpoints.task_log.TaskLogEndpoint.add_attachment]
87+
instead
88+
89+
Args:
90+
task_log_id: The id of the task log.
91+
attachment_paths: List of paths to the attachments to create.
92+
93+
Returns:
94+
The created task log attachments.
95+
"""
96+
warnings.warn(
97+
message=("Deprecated: use the task_log.add_attachment method instead"),
98+
category=DeprecationWarning,
99+
stacklevel=2,
100+
)
36101
files = [
37102
("attachments", self._fileinfo_from_filepath(attachment_path))
38103
for attachment_path in attachment_paths
@@ -42,6 +107,36 @@ def add_attachments(self, task_log_id: str, attachment_paths: List[str]) -> None
42107
)
43108

44109
def delete_attachment(self, task_log_id: str, attachment_id: str) -> None:
110+
"""Delete a task log attachment.
111+
112+
Args:
113+
task_log_id: The id of the task log.
114+
attachment_id: The id of the task log attachment.
115+
116+
Returns:
117+
N/A
118+
"""
45119
return self._session.make_request(
46120
"DELETE", f"/api/v1/log/{task_log_id}/attachments/{attachment_id}"
47121
)
122+
123+
def get(self, task_log_id: str) -> OutputTaskLog:
124+
"""Get a task log by id.
125+
126+
Args:
127+
task_log_id: The id of the task log.
128+
129+
Returns:
130+
The task log specified by the id.
131+
"""
132+
# TODO: temp implementation until a dedicated get endpoint [if ever ;)]
133+
logs = self._session.make_request(
134+
"POST",
135+
path="/api/v1/query",
136+
json={"query": [{"_name": "getLog", "idOrName": task_log_id}]},
137+
)
138+
139+
try:
140+
return logs[0]
141+
except IndexError:
142+
raise TheHiveError("404 - Task Log Not Found")

thehive4py/types/task_log.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import List, TypedDict
22

3+
from thehive4py.types.attachment import OutputAttachment
4+
35

46
class InputTaskLogRequired(TypedDict):
57
message: str
@@ -8,6 +10,7 @@ class InputTaskLogRequired(TypedDict):
810
class InputTaskLog(InputTaskLogRequired, total=False):
911
startDate: int
1012
includeInTimeline: int
13+
attachments: List[str]
1114

1215

1316
class OutputTaskLogRequired(TypedDict):
@@ -24,7 +27,7 @@ class OutputTaskLogRequired(TypedDict):
2427
class OutputTaskLog(OutputTaskLogRequired, total=False):
2528
_updatedBy: str
2629
_updatedAt: int
27-
attachments: List[dict] # TODO: typehint
30+
attachments: List[OutputAttachment]
2831
includeInTimeline: int
2932

3033

0 commit comments

Comments
 (0)