Skip to content

Commit 042f192

Browse files
committed
Implementation of API v2 endpoints to get comments
1 parent 48af393 commit 042f192

7 files changed

Lines changed: 193 additions & 2 deletions

File tree

source/app/blueprints/rest/v2/events_routes/comments.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
from app.blueprints.rest.endpoints import response_api_not_found
2626
from app.blueprints.rest.endpoints import response_api_created
2727
from app.blueprints.rest.endpoints import response_api_error
28+
from app.blueprints.rest.endpoints import response_api_success
2829
from app.blueprints.rest.parsing import parse_pagination_parameters
2930
from app.iris_engine.access_control.iris_user import iris_current_user
3031
from app.business.comments import comments_get_filtered_by_event
3132
from app.business.comments import comments_create_for_event
33+
from app.business.comments import comments_get_for_event
3234
from app.business.events import events_get
3335
from app.business.errors import ObjectNotFoundError
3436
from app.models.cases import CasesEvent
@@ -73,6 +75,17 @@ def create(self, event_identifier):
7375
except ObjectNotFoundError:
7476
return response_api_not_found()
7577

78+
def read(self, event_identifier, identifier):
79+
try:
80+
event = self._get_event(event_identifier, [CaseAccessLevel.read_only, CaseAccessLevel.full_access])
81+
comment = comments_get_for_event(event, identifier)
82+
result = self._schema.dump(comment)
83+
return response_api_success(result)
84+
except ValidationError as e:
85+
return response_api_error('Data error', data=e.normalized_messages())
86+
except ObjectNotFoundError:
87+
return response_api_not_found()
88+
7689

7790
events_comments_blueprint = Blueprint('events_comments', __name__, url_prefix='/<int:event_identifier>/comments')
7891
comments_operations = CommentsOperations()
@@ -88,3 +101,9 @@ def get_event_comments(event_identifier):
88101
@ac_api_requires()
89102
def create_event_comment(event_identifier):
90103
return comments_operations.create(event_identifier)
104+
105+
106+
@events_comments_blueprint.get('/<int:identifier>')
107+
@ac_api_requires()
108+
def get_event_comment(event_identifier, identifier):
109+
return comments_operations.read(event_identifier, identifier)

source/app/blueprints/rest/v2/evidences_routes/comments.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
from app.blueprints.rest.endpoints import response_api_not_found
2626
from app.blueprints.rest.endpoints import response_api_created
2727
from app.blueprints.rest.endpoints import response_api_error
28+
from app.blueprints.rest.endpoints import response_api_success
2829
from app.iris_engine.access_control.iris_user import iris_current_user
2930
from app.blueprints.rest.parsing import parse_pagination_parameters
3031
from app.business.comments import comments_get_filtered_by_evidence
3132
from app.business.comments import comments_create_for_evidence
33+
from app.business.comments import comments_get_for_evidence
3234
from app.models.models import CaseReceivedFile
3335
from app.business.evidences import evidences_get
3436
from app.business.errors import ObjectNotFoundError
@@ -74,18 +76,35 @@ def create(self, evidence_identifier):
7476
except ObjectNotFoundError:
7577
return response_api_not_found()
7678

79+
def read(self, event_identifier, identifier):
80+
try:
81+
evidence = self._get_evidence(event_identifier, [CaseAccessLevel.read_only, CaseAccessLevel.full_access])
82+
comment = comments_get_for_evidence(evidence, identifier)
83+
result = self._schema.dump(comment)
84+
return response_api_success(result)
85+
except ValidationError as e:
86+
return response_api_error('Data error', data=e.normalized_messages())
87+
except ObjectNotFoundError:
88+
return response_api_not_found()
89+
7790

7891
evidences_comments_blueprint = Blueprint('evidences_comments', __name__, url_prefix='/<int:evidence_identifier>/comments')
7992
comments_operations = CommentsOperations()
8093

8194

8295
@evidences_comments_blueprint.get('')
8396
@ac_api_requires()
84-
def get_evidences_comments(evidence_identifier):
97+
def get_evidence_comments(evidence_identifier):
8598
return comments_operations.get(evidence_identifier)
8699

87100

88101
@evidences_comments_blueprint.post('')
89102
@ac_api_requires()
90-
def create_evidences_comment(evidence_identifier):
103+
def create_evidence_comment(evidence_identifier):
91104
return comments_operations.create(evidence_identifier)
105+
106+
107+
@evidences_comments_blueprint.get('/<int:identifier>')
108+
@ac_api_requires()
109+
def get_evidence_comment(evidence_identifier, identifier):
110+
return comments_operations.read(evidence_identifier, identifier)

source/app/blueprints/rest/v2/iocs_routes/comments.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
from app.blueprints.rest.endpoints import response_api_not_found
2727
from app.blueprints.rest.endpoints import response_api_created
2828
from app.blueprints.rest.endpoints import response_api_error
29+
from app.blueprints.rest.endpoints import response_api_success
2930
from app.blueprints.rest.parsing import parse_pagination_parameters
3031
from app.business.comments import comments_get_filtered_by_ioc
3132
from app.business.comments import comments_create_for_ioc
33+
from app.business.comments import comments_get_for_ioc
3234
from app.business.iocs import iocs_get
3335
from app.business.errors import ObjectNotFoundError
3436
from app.schema.marshables import CommentSchema
@@ -72,6 +74,17 @@ def create(self, ioc_identifier):
7274
except ObjectNotFoundError:
7375
return response_api_not_found()
7476

77+
def read(self, ioc_identifier, identifier):
78+
try:
79+
ioc = self._get_ioc(ioc_identifier, [CaseAccessLevel.read_only, CaseAccessLevel.full_access])
80+
comment = comments_get_for_ioc(ioc, identifier)
81+
result = self._schema.dump(comment)
82+
return response_api_success(result)
83+
except ValidationError as e:
84+
return response_api_error('Data error', data=e.normalized_messages())
85+
except ObjectNotFoundError:
86+
return response_api_not_found()
87+
7588

7689
iocs_comments_blueprint = Blueprint('iocs_comments', __name__, url_prefix='/<int:ioc_identifier>/comments')
7790
comments_operations = CommentsOperations()
@@ -87,3 +100,9 @@ def get_iocs_comments(ioc_identifier):
87100
@ac_api_requires()
88101
def create_iocs_comment(ioc_identifier):
89102
return comments_operations.create(ioc_identifier)
103+
104+
105+
@iocs_comments_blueprint.get('/<int:identifier>')
106+
@ac_api_requires()
107+
def get_ioc_comment(ioc_identifier, identifier):
108+
return comments_operations.read(ioc_identifier, identifier)

source/app/blueprints/rest/v2/notes_routes/comments.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@
2626
from app.blueprints.rest.endpoints import response_api_not_found
2727
from app.blueprints.rest.endpoints import response_api_created
2828
from app.blueprints.rest.endpoints import response_api_error
29+
from app.blueprints.rest.endpoints import response_api_success
2930
from app.blueprints.rest.parsing import parse_pagination_parameters
3031
from app.business.comments import comments_get_filtered_by_note
3132
from app.business.comments import comments_create_for_note
33+
from app.business.comments import comments_get_for_note
3234
from app.business.notes import notes_get
3335
from app.business.errors import ObjectNotFoundError
3436
from app.schema.marshables import CommentSchema
@@ -73,6 +75,17 @@ def create(self, note_identifier):
7375
except ObjectNotFoundError:
7476
return response_api_not_found()
7577

78+
def read(self, note_identifier, identifier):
79+
try:
80+
note = self._get_note(note_identifier, [CaseAccessLevel.read_only, CaseAccessLevel.full_access])
81+
comment = comments_get_for_note(note, identifier)
82+
result = self._schema.dump(comment)
83+
return response_api_success(result)
84+
except ValidationError as e:
85+
return response_api_error('Data error', data=e.normalized_messages())
86+
except ObjectNotFoundError:
87+
return response_api_not_found()
88+
7689

7790
notes_comments_blueprint = Blueprint('notes_comments', __name__, url_prefix='/<int:note_identifier>/comments')
7891
comments_operations = CommentsOperations()
@@ -88,3 +101,9 @@ def get_notes_comments(note_identifier):
88101
@ac_api_requires()
89102
def create_notes_comment(note_identifier):
90103
return comments_operations.create(note_identifier)
104+
105+
106+
@notes_comments_blueprint.get('/<int:identifier>')
107+
@ac_api_requires()
108+
def get_note_comment(note_identifier, identifier):
109+
return comments_operations.read(note_identifier, identifier)

source/app/blueprints/rest/v2/tasks_routes/comments.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
from app.blueprints.rest.parsing import parse_pagination_parameters
2828
from app.blueprints.rest.endpoints import response_api_created
2929
from app.blueprints.rest.endpoints import response_api_error
30+
from app.blueprints.rest.endpoints import response_api_success
3031
from app.business.comments import comments_get_filtered_by_task
3132
from app.business.comments import comments_create_for_task
33+
from app.business.comments import comments_get_for_task
3234
from app.business.tasks import tasks_get
3335
from app.business.errors import ObjectNotFoundError
3436
from app.schema.marshables import CommentSchema
@@ -73,6 +75,17 @@ def create(self, task_identifier):
7375
except ObjectNotFoundError:
7476
return response_api_not_found()
7577

78+
def read(self, task_identifier, identifier):
79+
try:
80+
task = self._get_task(task_identifier, [CaseAccessLevel.read_only, CaseAccessLevel.full_access])
81+
comment = comments_get_for_task(task, identifier)
82+
result = self._schema.dump(comment)
83+
return response_api_success(result)
84+
except ValidationError as e:
85+
return response_api_error('Data error', data=e.normalized_messages())
86+
except ObjectNotFoundError:
87+
return response_api_not_found()
88+
7689

7790
tasks_comments_blueprint = Blueprint('tasks_comments', __name__, url_prefix='/<int:task_identifier>/comments')
7891
comments_operations = CommentsOperations()
@@ -88,3 +101,9 @@ def get_tasks_comments(task_identifier):
88101
@ac_api_requires()
89102
def create_tasks_comment(task_identifier):
90103
return comments_operations.create(task_identifier)
104+
105+
106+
@tasks_comments_blueprint.get('/<int:identifier>')
107+
@ac_api_requires()
108+
def get_task_comment(task_identifier, identifier):
109+
return comments_operations.read(task_identifier, identifier)

source/app/business/comments.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@
4040
from app.datamgmt.case.case_tasks_db import add_comment_to_task
4141
from app.datamgmt.case.case_events_db import add_comment_to_event
4242
from app.datamgmt.case.case_assets_db import get_case_asset_comment
43+
from app.datamgmt.case.case_rfiles_db import get_case_evidence_comment
44+
from app.datamgmt.case.case_iocs_db import get_case_ioc_comment
45+
from app.datamgmt.case.case_notes_db import get_case_note_comment
46+
from app.datamgmt.case.case_tasks_db import get_case_task_comment
47+
from app.datamgmt.case.case_events_db import get_case_event_comment
48+
from app.datamgmt.case.case_events_db import get_case_event_comment
4349
from app.iris_engine.module_handler.module_handler import call_modules_hook
4450
from app.iris_engine.utils.tracker import track_activity
4551
from app.models.comments import Comments
@@ -246,3 +252,38 @@ def comments_get_for_asset(asset: CaseAssets, identifier) -> Comments:
246252
if comment is None:
247253
raise ObjectNotFoundError
248254
return comment
255+
256+
257+
def comments_get_for_evidence(evidence: CaseReceivedFile, identifier) -> Comments:
258+
comment = get_case_evidence_comment(evidence.id, identifier)
259+
if comment is None:
260+
raise ObjectNotFoundError
261+
return comment
262+
263+
264+
def comments_get_for_ioc(ioc: Ioc, identifier) -> Comments:
265+
comment = get_case_ioc_comment(ioc.ioc_id, identifier)
266+
if comment is None:
267+
raise ObjectNotFoundError
268+
return comment
269+
270+
271+
def comments_get_for_note(note: Notes, identifier) -> Comments:
272+
comment = get_case_note_comment(note.note_id, identifier)
273+
if comment is None:
274+
raise ObjectNotFoundError
275+
return comment
276+
277+
278+
def comments_get_for_task(task: CaseTasks, identifier) -> Comments:
279+
comment = get_case_task_comment(task.id, identifier)
280+
if comment is None:
281+
raise ObjectNotFoundError
282+
return comment
283+
284+
285+
def comments_get_for_event(event: CasesEvent, identifier) -> Comments:
286+
comment = get_case_event_comment(event.event_id, identifier)
287+
if comment is None:
288+
raise ObjectNotFoundError
289+
return comment

tests/tests_rest_comments.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,3 +514,58 @@ def test_get_assets_comment_should_return_200(self):
514514

515515
response = self._subject.get(f'/api/v2/assets/{object_identifier}/comments/{identifier}', {})
516516
self.assertEqual(200, response.status_code)
517+
518+
def test_get_evidences_comment_should_return_200(self):
519+
case_identifier = self._subject.create_dummy_case()
520+
body = {'filename': 'filename'}
521+
response = self._subject.create(f'/api/v2/cases/{case_identifier}/evidences', body).json()
522+
object_identifier = response['id']
523+
response = self._subject.create(f'/api/v2/evidences/{object_identifier}/comments', {}).json()
524+
identifier = response['comment_id']
525+
response = self._subject.get(f'/api/v2/evidences/{object_identifier}/comments/{identifier}', {})
526+
self.assertEqual(200, response.status_code)
527+
528+
def test_get_iocs_comment_should_return_200(self):
529+
case_identifier = self._subject.create_dummy_case()
530+
body = {'ioc_type_id': 1, 'ioc_tlp_id': 2, 'ioc_value': '8.8.8.8', 'ioc_description': 'rewrw', 'ioc_tags': ''}
531+
response = self._subject.create(f'/api/v2/cases/{case_identifier}/iocs', body).json()
532+
object_identifier = response['ioc_id']
533+
response = self._subject.create(f'/api/v2/iocs/{object_identifier}/comments', {}).json()
534+
identifier = response['comment_id']
535+
response = self._subject.get(f'/api/v2/iocs/{object_identifier}/comments/{identifier}', {})
536+
self.assertEqual(200, response.status_code)
537+
538+
def test_get_notes_comment_should_return_200(self):
539+
case_identifier = self._subject.create_dummy_case()
540+
response = self._subject.create(f'/api/v2/cases/{case_identifier}/notes-directories',
541+
{'name': 'directory_name'}).json()
542+
directory_identifier = response['id']
543+
body = {'directory_id': directory_identifier}
544+
response = self._subject.create(f'/api/v2/cases/{case_identifier}/notes', body).json()
545+
object_identifier = response['note_id']
546+
response = self._subject.create(f'/api/v2/notes/{object_identifier}/comments', {}).json()
547+
identifier = response['comment_id']
548+
response = self._subject.get(f'/api/v2/notes/{object_identifier}/comments/{identifier}', {})
549+
self.assertEqual(200, response.status_code)
550+
551+
def test_get_tasks_comment_should_return_200(self):
552+
case_identifier = self._subject.create_dummy_case()
553+
body = {'task_assignees_id': [], 'task_status_id': 1, 'task_title': 'dummy title'}
554+
response = self._subject.create(f'/api/v2/cases/{case_identifier}/tasks', body).json()
555+
object_identifier = response['id']
556+
response = self._subject.create(f'/api/v2/tasks/{object_identifier}/comments', {}).json()
557+
identifier = response['comment_id']
558+
response = self._subject.get(f'/api/v2/tasks/{object_identifier}/comments/{identifier}', {})
559+
self.assertEqual(200, response.status_code)
560+
561+
def test_get_events_comment_should_return_200(self):
562+
case_identifier = self._subject.create_dummy_case()
563+
body = {'event_title': 'title', 'event_category_id': 1,
564+
'event_date': '2025-03-26T00:00:00.000', 'event_tz': '+00:00',
565+
'event_assets': [], 'event_iocs': []}
566+
response = self._subject.create(f'/api/v2/cases/{case_identifier}/events', body).json()
567+
object_identifier = response['event_id']
568+
response = self._subject.create(f'/api/v2/events/{object_identifier}/comments', {}).json()
569+
identifier = response['comment_id']
570+
response = self._subject.get(f'/api/v2/events/{object_identifier}/comments/{identifier}', {})
571+
self.assertEqual(200, response.status_code)

0 commit comments

Comments
 (0)