list dfir-iris users and assign user to alert (#53)
* list dfir-iris users and assign user to alert * precommit fixes
taylor_socfortress committed
Jul 19, 2023 at 10:13 UTC
fd89739e31bc8f66bb5d95320b199b7796348f5c
4 files changed
+282
backend/app/routes/dfir_iris.py
+31
@@ -5,6 +5,7 @@ from app.services.DFIR_IRIS.alerts import IRISAlertsService
5
from app.services.DFIR_IRIS.assets import AssetsService
6
from app.services.DFIR_IRIS.cases import CasesService
7
from app.services.DFIR_IRIS.notes import NotesService
8
+from app.services.DFIR_IRIS.users import IRISUsersService
9
10
bp = Blueprint("dfir_iris", __name__)
11
@@ -103,3 +104,33 @@ def get_alerts():
104
service = IRISAlertsService()
105
alerts = service.list_alerts()
106
return alerts
107
+
108
+
109
+@bp.route("/dfir_iris/users", methods=["GET"])
110
+def get_users():
111
+ """
112
+ Handle GET requests at the "/users" endpoint. Retrieve all users from DFIR IRIS.
113
+
114
+ Returns:
115
+ Response: A Flask Response object carrying a JSON representation of the list of users.
116
+ """
117
+ service = IRISUsersService()
118
+ users = service.list_users()
119
+ return users
120
+
121
+
122
+@bp.route("/dfir_iris/users/assign/<alert_id>", methods=["POST"])
123
+def assign_user_to_alert(alert_id: str):
124
+ """
125
+ Handle POST requests at the "/alerts/<alert_id>/assign" endpoint. Assign a user to an alert in DFIR IRIS.
126
+
127
+ Args:
128
+ alert_id (str): The ID of the alert to assign a user to.
129
+
130
+ Returns:
131
+ Response: A Flask Response object carrying a JSON representation of the result of the user assignment operation.
132
+ """
133
+ alert_owner_id = request.json["alert_owner_id"]
134
+ service = IRISUsersService()
135
+ assigned_user = service.assign_user_alert(alert_id=alert_id, alert_owner_id=alert_owner_id)
136
+ return assigned_user
backend/app/services/DFIR_IRIS/users.py
new
+115
@@ -0,0 +1,115 @@
1
+from typing import Dict
2
+
3
+from dfir_iris_client.alert import Alert
4
+
5
+# import requests
6
+from dfir_iris_client.users import User
7
+
8
+# from dfir_iris_client.helper.utils import assert_api_resp
9
+# from dfir_iris_client.helper.utils import get_data_from_resp
10
+# from dfir_iris_client.session import ClientSession
11
+from loguru import logger
12
+
13
+from app.services.DFIR_IRIS.universal import UniversalService
14
+
15
+
16
+class IRISUsersService:
17
+ """
18
+ A service class that encapsulates the logic for pulling and managing users from DFIR-IRIS. This class handles
19
+ fetching and creating users. It creates a DFIR-IRIS session upon initialization and uses it to interact with
20
+ the DFIR-IRIS users.
21
+ """
22
+
23
+ def __init__(self):
24
+ """
25
+ Initializes the IRISUsersService by creating a UniversalService object for "DFIR-IRIS" and establishing a session.
26
+ If the session creation is unsuccessful, an error is logged and the iris_session attribute is set to None.
27
+ """
28
+ self.universal_service = UniversalService("DFIR-IRIS")
29
+ session_result = self.universal_service.create_session()
30
+
31
+ if not session_result["success"]:
32
+ logger.error(session_result["message"])
33
+ self.iris_session = None
34
+ else:
35
+ self.iris_session = session_result["session"]
36
+
37
+ def list_users(self) -> Dict[str, object]:
38
+ """
39
+ Retrieves the list of users from DFIR-IRIS. If the iris_session attribute is None, this indicates
40
+ that the session creation was unsuccessful, and a dictionary with "success" set to False is returned. Otherwise,
41
+ it attempts to fetch and parse the user data.
42
+
43
+ Returns:
44
+ dict: A dictionary containing the success status, a message, and potentially the fetched users. The
45
+ "success" key is a boolean indicating whether the operation was successful. The "message" key is a string
46
+ providing details about the operation. If "success" is True, the dictionary also contains the "data" key
47
+ with the fetched users.
48
+ """
49
+ if self.iris_session is None:
50
+ return {
51
+ "success": False,
52
+ "message": "DFIR-IRIS session was not successfully created.",
53
+ }
54
+
55
+ logger.info("Collecting users from DFIR-IRIS")
56
+ user = User(session=self.iris_session)
57
+ result = self.universal_service.fetch_and_parse_data(
58
+ self.iris_session,
59
+ user.list_users,
60
+ )
61
+
62
+ if not result["success"]:
63
+ return {
64
+ "success": False,
65
+ "message": "Failed to collect users from DFIR-IRIS",
66
+ }
67
+
68
+ return {
69
+ "success": True,
70
+ "message": "Successfully collected users from DFIR-IRIS",
71
+ "users": result["data"],
72
+ }
73
+
74
+ def assign_user_alert(self, alert_id: str, alert_owner_id: int) -> Dict[str, object]:
75
+ """
76
+ Assigns a user to an alert in DFIR-IRIS. If the iris_session attribute is None, this indicates
77
+ that the session creation was unsuccessful, and a dictionary with "success" set to False is returned. Otherwise,
78
+ it attempts to assign a user to an alert.
79
+
80
+ Args:
81
+ alert_id (str): The ID of the alert to assign a user to.
82
+ alert_owner_id (int): The ID of the user to assign to the alert.
83
+
84
+ Returns:
85
+ dict: A dictionary containing the success status, a message, and potentially the assigned user. The
86
+ "success" key is a boolean indicating whether the operation was successful. The "message" key is a string
87
+ providing details about the operation. If "success" is True, the dictionary also contains the "data" key
88
+ with the assigned user.
89
+ """
90
+ if self.iris_session is None:
91
+ return {
92
+ "success": False,
93
+ "message": "DFIR-IRIS session was not successfully created.",
94
+ }
95
+
96
+ logger.info(f"Assigning user with user id {alert_owner_id} to alert {alert_id} in DFIR-IRIS")
97
+ alert = Alert(session=self.iris_session)
98
+ result = self.universal_service.fetch_and_parse_data(
99
+ self.iris_session,
100
+ alert.update_alert,
101
+ alert_id,
102
+ {"alert_owner_id": alert_owner_id},
103
+ )
104
+
105
+ if not result["success"]:
106
+ return {
107
+ "success": False,
108
+ "message": "Failed to assign user to alert in DFIR-IRIS",
109
+ }
110
+
111
+ return {
112
+ "success": True,
113
+ "message": "Successfully assigned user to alert in DFIR-IRIS",
114
+ "user": result["data"],
115
+ }
backend/app/static/swagger.json
+102
@@ -2364,6 +2364,108 @@
2364
"tags": ["DFIR Iris"]
2365
}
2366
},
2367
+ "/dfir_iris/users": {
2368
+ "get": {
2369
+ "summary": "Get all users",
2370
+ "description": "Endpoint to get all users.",
2371
+ "responses": {
2372
+ "200": {
2373
+ "description": "Successful operation",
2374
+ "content": {
2375
+ "application/json": {
2376
+ "schema": {
2377
+ "type": "object",
2378
+ "properties": {
2379
+ "users": {
2380
+ "type": "array",
2381
+ "items": {
2382
+ "type": "object",
2383
+ "description": "User details"
2384
+ }
2385
+ }
2386
+ }
2387
+ }
2388
+ }
2389
+ }
2390
+ },
2391
+ "default": {
2392
+ "description": "Unexpected error",
2393
+ "content": {
2394
+ "application/json": {
2395
+ "schema": {
2396
+ "$ref": "#/components/schemas/Error"
2397
+ }
2398
+ }
2399
+ }
2400
+ }
2401
+ },
2402
+ "operationId": "getAllUsers",
2403
+ "tags": ["DFIR Iris"]
2404
+ }
2405
+ },
2406
+ "/dfir_iris/users/assign/{alert_id}": {
2407
+ "post": {
2408
+ "summary": "Assign a user to a DFIR-IRIS Alert",
2409
+ "description": "Assign a user to a DFIR-IRIS Alert.",
2410
+ "parameters": [
2411
+ {
2412
+ "name": "alert_id",
2413
+ "in": "path",
2414
+ "description": "ID of the alert to assign.",
2415
+ "required": true,
2416
+ "schema": {
2417
+ "type": "string"
2418
+ }
2419
+ }
2420
+ ],
2421
+ "requestBody": {
2422
+ "description": "Assignee details",
2423
+ "content": {
2424
+ "application/json": {
2425
+ "schema": {
2426
+ "type": "object",
2427
+ "properties": {
2428
+ "alert_owner_id": {
2429
+ "type": "integer",
2430
+ "description": "The owner id of who to assign the alert to. Invoke the `/dfir_iris/users` to obtain the owner id."
2431
+ }
2432
+ }
2433
+ }
2434
+ }
2435
+ }
2436
+ },
2437
+ "responses": {
2438
+ "200": {
2439
+ "description": "Successful operation",
2440
+ "content": {
2441
+ "application/json": {
2442
+ "schema": {
2443
+ "type": "object",
2444
+ "properties": {
2445
+ "output": {
2446
+ "type": "string",
2447
+ "description": "The output of the command."
2448
+ }
2449
+ }
2450
+ }
2451
+ }
2452
+ }
2453
+ },
2454
+ "default": {
2455
+ "description": "Unexpected error",
2456
+ "content": {
2457
+ "application/json": {
2458
+ "schema": {
2459
+ "$ref": "#/components/schemas/Error"
2460
+ }
2461
+ }
2462
+ }
2463
+ }
2464
+ },
2465
+ "operationId": "assignUserToAlert",
2466
+ "tags": ["DFIR Iris"]
2467
+ }
2468
+ },
2469
"/sublime/alerts": {
2470
"get": {
2471
"summary": "Get all alerts",
backend/docs/dfiriris.md
+34
@@ -178,6 +178,40 @@ This file serves as a core component in managing case notes in DFIR-IRIS, provid
178
::: app.services.DFIR_IRIS.notes
179
<br>
180
181
+### <span style="color:red">Users Services</span>
182
+
183
+## Python Script: users.py
184
+
185
+This script is responsible for managing user interactions in DFIR-IRIS.
186
+
187
+### Import Statements
188
+
189
+The script begins by importing necessary modules and classes:
190
+
191
+- `typing`: For specifying type hints in function signatures.
192
+- `User` and `Alert` classes from the `dfir_iris_client` package: These classes likely encapsulate the data and behavior associated with users and alerts in DFIR-IRIS.
193
+- `loguru`: A third-party logging module to log messages, here used for error and info level logging.
194
+- `UniversalService` class from `app.services.DFIR_IRIS.universal`: This class is used to create a session with DFIR-IRIS and fetch/parse data from it.
195
+
196
+### IRISUsersService Class
197
+
198
+The `IRISUsersService` class encapsulates the logic for managing users in DFIR-IRIS.
199
+
200
+#### **init** method
201
+
202
+This method initializes an instance of the `IRISUsersService` class. It creates an instance of the `UniversalService` class for "DFIR-IRIS" and attempts to establish a session with DFIR-IRIS. If the session creation is successful, the session is stored in the `iris_session` attribute of the `IRISUsersService` instance. If the session creation is not successful, an error message is logged, and `iris_session` is set to `None`.
203
+
204
+#### list_users method
205
+
206
+This method retrieves the list of users from DFIR-IRIS. If `iris_session` is `None` (indicating unsuccessful session creation), it returns a dictionary with "success" set to `False`. If a session exists, it uses the `User` class from the `dfir_iris_client` package to fetch and parse the user data from DFIR-IRIS. The result is a dictionary containing information about the success of the operation, a message describing the operation, and (if the operation was successful) the fetched users.
207
+
208
+#### assign_user_alert method
209
+
210
+This method assigns a user to an alert in DFIR-IRIS. Similar to `list_users`, it checks if `iris_session` is `None` and returns a failure message if it is. If a session exists, it uses the `Alert` class from the `dfir_iris_client` package to assign a user to an alert. The user and alert are identified by their IDs, which are passed as arguments to the method. The result is a dictionary containing information about the success of the operation, a message describing the operation, and (if the operation was successful) the assigned user.
211
+
212
+::: app.services.DFIR_IRIS.users
213
+<br>
214
+
215
### <span style="color:red">Universal Services</span>
216
217
::: app.services.DFIR_IRIS.universal