binalyze-air-sdk 1.0.2__py3-none-any.whl → 1.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. binalyze_air/__init__.py +77 -77
  2. binalyze_air/apis/__init__.py +67 -27
  3. binalyze_air/apis/acquisitions.py +107 -0
  4. binalyze_air/apis/api_tokens.py +49 -0
  5. binalyze_air/apis/assets.py +161 -0
  6. binalyze_air/apis/audit_logs.py +26 -0
  7. binalyze_air/apis/{authentication.py → auth.py} +29 -27
  8. binalyze_air/apis/auto_asset_tags.py +79 -75
  9. binalyze_air/apis/backup.py +177 -0
  10. binalyze_air/apis/baseline.py +46 -0
  11. binalyze_air/apis/cases.py +225 -0
  12. binalyze_air/apis/cloud_forensics.py +116 -0
  13. binalyze_air/apis/event_subscription.py +96 -96
  14. binalyze_air/apis/evidence.py +249 -53
  15. binalyze_air/apis/interact.py +153 -36
  16. binalyze_air/apis/investigation_hub.py +234 -0
  17. binalyze_air/apis/license.py +104 -0
  18. binalyze_air/apis/logger.py +83 -0
  19. binalyze_air/apis/multipart_upload.py +201 -0
  20. binalyze_air/apis/notifications.py +115 -0
  21. binalyze_air/apis/organizations.py +267 -0
  22. binalyze_air/apis/params.py +44 -39
  23. binalyze_air/apis/policies.py +186 -0
  24. binalyze_air/apis/preset_filters.py +79 -0
  25. binalyze_air/apis/recent_activities.py +71 -0
  26. binalyze_air/apis/relay_server.py +104 -0
  27. binalyze_air/apis/settings.py +395 -27
  28. binalyze_air/apis/tasks.py +80 -0
  29. binalyze_air/apis/triage.py +197 -0
  30. binalyze_air/apis/user_management.py +183 -74
  31. binalyze_air/apis/webhook_executions.py +50 -0
  32. binalyze_air/apis/webhooks.py +322 -230
  33. binalyze_air/base.py +207 -133
  34. binalyze_air/client.py +217 -1337
  35. binalyze_air/commands/__init__.py +175 -145
  36. binalyze_air/commands/acquisitions.py +661 -387
  37. binalyze_air/commands/api_tokens.py +55 -0
  38. binalyze_air/commands/assets.py +324 -362
  39. binalyze_air/commands/{authentication.py → auth.py} +36 -36
  40. binalyze_air/commands/auto_asset_tags.py +230 -230
  41. binalyze_air/commands/backup.py +47 -0
  42. binalyze_air/commands/baseline.py +32 -396
  43. binalyze_air/commands/cases.py +609 -602
  44. binalyze_air/commands/cloud_forensics.py +88 -0
  45. binalyze_air/commands/event_subscription.py +101 -101
  46. binalyze_air/commands/evidences.py +918 -988
  47. binalyze_air/commands/interact.py +172 -58
  48. binalyze_air/commands/investigation_hub.py +315 -0
  49. binalyze_air/commands/license.py +183 -0
  50. binalyze_air/commands/logger.py +126 -0
  51. binalyze_air/commands/multipart_upload.py +363 -0
  52. binalyze_air/commands/notifications.py +45 -0
  53. binalyze_air/commands/organizations.py +200 -221
  54. binalyze_air/commands/policies.py +175 -203
  55. binalyze_air/commands/preset_filters.py +55 -0
  56. binalyze_air/commands/recent_activities.py +32 -0
  57. binalyze_air/commands/relay_server.py +144 -0
  58. binalyze_air/commands/settings.py +431 -29
  59. binalyze_air/commands/tasks.py +95 -56
  60. binalyze_air/commands/triage.py +224 -360
  61. binalyze_air/commands/user_management.py +351 -126
  62. binalyze_air/commands/webhook_executions.py +77 -0
  63. binalyze_air/config.py +244 -244
  64. binalyze_air/exceptions.py +49 -49
  65. binalyze_air/http_client.py +426 -305
  66. binalyze_air/models/__init__.py +287 -285
  67. binalyze_air/models/acquisitions.py +365 -250
  68. binalyze_air/models/api_tokens.py +73 -0
  69. binalyze_air/models/assets.py +438 -438
  70. binalyze_air/models/audit.py +247 -272
  71. binalyze_air/models/audit_logs.py +14 -0
  72. binalyze_air/models/{authentication.py → auth.py} +69 -69
  73. binalyze_air/models/auto_asset_tags.py +227 -116
  74. binalyze_air/models/backup.py +138 -0
  75. binalyze_air/models/baseline.py +231 -231
  76. binalyze_air/models/cases.py +275 -275
  77. binalyze_air/models/cloud_forensics.py +145 -0
  78. binalyze_air/models/event_subscription.py +170 -171
  79. binalyze_air/models/evidence.py +65 -65
  80. binalyze_air/models/evidences.py +367 -348
  81. binalyze_air/models/interact.py +266 -135
  82. binalyze_air/models/investigation_hub.py +265 -0
  83. binalyze_air/models/license.py +150 -0
  84. binalyze_air/models/logger.py +83 -0
  85. binalyze_air/models/multipart_upload.py +352 -0
  86. binalyze_air/models/notifications.py +138 -0
  87. binalyze_air/models/organizations.py +293 -293
  88. binalyze_air/models/params.py +153 -127
  89. binalyze_air/models/policies.py +260 -249
  90. binalyze_air/models/preset_filters.py +79 -0
  91. binalyze_air/models/recent_activities.py +70 -0
  92. binalyze_air/models/relay_server.py +121 -0
  93. binalyze_air/models/settings.py +538 -84
  94. binalyze_air/models/tasks.py +215 -149
  95. binalyze_air/models/triage.py +141 -142
  96. binalyze_air/models/user_management.py +200 -97
  97. binalyze_air/models/webhook_executions.py +33 -0
  98. binalyze_air/queries/__init__.py +121 -133
  99. binalyze_air/queries/acquisitions.py +155 -155
  100. binalyze_air/queries/api_tokens.py +46 -0
  101. binalyze_air/queries/assets.py +186 -105
  102. binalyze_air/queries/audit.py +400 -416
  103. binalyze_air/queries/{authentication.py → auth.py} +55 -55
  104. binalyze_air/queries/auto_asset_tags.py +59 -59
  105. binalyze_air/queries/backup.py +66 -0
  106. binalyze_air/queries/baseline.py +21 -185
  107. binalyze_air/queries/cases.py +292 -292
  108. binalyze_air/queries/cloud_forensics.py +137 -0
  109. binalyze_air/queries/event_subscription.py +54 -54
  110. binalyze_air/queries/evidence.py +139 -139
  111. binalyze_air/queries/evidences.py +279 -279
  112. binalyze_air/queries/interact.py +140 -28
  113. binalyze_air/queries/investigation_hub.py +329 -0
  114. binalyze_air/queries/license.py +85 -0
  115. binalyze_air/queries/logger.py +58 -0
  116. binalyze_air/queries/multipart_upload.py +180 -0
  117. binalyze_air/queries/notifications.py +71 -0
  118. binalyze_air/queries/organizations.py +222 -222
  119. binalyze_air/queries/params.py +154 -115
  120. binalyze_air/queries/policies.py +149 -149
  121. binalyze_air/queries/preset_filters.py +60 -0
  122. binalyze_air/queries/recent_activities.py +44 -0
  123. binalyze_air/queries/relay_server.py +42 -0
  124. binalyze_air/queries/settings.py +533 -20
  125. binalyze_air/queries/tasks.py +125 -81
  126. binalyze_air/queries/triage.py +230 -230
  127. binalyze_air/queries/user_management.py +193 -83
  128. binalyze_air/queries/webhook_executions.py +39 -0
  129. binalyze_air_sdk-1.0.3.dist-info/METADATA +752 -0
  130. binalyze_air_sdk-1.0.3.dist-info/RECORD +132 -0
  131. {binalyze_air_sdk-1.0.2.dist-info → binalyze_air_sdk-1.0.3.dist-info}/WHEEL +1 -1
  132. binalyze_air/apis/endpoints.py +0 -22
  133. binalyze_air/apis/evidences.py +0 -216
  134. binalyze_air/apis/users.py +0 -68
  135. binalyze_air/commands/users.py +0 -101
  136. binalyze_air/models/endpoints.py +0 -76
  137. binalyze_air/models/users.py +0 -82
  138. binalyze_air/queries/endpoints.py +0 -25
  139. binalyze_air/queries/users.py +0 -69
  140. binalyze_air_sdk-1.0.2.dist-info/METADATA +0 -706
  141. binalyze_air_sdk-1.0.2.dist-info/RECORD +0 -82
  142. {binalyze_air_sdk-1.0.2.dist-info → binalyze_air_sdk-1.0.3.dist-info}/top_level.txt +0 -0
@@ -1,136 +1,267 @@
1
- """
2
- Interact API models for the Binalyze AIR SDK.
3
- """
4
-
5
- from typing import List, Optional, Dict, Any
6
- from datetime import datetime
7
- from enum import Enum
8
- from pydantic import Field
9
-
10
- from ..base import AIRBaseModel
11
-
12
-
13
- class SendToLocation(str, Enum):
14
- """Send to location options."""
15
- USER_LOCAL = "user-local"
16
- REPOSITORY = "repository"
17
- EVIDENCE_REPOSITORY = "evidence-repository"
18
-
19
-
20
- class TaskConfigChoice(str, Enum):
21
- """Task configuration choice options."""
22
- USE_POLICY = "use-policy"
23
- USE_CUSTOM_OPTIONS = "use-custom-options"
24
-
25
-
26
- class SendToConfig(AIRBaseModel):
27
- """Send to configuration model."""
28
-
29
- location: SendToLocation
30
- repository_id: Optional[str] = Field(default=None, alias="repositoryId")
31
- evidence_repository_id: Optional[str] = Field(default=None, alias="evidenceRepositoryId")
32
-
33
-
34
- class BandwidthConfig(AIRBaseModel):
35
- """Bandwidth configuration model."""
36
-
37
- limit: Optional[int] = None
38
-
39
-
40
- class DiskSpaceConfig(AIRBaseModel):
41
- """Disk space configuration model."""
42
-
43
- reserve: Optional[int] = None
44
-
45
-
46
- class TaskConfig(AIRBaseModel):
47
- """Task configuration model."""
48
-
49
- choice: TaskConfigChoice
50
- send_to: Optional[SendToConfig] = Field(default=None, alias="sendTo")
51
- bandwidth: Optional[BandwidthConfig] = None
52
- disk_space: Optional[DiskSpaceConfig] = Field(default=None, alias="diskSpace")
53
-
54
-
55
- class AssignInteractiveShellTaskRequest(AIRBaseModel):
56
- """Request model for assigning interactive shell task."""
57
-
58
- asset_id: str = Field(alias="assetId")
59
- case_id: str = Field(alias="caseId")
60
- task_config: TaskConfig = Field(alias="taskConfig")
61
-
62
-
63
- class InteractiveShellTaskResponse(AIRBaseModel):
64
- """Response model for interactive shell task assignment."""
65
-
66
- session_id: str = Field(alias="sessionId")
67
- idle_timeout: int = Field(alias="idleTimeout")
68
- config: TaskConfig
69
-
70
-
71
- # Legacy models for backward compatibility (deprecated)
72
- class InteractionType(str, Enum):
73
- """Interaction types."""
74
- SHELL = "shell"
75
- POWERSHELL = "powershell"
76
- CMD = "cmd"
77
- BASH = "bash"
78
-
79
-
80
- class InteractionStatus(str, Enum):
81
- """Interaction status."""
82
- PENDING = "pending"
83
- RUNNING = "running"
84
- COMPLETED = "completed"
85
- FAILED = "failed"
86
- CANCELLED = "cancelled"
87
- TIMEOUT = "timeout"
88
-
89
-
90
- class ShellInteraction(AIRBaseModel):
91
- """Shell interaction model (legacy)."""
92
-
93
- id: str
94
- task_id: str
95
- endpoint_id: str
96
- endpoint_name: str
97
- interaction_type: InteractionType
98
- command: str
99
- output: Optional[str] = None
100
- error_output: Optional[str] = None
101
- exit_code: Optional[int] = None
102
- status: InteractionStatus = InteractionStatus.PENDING
103
- timeout: int = 300 # seconds
104
- organization_id: int
105
- created_by: Optional[str] = None
106
- created_at: Optional[datetime] = None
107
- started_at: Optional[datetime] = None
108
- completed_at: Optional[datetime] = None
109
- duration: Optional[int] = None # seconds
110
- environment_variables: Optional[Dict[str, str]] = None
111
- working_directory: Optional[str] = None
112
-
113
-
114
- class AssignShellTaskRequest(AIRBaseModel):
115
- """Request model for assigning shell interaction tasks (legacy)."""
116
-
117
- endpoint_ids: List[str]
118
- command: str
119
- interaction_type: InteractionType = InteractionType.SHELL
120
- timeout: Optional[int] = 300
121
- organization_ids: Optional[List[int]] = None
122
- case_id: Optional[str] = None
123
- environment_variables: Optional[Dict[str, str]] = None
124
- working_directory: Optional[str] = None
125
- description: Optional[str] = None
126
-
127
-
128
- class ShellTaskResponse(AIRBaseModel):
129
- """Response model for shell task assignment (legacy)."""
130
-
131
- task_id: str
132
- endpoint_interactions: List[ShellInteraction]
133
- success_count: int
134
- failure_count: int
135
- total_count: int
1
+ """
2
+ Interact API models for the Binalyze AIR SDK.
3
+ """
4
+
5
+ from typing import List, Optional, Dict, Any
6
+ from datetime import datetime
7
+ from enum import Enum
8
+ from pydantic import Field
9
+
10
+ from ..base import AIRBaseModel
11
+
12
+
13
+ class SendToLocation(str, Enum):
14
+ """Send to location options."""
15
+ USER_LOCAL = "user-local"
16
+ REPOSITORY = "repository"
17
+ EVIDENCE_REPOSITORY = "evidence-repository"
18
+
19
+
20
+ class TaskConfigChoice(str, Enum):
21
+ """Task configuration choice options."""
22
+ USE_POLICY = "use-policy"
23
+ USE_CUSTOM_OPTIONS = "use-custom-options"
24
+
25
+
26
+ class SendToConfig(AIRBaseModel):
27
+ """Send to configuration model."""
28
+
29
+ location: SendToLocation
30
+ repository_id: Optional[str] = Field(default=None, alias="repositoryId")
31
+ evidence_repository_id: Optional[str] = Field(default=None, alias="evidenceRepositoryId")
32
+
33
+
34
+ class BandwidthConfig(AIRBaseModel):
35
+ """Bandwidth configuration model."""
36
+
37
+ limit: Optional[int] = None
38
+
39
+
40
+ class DiskSpaceConfig(AIRBaseModel):
41
+ """Disk space configuration model."""
42
+
43
+ reserve: Optional[int] = None
44
+
45
+
46
+ class TaskConfig(AIRBaseModel):
47
+ """Task configuration model."""
48
+
49
+ choice: TaskConfigChoice
50
+ send_to: Optional[SendToConfig] = Field(default=None, alias="sendTo")
51
+ bandwidth: Optional[BandwidthConfig] = None
52
+ disk_space: Optional[DiskSpaceConfig] = Field(default=None, alias="diskSpace")
53
+
54
+
55
+ class AssignInteractiveShellTaskRequest(AIRBaseModel):
56
+ """Request model for assigning interactive shell task."""
57
+
58
+ asset_id: str = Field(alias="assetId")
59
+ case_id: str = Field(alias="caseId")
60
+ task_config: TaskConfig = Field(alias="taskConfig")
61
+
62
+
63
+ class InteractiveShellTaskResponse(AIRBaseModel):
64
+ """Response model for interactive shell task assignment."""
65
+
66
+ session_id: str = Field(alias="sessionId")
67
+ idle_timeout: int = Field(alias="idleTimeout")
68
+ config: TaskConfig
69
+
70
+
71
+ # NEW MODELS FOR INTERACT API
72
+
73
+ class LibraryFile(AIRBaseModel):
74
+ """Library file model."""
75
+
76
+ id: str = Field(alias="_id")
77
+ name: str
78
+ organization_ids: List[int] = Field(alias="organizationIds")
79
+ size: int
80
+ sha256: str
81
+ uploaded_by: str = Field(alias="uploadedBy")
82
+ uploaded_at: datetime = Field(alias="uploadedAt")
83
+ last_used_at: Optional[datetime] = Field(default=None, alias="lastUsedAt")
84
+ last_used_by: Optional[str] = Field(default=None, alias="lastUsedBy")
85
+
86
+
87
+ class LibraryFileFilter(AIRBaseModel):
88
+ """Library file filter model."""
89
+
90
+ search_term: Optional[str] = Field(default=None, alias="searchTerm")
91
+ organization_ids: Optional[List[int]] = Field(default=None, alias="organizationIds")
92
+ name: Optional[str] = None
93
+ uploaded_by: Optional[str] = Field(default=None, alias="uploadedBy")
94
+ uploaded_at: Optional[str] = Field(default=None, alias="uploadedAt")
95
+
96
+ def to_params(self) -> Dict[str, Any]:
97
+ """Convert filter to query parameters."""
98
+ params = {}
99
+ if self.search_term:
100
+ params["filter[searchTerm]"] = self.search_term
101
+ if self.organization_ids:
102
+ params["filter[organizationIds]"] = ",".join([str(x) for x in self.organization_ids])
103
+ if self.name:
104
+ params["filter[name]"] = self.name
105
+ if self.uploaded_by:
106
+ params["filter[uploadedBy]"] = self.uploaded_by
107
+ if self.uploaded_at:
108
+ params["filter[uploadedAt]"] = self.uploaded_at
109
+ return params
110
+
111
+
112
+ class ExecuteCommandRequest(AIRBaseModel):
113
+ """Request model for executing interact command."""
114
+
115
+ command: str
116
+ accept: Optional[str] = "json" # json or text
117
+
118
+
119
+ class ExecuteCommandResponse(AIRBaseModel):
120
+ """Response model for execute command."""
121
+
122
+ message_id: str = Field(alias="messageId")
123
+ session: Dict[str, str]
124
+ body: str
125
+ cwd: str
126
+ exit_code: int = Field(alias="exitCode")
127
+
128
+
129
+ class InteractCommandOption(AIRBaseModel):
130
+ """Interact command option model."""
131
+
132
+ name: str
133
+ abbreviations: List[str]
134
+ effect: str
135
+ required: bool
136
+
137
+
138
+ class InteractCommand(AIRBaseModel):
139
+ """Interact command model."""
140
+
141
+ command: List[str]
142
+ description: str
143
+ options: List[InteractCommandOption]
144
+ privilege: str
145
+ usage: List[str]
146
+
147
+
148
+ class SessionInfo(AIRBaseModel):
149
+ """Session information model."""
150
+
151
+ id: str
152
+
153
+
154
+ class CommandMessage(AIRBaseModel):
155
+ """Command message model."""
156
+
157
+ message_id: str = Field(alias="messageId")
158
+ session: SessionInfo
159
+ body: str
160
+ cwd: str
161
+ exit_code: int = Field(alias="exitCode")
162
+
163
+
164
+ class InterruptCommandRequest(AIRBaseModel):
165
+ """Request model for interrupting command."""
166
+ pass # Empty request body
167
+
168
+
169
+ class CloseSessionRequest(AIRBaseModel):
170
+ """Request model for closing session."""
171
+ pass # Empty request body
172
+
173
+
174
+ class UploadFileRequest(AIRBaseModel):
175
+ """Request model for uploading file to library."""
176
+
177
+ file_content: bytes
178
+ filename: str
179
+ organization_ids: Optional[List[int]] = Field(default=None, alias="organizationIds")
180
+
181
+
182
+ class DeleteFileRequest(AIRBaseModel):
183
+ """Request model for deleting file from library."""
184
+
185
+ file_id: str = Field(alias="fileId")
186
+
187
+
188
+ class CheckFileExistsRequest(AIRBaseModel):
189
+ """Request model for checking if file exists."""
190
+
191
+ filename: str
192
+ sha256: Optional[str] = None
193
+
194
+
195
+ class FileExistsResponse(AIRBaseModel):
196
+ """Response model for file exists check."""
197
+
198
+ exists: bool
199
+ file_id: Optional[str] = Field(default=None, alias="fileId")
200
+
201
+
202
+ # Legacy models for backward compatibility (deprecated)
203
+ class InteractionType(str, Enum):
204
+ """Interaction types."""
205
+ SHELL = "shell"
206
+ POWERSHELL = "powershell"
207
+ CMD = "cmd"
208
+ BASH = "bash"
209
+
210
+
211
+ class InteractionStatus(str, Enum):
212
+ """Interaction status."""
213
+ PENDING = "pending"
214
+ RUNNING = "running"
215
+ COMPLETED = "completed"
216
+ FAILED = "failed"
217
+ CANCELLED = "cancelled"
218
+ TIMEOUT = "timeout"
219
+
220
+
221
+ class ShellInteraction(AIRBaseModel):
222
+ """Shell interaction model (legacy)."""
223
+
224
+ id: str
225
+ task_id: str
226
+ endpoint_id: str
227
+ endpoint_name: str
228
+ interaction_type: InteractionType
229
+ command: str
230
+ output: Optional[str] = None
231
+ error_output: Optional[str] = None
232
+ exit_code: Optional[int] = None
233
+ status: InteractionStatus = InteractionStatus.PENDING
234
+ timeout: int = 300 # seconds
235
+ organization_id: int
236
+ created_by: Optional[str] = None
237
+ created_at: Optional[datetime] = None
238
+ started_at: Optional[datetime] = None
239
+ completed_at: Optional[datetime] = None
240
+ duration: Optional[int] = None # seconds
241
+ environment_variables: Optional[Dict[str, str]] = None
242
+ working_directory: Optional[str] = None
243
+
244
+
245
+ class AssignShellTaskRequest(AIRBaseModel):
246
+ """Request model for assigning shell interaction tasks (legacy)."""
247
+
248
+ endpoint_ids: List[str]
249
+ command: str
250
+ interaction_type: InteractionType = InteractionType.SHELL
251
+ timeout: Optional[int] = 300
252
+ organization_ids: Optional[List[int]] = None
253
+ case_id: Optional[str] = None
254
+ environment_variables: Optional[Dict[str, str]] = None
255
+ working_directory: Optional[str] = None
256
+ description: Optional[str] = None
257
+
258
+
259
+ class ShellTaskResponse(AIRBaseModel):
260
+ """Response model for shell task assignment (legacy)."""
261
+
262
+ task_id: str
263
+ endpoint_interactions: List[ShellInteraction]
264
+ success_count: int
265
+ failure_count: int
266
+ total_count: int
136
267
  errors: Optional[List[Dict[str, Any]]] = None
@@ -0,0 +1,265 @@
1
+ """
2
+ Investigation Hub models for the Binalyze AIR SDK.
3
+ """
4
+
5
+ from typing import Optional, List, Dict, Any
6
+ from datetime import datetime
7
+ from pydantic import Field
8
+
9
+ from ..base import AIRBaseModel
10
+
11
+
12
+ class InvestigationMeta(AIRBaseModel):
13
+ """Investigation metadata model."""
14
+
15
+ case_id: Optional[str] = Field(default=None, alias="caseId")
16
+ disk_usage_in_bytes: Optional[int] = Field(default=None, alias="diskUsageInBytes")
17
+
18
+
19
+ class Investigation(AIRBaseModel):
20
+ """Investigation model."""
21
+
22
+ uid: str
23
+ investigation_schema: str = Field(alias="schema")
24
+ type: str
25
+ meta: Optional[InvestigationMeta] = None
26
+ timezone: str = "UTC"
27
+ organization_id: int = Field(alias="organizationId")
28
+ last_accessed_at: Optional[datetime] = Field(default=None, alias="lastAccessedAt")
29
+ status: str
30
+ migrations_completed: bool = Field(default=True, alias="migrationsCompleted")
31
+
32
+
33
+ class UpdateInvestigationRequest(AIRBaseModel):
34
+ """Request model for updating investigations."""
35
+
36
+ timezone: Optional[str] = None
37
+ meta: Optional[Dict[str, Any]] = None
38
+
39
+
40
+ class InvestigationAsset(AIRBaseModel):
41
+ """Investigation asset model."""
42
+
43
+ id: str = Field(alias="_id")
44
+ name: str
45
+ platform: str
46
+ ip_address: Optional[str] = Field(default=None, alias="ipAddress")
47
+ organization_id: int = Field(alias="organizationId")
48
+
49
+
50
+ class FlagSummary(AIRBaseModel):
51
+ """Flag summary model."""
52
+
53
+ id: int
54
+ name: str
55
+ color: str
56
+ count: int
57
+
58
+
59
+ class EvidenceSection(AIRBaseModel):
60
+ """Evidence section model."""
61
+
62
+ name: str
63
+ display_name: str = Field(alias="displayName")
64
+ table_count: int = Field(alias="tableCount")
65
+ record_count: int = Field(alias="recordCount")
66
+
67
+
68
+ class EvidenceStructure(AIRBaseModel):
69
+ """Evidence structure model."""
70
+
71
+ name: str
72
+ type: str
73
+ nullable: bool = Field(default=True)
74
+ primary_key: bool = Field(default=False, alias="primaryKey")
75
+
76
+
77
+ class SQLQueryRequest(AIRBaseModel):
78
+ """SQL query request model."""
79
+
80
+ query: str
81
+ page_size: int = Field(default=10, alias="pageSize")
82
+ page_number: int = Field(default=1, alias="pageNumber")
83
+
84
+
85
+ class SQLQueryResult(AIRBaseModel):
86
+ """SQL query result model."""
87
+
88
+ entities: List[Dict[str, Any]]
89
+ total_entity_count: int = Field(alias="totalEntityCount")
90
+ current_page: int = Field(alias="currentPage")
91
+ page_size: int = Field(alias="pageSize")
92
+ next_page: int = Field(alias="nextPage")
93
+ total_page_count: int = Field(alias="totalPageCount")
94
+ previous_page: int = Field(alias="previousPage")
95
+
96
+
97
+ class FlagEvidenceRequest(AIRBaseModel):
98
+ """Flag evidence request model."""
99
+
100
+ flag_id: int = Field(alias="flagId")
101
+ records: List[Dict[str, Any]]
102
+ section: str
103
+
104
+
105
+ class EvidenceNote(AIRBaseModel):
106
+ """Evidence note model."""
107
+
108
+ id: str
109
+ content: str
110
+ created_at: datetime = Field(alias="createdAt")
111
+ created_by: str = Field(alias="createdBy")
112
+
113
+
114
+ class FindingsSummary(AIRBaseModel):
115
+ """Findings summary model."""
116
+
117
+ total_findings: int = Field(alias="totalFindings")
118
+ critical_count: int = Field(alias="criticalCount")
119
+ high_count: int = Field(alias="highCount")
120
+ medium_count: int = Field(alias="mediumCount")
121
+ low_count: int = Field(alias="lowCount")
122
+ info_count: int = Field(alias="infoCount")
123
+
124
+
125
+ class FindingsStructure(AIRBaseModel):
126
+ """Findings structure model."""
127
+
128
+ flagged_by_list: List[str] = Field(alias="flaggedByList")
129
+ tactics: List[str]
130
+ tactic_ids: List[str] = Field(alias="tacticIds")
131
+ techniques: List[str]
132
+ technique_ids: List[str] = Field(alias="techniqueIds")
133
+ evidence_categories: List[Dict[str, str]] = Field(alias="evidenceCategories")
134
+ extra_columns: List[Dict[str, Any]] = Field(alias="extraColumns")
135
+ columns_structure: List[Dict[str, Any]] = Field(alias="columnsStructure")
136
+
137
+
138
+ class FindingsFilter(AIRBaseModel):
139
+ """Findings filter model."""
140
+
141
+ assignment_ids: Optional[List[str]] = Field(default=None, alias="assignmentIds")
142
+ flag_ids: Optional[List[int]] = Field(default=None, alias="flagIds")
143
+ verdict_scores: Optional[List[str]] = Field(default=None, alias="verdictScores")
144
+ created_by: Optional[List[str]] = Field(default=None, alias="createdBy")
145
+ mitre_technique_ids: Optional[List[str]] = Field(default=None, alias="mitreTechniqueIds")
146
+ mitre_tactic_ids: Optional[List[str]] = Field(default=None, alias="mitreTacticIds")
147
+
148
+
149
+ class FindingsRequest(AIRBaseModel):
150
+ """Findings request model."""
151
+
152
+ take: int = Field(default=50)
153
+ skip: int = Field(default=0)
154
+ filter: Optional[List[Dict[str, Any]]] = Field(default=None)
155
+ global_filter: Optional[FindingsFilter] = Field(default=None, alias="globalFilter")
156
+ sort: Optional[List[Dict[str, str]]] = Field(default=None)
157
+
158
+
159
+ class FindingsResult(AIRBaseModel):
160
+ """Findings result model."""
161
+
162
+ entities: List[Dict[str, Any]]
163
+ total_count: int = Field(alias="totalCount")
164
+ total_count_with_no_filter: int = Field(alias="totalCountWithNoFilter")
165
+
166
+
167
+ class MitreMatch(AIRBaseModel):
168
+ """MITRE ATT&CK match model."""
169
+
170
+ technique_id: str = Field(alias="techniqueId")
171
+ technique_name: str = Field(alias="techniqueName")
172
+ tactic: str
173
+ confidence: float
174
+
175
+
176
+ class InvestigationComment(AIRBaseModel):
177
+ """Investigation comment model."""
178
+
179
+ id: str
180
+ content: str
181
+ evidence_id: Optional[str] = Field(default=None, alias="evidenceId")
182
+ created_at: datetime = Field(alias="createdAt")
183
+ created_by: str = Field(alias="createdBy")
184
+
185
+
186
+ class EvidenceItem(AIRBaseModel):
187
+ """Evidence item for comments."""
188
+
189
+ evidence: str
190
+ task_assignment_id: str = Field(alias="taskAssignmentId")
191
+ object_id: int = Field(alias="objectId")
192
+
193
+
194
+ class AddNoteRequest(AIRBaseModel):
195
+ """Add note request model."""
196
+
197
+ items: List[EvidenceItem]
198
+ note: str
199
+ source: str = "EVIDENCE"
200
+
201
+
202
+ class CreateCommentRequest(AIRBaseModel):
203
+ """Create comment request model."""
204
+
205
+ items: List[EvidenceItem]
206
+ content: str
207
+ mentioned_usernames: List[str] = Field(default_factory=list, alias="mentionedUsernames")
208
+ source: str = "EVIDENCE"
209
+
210
+
211
+ class InvestigationActivity(AIRBaseModel):
212
+ """Investigation activity model."""
213
+
214
+ id: str
215
+ type: str
216
+ description: str
217
+ user_id: str = Field(alias="userId")
218
+ created_at: datetime = Field(alias="createdAt")
219
+ read: bool = Field(default=False)
220
+
221
+
222
+ class MarkActivityAsReadRequest(AIRBaseModel):
223
+ """Mark activity as read request model."""
224
+
225
+ mark_all: bool = Field(default=False, alias="markAll")
226
+ activity_id: Optional[int] = Field(default=None, alias="activityId")
227
+
228
+
229
+ class AdvancedFilter(AIRBaseModel):
230
+ """Advanced filter model."""
231
+
232
+ id: int # API returns integer ID
233
+ name: str
234
+ organization_id: int = Field(alias="organizationId")
235
+ filter: Optional[Dict[str, Any]] = Field(default=None) # Match API response
236
+ table_name: Optional[str] = Field(default=None, alias="tableName")
237
+ created_at: datetime = Field(alias="createdAt")
238
+ created_by: Optional[str] = Field(default=None, alias="createdBy")
239
+ updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
240
+
241
+
242
+ class CreateAdvancedFilterRequest(AIRBaseModel):
243
+ """Create advanced filter request model."""
244
+
245
+ name: str
246
+ filter: Dict[str, Any] # Contains main and sections
247
+ table_name: str = Field(alias="tableName")
248
+ organization_id: int = Field(alias="organizationId")
249
+
250
+
251
+ class UpdateAdvancedFilterRequest(AIRBaseModel):
252
+ """Update advanced filter request model."""
253
+
254
+ name: Optional[str] = Field(default=None)
255
+ filter: Optional[Dict[str, Any]] = Field(default=None) # Contains main and sections
256
+ table_name: Optional[str] = Field(default=None, alias="tableName")
257
+ organization_id: Optional[int] = Field(default=None, alias="organizationId")
258
+
259
+
260
+ class ExportRequest(AIRBaseModel):
261
+ """Export request model."""
262
+
263
+ format: str = "csv" # csv, json, xlsx
264
+ filters: Optional[Dict[str, Any]] = None
265
+ columns: Optional[List[str]] = None