binalyze-air-sdk 1.0.1__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.
- binalyze_air/__init__.py +77 -77
- binalyze_air/apis/__init__.py +67 -27
- binalyze_air/apis/acquisitions.py +107 -0
- binalyze_air/apis/api_tokens.py +49 -0
- binalyze_air/apis/assets.py +161 -0
- binalyze_air/apis/audit_logs.py +26 -0
- binalyze_air/apis/{authentication.py → auth.py} +29 -27
- binalyze_air/apis/auto_asset_tags.py +79 -75
- binalyze_air/apis/backup.py +177 -0
- binalyze_air/apis/baseline.py +46 -0
- binalyze_air/apis/cases.py +225 -0
- binalyze_air/apis/cloud_forensics.py +116 -0
- binalyze_air/apis/event_subscription.py +96 -96
- binalyze_air/apis/evidence.py +249 -53
- binalyze_air/apis/interact.py +153 -36
- binalyze_air/apis/investigation_hub.py +234 -0
- binalyze_air/apis/license.py +104 -0
- binalyze_air/apis/logger.py +83 -0
- binalyze_air/apis/multipart_upload.py +201 -0
- binalyze_air/apis/notifications.py +115 -0
- binalyze_air/apis/organizations.py +267 -0
- binalyze_air/apis/params.py +44 -39
- binalyze_air/apis/policies.py +186 -0
- binalyze_air/apis/preset_filters.py +79 -0
- binalyze_air/apis/recent_activities.py +71 -0
- binalyze_air/apis/relay_server.py +104 -0
- binalyze_air/apis/settings.py +395 -27
- binalyze_air/apis/tasks.py +80 -0
- binalyze_air/apis/triage.py +197 -0
- binalyze_air/apis/user_management.py +183 -74
- binalyze_air/apis/webhook_executions.py +50 -0
- binalyze_air/apis/webhooks.py +322 -230
- binalyze_air/base.py +207 -133
- binalyze_air/client.py +217 -1337
- binalyze_air/commands/__init__.py +175 -145
- binalyze_air/commands/acquisitions.py +661 -387
- binalyze_air/commands/api_tokens.py +55 -0
- binalyze_air/commands/assets.py +324 -362
- binalyze_air/commands/{authentication.py → auth.py} +36 -36
- binalyze_air/commands/auto_asset_tags.py +230 -230
- binalyze_air/commands/backup.py +47 -0
- binalyze_air/commands/baseline.py +32 -396
- binalyze_air/commands/cases.py +609 -602
- binalyze_air/commands/cloud_forensics.py +88 -0
- binalyze_air/commands/event_subscription.py +101 -101
- binalyze_air/commands/evidences.py +918 -988
- binalyze_air/commands/interact.py +172 -58
- binalyze_air/commands/investigation_hub.py +315 -0
- binalyze_air/commands/license.py +183 -0
- binalyze_air/commands/logger.py +126 -0
- binalyze_air/commands/multipart_upload.py +363 -0
- binalyze_air/commands/notifications.py +45 -0
- binalyze_air/commands/organizations.py +200 -221
- binalyze_air/commands/policies.py +175 -203
- binalyze_air/commands/preset_filters.py +55 -0
- binalyze_air/commands/recent_activities.py +32 -0
- binalyze_air/commands/relay_server.py +144 -0
- binalyze_air/commands/settings.py +431 -29
- binalyze_air/commands/tasks.py +95 -56
- binalyze_air/commands/triage.py +224 -360
- binalyze_air/commands/user_management.py +351 -126
- binalyze_air/commands/webhook_executions.py +77 -0
- binalyze_air/config.py +244 -244
- binalyze_air/exceptions.py +49 -49
- binalyze_air/http_client.py +426 -305
- binalyze_air/models/__init__.py +287 -285
- binalyze_air/models/acquisitions.py +365 -250
- binalyze_air/models/api_tokens.py +73 -0
- binalyze_air/models/assets.py +438 -438
- binalyze_air/models/audit.py +247 -272
- binalyze_air/models/audit_logs.py +14 -0
- binalyze_air/models/{authentication.py → auth.py} +69 -69
- binalyze_air/models/auto_asset_tags.py +227 -116
- binalyze_air/models/backup.py +138 -0
- binalyze_air/models/baseline.py +231 -231
- binalyze_air/models/cases.py +275 -275
- binalyze_air/models/cloud_forensics.py +145 -0
- binalyze_air/models/event_subscription.py +170 -171
- binalyze_air/models/evidence.py +65 -65
- binalyze_air/models/evidences.py +367 -348
- binalyze_air/models/interact.py +266 -135
- binalyze_air/models/investigation_hub.py +265 -0
- binalyze_air/models/license.py +150 -0
- binalyze_air/models/logger.py +83 -0
- binalyze_air/models/multipart_upload.py +352 -0
- binalyze_air/models/notifications.py +138 -0
- binalyze_air/models/organizations.py +293 -293
- binalyze_air/models/params.py +153 -127
- binalyze_air/models/policies.py +260 -249
- binalyze_air/models/preset_filters.py +79 -0
- binalyze_air/models/recent_activities.py +70 -0
- binalyze_air/models/relay_server.py +121 -0
- binalyze_air/models/settings.py +538 -84
- binalyze_air/models/tasks.py +215 -149
- binalyze_air/models/triage.py +141 -142
- binalyze_air/models/user_management.py +200 -97
- binalyze_air/models/webhook_executions.py +33 -0
- binalyze_air/queries/__init__.py +121 -133
- binalyze_air/queries/acquisitions.py +155 -155
- binalyze_air/queries/api_tokens.py +46 -0
- binalyze_air/queries/assets.py +186 -105
- binalyze_air/queries/audit.py +400 -416
- binalyze_air/queries/{authentication.py → auth.py} +55 -55
- binalyze_air/queries/auto_asset_tags.py +59 -59
- binalyze_air/queries/backup.py +66 -0
- binalyze_air/queries/baseline.py +21 -185
- binalyze_air/queries/cases.py +292 -292
- binalyze_air/queries/cloud_forensics.py +137 -0
- binalyze_air/queries/event_subscription.py +54 -54
- binalyze_air/queries/evidence.py +139 -139
- binalyze_air/queries/evidences.py +279 -279
- binalyze_air/queries/interact.py +140 -28
- binalyze_air/queries/investigation_hub.py +329 -0
- binalyze_air/queries/license.py +85 -0
- binalyze_air/queries/logger.py +58 -0
- binalyze_air/queries/multipart_upload.py +180 -0
- binalyze_air/queries/notifications.py +71 -0
- binalyze_air/queries/organizations.py +222 -222
- binalyze_air/queries/params.py +154 -115
- binalyze_air/queries/policies.py +149 -149
- binalyze_air/queries/preset_filters.py +60 -0
- binalyze_air/queries/recent_activities.py +44 -0
- binalyze_air/queries/relay_server.py +42 -0
- binalyze_air/queries/settings.py +533 -20
- binalyze_air/queries/tasks.py +125 -81
- binalyze_air/queries/triage.py +230 -230
- binalyze_air/queries/user_management.py +193 -83
- binalyze_air/queries/webhook_executions.py +39 -0
- binalyze_air_sdk-1.0.3.dist-info/METADATA +752 -0
- binalyze_air_sdk-1.0.3.dist-info/RECORD +132 -0
- {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/WHEEL +1 -1
- binalyze_air/apis/endpoints.py +0 -22
- binalyze_air/apis/evidences.py +0 -216
- binalyze_air/apis/users.py +0 -68
- binalyze_air/commands/users.py +0 -101
- binalyze_air/models/endpoints.py +0 -76
- binalyze_air/models/users.py +0 -82
- binalyze_air/queries/endpoints.py +0 -25
- binalyze_air/queries/users.py +0 -69
- binalyze_air_sdk-1.0.1.dist-info/METADATA +0 -635
- binalyze_air_sdk-1.0.1.dist-info/RECORD +0 -82
- {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/top_level.txt +0 -0
binalyze_air/models/interact.py
CHANGED
@@ -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
|
-
#
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|