Skip to content

Commit

Permalink
Endpoint for case templates
Browse files Browse the repository at this point in the history
  • Loading branch information
Anko59 committed Dec 27, 2024
1 parent 570066e commit 9d7c45e
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ repos:
language: system
pass_filenames: false
always_run: true
stages: [push]
stages: [pre-push]
24 changes: 24 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from thehive4py.helpers import now_to_ts
from thehive4py.types.alert import InputAlert, OutputAlert
from thehive4py.types.case import InputCase, OutputCase
from thehive4py.types.case_template import InputCaseTemplate, OutputCaseTemplate
from thehive4py.types.comment import OutputComment
from thehive4py.types.custom_field import OutputCustomField
from thehive4py.types.observable import InputObservable, OutputObservable
Expand Down Expand Up @@ -104,6 +105,17 @@ def test_case(thehive: TheHiveApi) -> OutputCase:
)


@pytest.fixture
def test_case_template(thehive: TheHiveApi) -> OutputCaseTemplate:
return thehive.case_template.create(
case_template={
"name": "my first case template",
"description": "...",
"tags": ["whatever"],
}
)


@pytest.fixture
def test_cases(thehive: TheHiveApi) -> List[OutputCase]:
cases: List[InputCase] = [
Expand All @@ -113,6 +125,18 @@ def test_cases(thehive: TheHiveApi) -> List[OutputCase]:
return [thehive.case.create(case=case) for case in cases]


@pytest.fixture
def test_case_templates(thehive: TheHiveApi) -> List[OutputCaseTemplate]:
case_templates: List[InputCaseTemplate] = [
{"name": "my first case template", "description": "..."},
{"name": "my second case template", "description": "..."},
]
return [
thehive.case_template.create(case_template=case_template)
for case_template in case_templates
]


@pytest.fixture
def test_observable(thehive: TheHiveApi, test_case: OutputCase) -> OutputObservable:
return thehive.observable.create_in_case(
Expand Down
63 changes: 63 additions & 0 deletions tests/test_case_template_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from typing import List

import pytest
from thehive4py.client import TheHiveApi
from thehive4py.errors import TheHiveError
from thehive4py.types.case_template import InputCaseTemplate, OutputCaseTemplate


class TestCaseTemplateEndpoint:
def test_create_and_get(self, thehive: TheHiveApi):
created_case_template = thehive.case_template.create(
case_template={
"name": "my first template",
"description": "Template description",
}
)
fetched_case_template = thehive.case_template.get(created_case_template["_id"])
assert created_case_template == fetched_case_template

def test_update(self, thehive: TheHiveApi, test_case_template: OutputCaseTemplate):
case_template_id = test_case_template["_id"]
update_fields: InputCaseTemplate = {
"name": "updated template name",
"description": "updated template description",
}
thehive.case_template.update(
case_template_id=case_template_id, fields=update_fields
)
updated_case_template = thehive.case_template.get(
case_template_id=case_template_id
)

for key, value in update_fields.items():
assert updated_case_template.get(key) == value

def test_update_with_wrong_argument_error(
self, thehive: TheHiveApi, test_case_template: OutputCaseTemplate
):
case_template_id = test_case_template["_id"]
update_fields: InputCaseTemplate = {
"name": "updated template name",
"description": "updated template description",
}
wrong_kwargs = {"template_fields": update_fields, "wrong_arg": "value"}
with pytest.raises(TheHiveError, match=rf".*{list(wrong_kwargs.keys())}.*"):
thehive.case_template.update(case_template_id=case_template_id, **wrong_kwargs) # type: ignore

def test_delete(self, thehive: TheHiveApi, test_case_template: OutputCaseTemplate):
case_template_id = test_case_template["_id"]
thehive.case_template.delete(case_template_id=case_template_id)
with pytest.raises(TheHiveError):
thehive.case_template.get(case_template_id=case_template_id)

def test_find(
self,
thehive: TheHiveApi,
test_case_templates: List[OutputCaseTemplate],
):
filters = {"name": "my first template"}
found_templates = thehive.case_template.find(filters=filters)
names = [template["name"] for template in found_templates]
for test_template in test_case_templates:
assert test_template["name"] in names
2 changes: 2 additions & 0 deletions thehive4py/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from thehive4py.endpoints import (
AlertEndpoint,
CaseEndpoint,
CaseTemplateEndpoint,
CommentEndpoint,
ObservableEndpoint,
OrganisationEndpoint,
Expand Down Expand Up @@ -62,6 +63,7 @@ def __init__(
# case management endpoints
self.alert = AlertEndpoint(self.session)
self.case = CaseEndpoint(self.session)
self.case_template = CaseTemplateEndpoint(self.session)
self.comment = CommentEndpoint(self.session)
self.observable = ObservableEndpoint(self.session)
self.procedure = ProcedureEndpoint(self.session)
Expand Down
1 change: 1 addition & 0 deletions thehive4py/endpoints/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .alert import AlertEndpoint
from .case import CaseEndpoint
from .case_template import CaseTemplateEndpoint
from .comment import CommentEndpoint
from .cortex import CortexEndpoint
from .custom_field import CustomFieldEndpoint
Expand Down
47 changes: 47 additions & 0 deletions thehive4py/endpoints/case_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from thehive4py.endpoints._base import EndpointBase
from thehive4py.query import QueryExpr
from thehive4py.query.filters import FilterExpr
from thehive4py.query.page import Paginate
from thehive4py.query.sort import SortExpr
from thehive4py.types.case_template import OutputCaseTemplate, InputCaseTemplate
from typing import List, Optional


class CaseTemplateEndpoint(EndpointBase):
def find(
self,
filters: Optional[FilterExpr] = None,
sortby: Optional[SortExpr] = None,
paginate: Optional[Paginate] = None,
) -> List[OutputCaseTemplate]:
query: QueryExpr = [
{"_name": "listCaseTemplate"},
*self._build_subquery(filters=filters, sortby=sortby, paginate=paginate),
]

return self._session.make_request(
"POST",
path="/api/v1/query",
json={"query": query},
params={"name": "caseTemplate"},
)

def get(self, case_template_id: str) -> OutputCaseTemplate:
return self._session.make_request(
"GET", path=f"/api/v1/caseTemplate/{case_template_id}"
)

def create(self, case_template: InputCaseTemplate) -> OutputCaseTemplate:
return self._session.make_request(
"POST", path="/api/v1/caseTemplate", json=case_template
)

def delete(self, case_template_id: str) -> None:
self._session.make_request(
"DELETE", path=f"/api/v1/caseTemplate/{case_template_id}"
)

def update(self, case_template_id: str, fields: InputCaseTemplate) -> None:
return self._session.make_request(
"PATCH", path=f"/api/v1/caseTemplate/{case_template_id}", json=fields
)
52 changes: 52 additions & 0 deletions thehive4py/types/case_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import List, Literal, TypedDict, Union

from .custom_field import InputCustomFieldValue
from .task import InputCreateTask

SeverityValue = Literal[1, 2, 3, 4]
TlpValue = Literal[0, 1, 2, 3, 4]
PapValue = Literal[0, 1, 2, 3]


class InputCaseTemplateRequired(TypedDict):
name: str


class InputCaseTemplate(InputCaseTemplateRequired, total=False):
displayName: str
titlePrefix: str
description: str
severity: SeverityValue
tags: List[str]
flag: bool
tlp: TlpValue
pap: PapValue
summary: str
tasks: List[InputCreateTask]
pageTemplateIds: List[str]
customFields: Union[dict, List[InputCustomFieldValue]]


class OutputCaseTemplateRequired(TypedDict):
_id: str
_type: str
_createdBy: str
_createdAt: int
name: str


class OutputCaseTemplate(OutputCaseTemplateRequired, total=False):
_updatedBy: str
_updatedAt: int
displayName: str
titlePrefix: str
description: str
severity: SeverityValue
tags: List[str]
flag: bool
tlp: TlpValue
pap: PapValue
summary: str
tasks: List[InputCreateTask]
pageTemplateIds: List[str]
customFields: Union[dict, List[InputCustomFieldValue]]

0 comments on commit 9d7c45e

Please sign in to comment.