No Description

__init__.py 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. # IRIS Source Code
  2. # Copyright (C) 2024 - DFIR-IRIS
  3. # contact@dfir-iris.org
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU Lesser General Public
  7. # License as published by the Free Software Foundation; either
  8. # version 3 of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with this program; if not, write to the Free Software Foundation,
  17. # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. from flask import Blueprint
  19. from flask import request
  20. from flask_login import current_user
  21. from werkzeug import Response
  22. from app.blueprints.rest.parsing import parse_comma_separated_identifiers
  23. from app.blueprints.rest.parsing import parse_boolean
  24. from app.blueprints.rest.endpoints import response_api_success
  25. from app.blueprints.rest.endpoints import response_api_deleted
  26. from app.blueprints.rest.endpoints import response_api_not_found
  27. from app.blueprints.rest.endpoints import response_api_created
  28. from app.blueprints.rest.endpoints import response_api_error
  29. from app.blueprints.rest.endpoints import response_api_paginated
  30. from app.blueprints.rest.parsing import parse_pagination_parameters
  31. from app.blueprints.rest.v2.cases.assets import case_assets_blueprint
  32. from app.blueprints.rest.v2.cases.iocs import case_iocs_blueprint
  33. from app.blueprints.rest.v2.cases.tasks import case_tasks_blueprint
  34. from app.business.cases import cases_create
  35. from app.business.cases import cases_delete
  36. from app.datamgmt.case.case_db import get_case
  37. from app.business.cases import cases_update
  38. from app.business.errors import BusinessProcessingError
  39. from app.datamgmt.manage.manage_cases_db import get_filtered_cases
  40. from app.schema.marshables import CaseSchemaForAPIV2
  41. from app.blueprints.access_controls import ac_api_requires
  42. from app.iris_engine.access_control.utils import ac_fast_check_current_user_has_case_access
  43. from app.blueprints.access_controls import ac_api_return_access_denied
  44. from app.models.authorization import Permissions
  45. from app.models.authorization import CaseAccessLevel
  46. # Create blueprint & import child blueprints
  47. cases_blueprint = Blueprint('cases',
  48. __name__,
  49. url_prefix='/cases')
  50. cases_blueprint.register_blueprint(case_assets_blueprint)
  51. cases_blueprint.register_blueprint(case_iocs_blueprint)
  52. cases_blueprint.register_blueprint(case_tasks_blueprint)
  53. # Routes
  54. @cases_blueprint.post('')
  55. @ac_api_requires(Permissions.standard_user)
  56. def create_case():
  57. """
  58. Handles creating a new case.
  59. """
  60. try:
  61. case = cases_create(request.get_json())
  62. return response_api_created(CaseSchemaForAPIV2().dump(case))
  63. except BusinessProcessingError as e:
  64. return response_api_error(e.get_message(), e.get_data())
  65. @cases_blueprint.get('')
  66. @ac_api_requires()
  67. def get_cases() -> Response:
  68. """
  69. Handles getting cases, with optional filtering & pagination
  70. """
  71. pagination_parameters = parse_pagination_parameters(request)
  72. case_ids_str = request.args.get('case_ids', None, type=parse_comma_separated_identifiers)
  73. case_customer_id = request.args.get('case_customer_id', None, type=str)
  74. case_name = request.args.get('case_name', None, type=str)
  75. case_description = request.args.get('case_description', None, type=str)
  76. case_classification_id = request.args.get(
  77. 'case_classification_id', None, type=int)
  78. case_owner_id = request.args.get('case_owner_id', None, type=int)
  79. case_opening_user_id = request.args.get(
  80. 'case_opening_user_id', None, type=int)
  81. case_severity_id = request.args.get('case_severity_id', None, type=int)
  82. case_state_id = request.args.get('case_state_id', None, type=int)
  83. case_soc_id = request.args.get('case_soc_id', None, type=str)
  84. start_open_date = request.args.get('start_open_date', None, type=str)
  85. end_open_date = request.args.get('end_open_date', None, type=str)
  86. is_open = request.args.get('is_open', None, type=parse_boolean)
  87. filtered_cases = get_filtered_cases(
  88. current_user.id,
  89. pagination_parameters,
  90. case_ids=case_ids_str,
  91. case_customer_id=case_customer_id,
  92. case_name=case_name,
  93. case_description=case_description,
  94. case_classification_id=case_classification_id,
  95. case_owner_id=case_owner_id,
  96. case_opening_user_id=case_opening_user_id,
  97. case_severity_id=case_severity_id,
  98. case_state_id=case_state_id,
  99. case_soc_id=case_soc_id,
  100. start_open_date=start_open_date,
  101. end_open_date=end_open_date,
  102. search_value='',
  103. is_open=is_open
  104. )
  105. if filtered_cases is None:
  106. return response_api_error('Filtering error')
  107. case_schema = CaseSchemaForAPIV2()
  108. return response_api_paginated(case_schema, filtered_cases)
  109. @cases_blueprint.get('/<int:identifier>')
  110. @ac_api_requires()
  111. def case_routes_get(identifier):
  112. """
  113. Get a case by its ID
  114. """
  115. case = get_case(identifier)
  116. if not case:
  117. return response_api_not_found()
  118. if not ac_fast_check_current_user_has_case_access(identifier, [CaseAccessLevel.read_only, CaseAccessLevel.full_access]):
  119. return ac_api_return_access_denied(caseid=identifier)
  120. return response_api_success(CaseSchemaForAPIV2().dump(case))
  121. @cases_blueprint.put('/<int:identifier>')
  122. @ac_api_requires(Permissions.standard_user)
  123. def rest_v2_cases_update(identifier):
  124. if not ac_fast_check_current_user_has_case_access(identifier, [CaseAccessLevel.full_access]):
  125. return ac_api_return_access_denied(caseid=identifier)
  126. try:
  127. case, _ = cases_update(identifier, request.get_json())
  128. return response_api_success(CaseSchemaForAPIV2().dump(case))
  129. except BusinessProcessingError as e:
  130. return response_api_error(e.get_message(), e.get_data())
  131. @cases_blueprint.delete('/<int:identifier>')
  132. @ac_api_requires(Permissions.standard_user)
  133. def case_routes_delete(identifier):
  134. """
  135. Delete a case by ID
  136. """
  137. if not ac_fast_check_current_user_has_case_access(identifier, [CaseAccessLevel.full_access]):
  138. return ac_api_return_access_denied(caseid=identifier)
  139. try:
  140. cases_delete(identifier)
  141. return response_api_deleted()
  142. except BusinessProcessingError as e:
  143. return response_api_error(e.get_message(), e.get_data())