retrieve cases still open longer than 24 hours (#75)
taylor_socfortress committed
Jul 26, 2023 at 14:50 UTC
b1e3f983cb4e4fec1ad3f57f696da5b66091b46e
3 files changed
+104
backend/app/routes/dfir_iris.py
+21
@@ -1,4 +1,5 @@
1
from flask import Blueprint
2
+from flask import jsonify
3
from flask import request
4
5
from app.services.DFIR_IRIS.alerts import IRISAlertsService
@@ -23,6 +24,26 @@ def get_cases():
24
return cases
25
26
27
+@bp.route("/dfir_iris/cases/kpi", methods=["GET"])
28
+def get_cases_kpi():
29
+ """
30
+ Handle GET requests at the "/cases" endpoint. Retrieve all cases from DFIR IRIS and calculate their KPI.
31
+
32
+ Currently supports collecting cases older than 24 hours that are still open.
33
+
34
+ Returns:
35
+ Response: A Flask Response object carrying a JSON representation of the list of cases.
36
+ """
37
+ service = CasesService()
38
+ result = service.list_cases()
39
+
40
+ if not result["success"]:
41
+ return jsonify(result), 500
42
+
43
+ cases = service.calculate_kpis(result["cases"])
44
+ return jsonify({"cases": cases}), 200
45
+
46
+
47
@bp.route("/dfir_iris/cases/<case_id>", methods=["GET"])
48
def get_case(case_id: str):
49
"""
backend/app/services/DFIR_IRIS/cases.py
+44
@@ -1,3 +1,4 @@
1
+from datetime import datetime
2
from typing import Dict
3
4
# import requests
@@ -58,6 +59,49 @@ class CasesService:
59
"cases": result["data"],
60
}
61
62
+ def calculate_kpis(self, cases):
63
+ """
64
+ Calculate KPIs for a list of cases and return only those that have breached.
65
+
66
+ Args:
67
+ cases (List[Dict]): The list of cases to calculate KPIs for.
68
+
69
+ Returns:
70
+ Dict: A dictionary containing the success status, a message, and the cases that have breached KPIs.
71
+ """
72
+ try:
73
+ cases_breached = [case for case in cases if self._is_kpi_breached(case)]
74
+ return {"success": True, "message": "Successfully calculated KPIs.", "cases_breached": cases_breached}
75
+ except Exception as e:
76
+ return {"success": False, "message": f"Failed to calculate KPIs: {e}"}
77
+
78
+ def _is_kpi_breached(self, case):
79
+ """
80
+ Check if a case's KPI is breached. A case is breached if it is older than 24 hours and still open.
81
+
82
+ Args:
83
+ case (Dict): The case to check.
84
+
85
+ Returns:
86
+ bool: True if the KPI is breached, False otherwise.
87
+ """
88
+ # Check if the `case_close_date` is empty and `case_open_date` is not
89
+ if case["case_close_date"] == "" and case["case_open_date"] != "":
90
+ # Get the current date
91
+ current_date = datetime.now()
92
+ # Get the case open date
93
+ case_open_date = datetime.strptime(case["case_open_date"], "%m/%d/%Y")
94
+ # Calculate the difference between the current date and the case open date
95
+ difference = current_date - case_open_date
96
+ # Convert the difference to days
97
+ difference = difference.days
98
+ # Check if the difference is greater than 1 day
99
+ if difference > 1:
100
+ # Set the KPI to True
101
+ case["kpi_breached"] = True
102
+ return True
103
+ return False
104
+
105
def get_case(self, case_id: int) -> bool:
106
"""
107
Gets a case from DFIR-IRIS and returns all the details
backend/app/static/swagger.json
+39
@@ -3022,6 +3022,45 @@
3022
"tags": ["DFIR Iris"]
3023
}
3024
},
3025
+ "/dfir_iris/cases/kpi": {
3026
+ "get": {
3027
+ "summary": "Get KPIs for all cases",
3028
+ "description": "Endpoint to get KPIs for all cases.",
3029
+ "responses": {
3030
+ "200": {
3031
+ "description": "Successful operation",
3032
+ "content": {
3033
+ "application/json": {
3034
+ "schema": {
3035
+ "type": "object",
3036
+ "properties": {
3037
+ "cases": {
3038
+ "type": "array",
3039
+ "items": {
3040
+ "type": "object",
3041
+ "description": "Case details"
3042
+ }
3043
+ }
3044
+ }
3045
+ }
3046
+ }
3047
+ }
3048
+ },
3049
+ "default": {
3050
+ "description": "Unexpected error",
3051
+ "content": {
3052
+ "application/json": {
3053
+ "schema": {
3054
+ "$ref": "#/components/schemas/Error"
3055
+ }
3056
+ }
3057
+ }
3058
+ }
3059
+ },
3060
+ "operationId": "getKPIsForAllCases",
3061
+ "tags": ["DFIR Iris"]
3062
+ }
3063
+ },
3064
"/dfir_iris/cases/{case_id}": {
3065
"get": {
3066
"summary": "Get a case",