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/cases.py
CHANGED
@@ -1,276 +1,276 @@
|
|
1
|
-
"""
|
2
|
-
Case-related data models for the Binalyze AIR SDK.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from typing import List, Optional, Dict, Any, Literal, Union
|
6
|
-
from datetime import datetime
|
7
|
-
from enum import Enum
|
8
|
-
from pydantic import Field, field_validator
|
9
|
-
|
10
|
-
from ..base import AIRBaseModel, Filter
|
11
|
-
|
12
|
-
|
13
|
-
class CaseStatus(str, Enum):
|
14
|
-
"""Case status."""
|
15
|
-
OPEN = "open"
|
16
|
-
CLOSED = "closed"
|
17
|
-
ARCHIVED = "archived"
|
18
|
-
|
19
|
-
|
20
|
-
class CaseNote(AIRBaseModel):
|
21
|
-
"""Case note model."""
|
22
|
-
|
23
|
-
id: str = Field(alias="_id")
|
24
|
-
case_id: str = Field(alias="caseId")
|
25
|
-
value: str
|
26
|
-
written_at: Optional[datetime] = Field(default=None, alias="writtenAt")
|
27
|
-
written_by: Optional[str] = Field(default=None, alias="writtenBy")
|
28
|
-
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
29
|
-
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
30
|
-
|
31
|
-
|
32
|
-
class Case(AIRBaseModel):
|
33
|
-
"""Case model."""
|
34
|
-
|
35
|
-
id: str = Field(alias="_id")
|
36
|
-
name: str
|
37
|
-
status: CaseStatus = CaseStatus.OPEN
|
38
|
-
owner_user_id: str = Field(alias="ownerUserId")
|
39
|
-
owner_user: Optional[Any] = Field(default=None, alias="ownerUser")
|
40
|
-
assigned_user_ids: List[str] = Field(default=[], alias="assignedUserIds")
|
41
|
-
assigned_users: List[Any] = Field(default=[], alias="assignedUsers")
|
42
|
-
visibility: str
|
43
|
-
organization_id: int = Field(default=0, alias="organizationId")
|
44
|
-
notes: List[Any] = []
|
45
|
-
endpoint_count: int = Field(default=0, alias="endpointCount")
|
46
|
-
task_count: int = Field(default=0, alias="taskCount")
|
47
|
-
acquisition_task_count: int = Field(default=0, alias="acquisitionTaskCount")
|
48
|
-
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
49
|
-
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
50
|
-
closed_at: Optional[datetime] = Field(default=None, alias="closedAt")
|
51
|
-
archived_at: Optional[datetime] = Field(default=None, alias="archivedAt")
|
52
|
-
# Optional fields that may not be in all responses
|
53
|
-
source: Optional[str] = None
|
54
|
-
started_on: Optional[datetime] = Field(default=None, alias="startedOn")
|
55
|
-
total_days: int = Field(default=0, alias="totalDays")
|
56
|
-
total_endpoints: int = Field(default=0, alias="totalEndpoints")
|
57
|
-
closed_on: Optional[datetime] = Field(default=None, alias="closedOn")
|
58
|
-
|
59
|
-
|
60
|
-
class CaseActivity(AIRBaseModel):
|
61
|
-
"""Case activity model."""
|
62
|
-
|
63
|
-
id: Optional[str] = Field(default=None, alias="_id")
|
64
|
-
case_id: Optional[str] = Field(default=None, alias="caseId")
|
65
|
-
user_id: Optional[str] = Field(default=None, alias="userId")
|
66
|
-
user: Optional[Any] = None
|
67
|
-
activity_type: Optional[str] = Field(default=None, alias="activityType")
|
68
|
-
description: Optional[str] = None
|
69
|
-
details: Dict[str, Any] = {}
|
70
|
-
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
71
|
-
# Legacy fields that may still exist
|
72
|
-
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
73
|
-
type: Optional[str] = None
|
74
|
-
performed_by: Optional[str] = Field(default=None, alias="performedBy")
|
75
|
-
data: Optional[Any] = None
|
76
|
-
organization_ids: List[int] = Field(default=[], alias="organizationIds")
|
77
|
-
|
78
|
-
|
79
|
-
class CaseEndpoint(AIRBaseModel):
|
80
|
-
"""Case endpoint model."""
|
81
|
-
|
82
|
-
platform: str
|
83
|
-
tags: List[str] = []
|
84
|
-
isolation_status: str = Field(alias="isolationStatus")
|
85
|
-
id: str = Field(alias="_id")
|
86
|
-
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
87
|
-
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
88
|
-
organization_id: int = Field(default=0, alias="organizationId")
|
89
|
-
ip_address: Optional[str] = Field(default=None, alias="ipAddress")
|
90
|
-
name: str
|
91
|
-
group_id: Optional[str] = Field(default=None, alias="groupId")
|
92
|
-
group_full_path: Optional[str] = Field(default=None, alias="groupFullPath")
|
93
|
-
os: str
|
94
|
-
is_server: bool = Field(default=False, alias="isServer")
|
95
|
-
is_managed: bool = Field(default=True, alias="isManaged")
|
96
|
-
last_seen: Optional[datetime] = Field(default=None, alias="lastSeen")
|
97
|
-
version: Optional[str] = None
|
98
|
-
version_no: Optional[int] = Field(default=None, alias="versionNo")
|
99
|
-
registered_at: Optional[datetime] = Field(default=None, alias="registeredAt")
|
100
|
-
security_token: Optional[str] = Field(default=None, alias="securityToken")
|
101
|
-
online_status: str = Field(alias="onlineStatus")
|
102
|
-
issues: List[str] = []
|
103
|
-
label: Optional[str] = None
|
104
|
-
waiting_for_version_update_fix: bool = Field(default=False, alias="waitingForVersionUpdateFix")
|
105
|
-
|
106
|
-
|
107
|
-
class CaseTask(AIRBaseModel):
|
108
|
-
"""Case task model."""
|
109
|
-
|
110
|
-
id: str = Field(alias="_id")
|
111
|
-
task_id: str = Field(alias="taskId")
|
112
|
-
name: str
|
113
|
-
type: str
|
114
|
-
endpoint_id: str = Field(alias="endpointId")
|
115
|
-
endpoint_name: str = Field(alias="endpointName")
|
116
|
-
organization_id: int = Field(default=0, alias="organizationId")
|
117
|
-
status: str
|
118
|
-
recurrence: Optional[str] = None
|
119
|
-
progress: int = 0
|
120
|
-
duration: Optional[int] = None
|
121
|
-
case_ids: List[str] = Field(default=[], alias="caseIds")
|
122
|
-
is_comparable: bool = Field(default=False, alias="isComparable")
|
123
|
-
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
124
|
-
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
125
|
-
response: Optional[Any] = None
|
126
|
-
|
127
|
-
|
128
|
-
class UserProfile(AIRBaseModel):
|
129
|
-
"""User profile model."""
|
130
|
-
|
131
|
-
name: str
|
132
|
-
surname: str
|
133
|
-
department: str
|
134
|
-
|
135
|
-
|
136
|
-
class Role(AIRBaseModel):
|
137
|
-
"""User role model."""
|
138
|
-
|
139
|
-
id: str = Field(alias="_id")
|
140
|
-
name: str
|
141
|
-
created_by: str = Field(alias="createdBy")
|
142
|
-
tag: str
|
143
|
-
privilege_types: List[str] = Field(default=[], alias="privilegeTypes")
|
144
|
-
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
145
|
-
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
146
|
-
|
147
|
-
|
148
|
-
class User(AIRBaseModel):
|
149
|
-
"""User model."""
|
150
|
-
|
151
|
-
id: str = Field(alias="_id")
|
152
|
-
email: str
|
153
|
-
username: str
|
154
|
-
organization_ids: Union[List[int], str] = Field(default=[], alias="organizationIds")
|
155
|
-
strategy: str
|
156
|
-
profile: UserProfile
|
157
|
-
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
158
|
-
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
159
|
-
roles: List[Role] = []
|
160
|
-
|
161
|
-
@field_validator('organization_ids', mode='before')
|
162
|
-
@classmethod
|
163
|
-
def parse_organization_ids(cls, v):
|
164
|
-
"""Handle organizationIds which can be a list of ints or the string 'ALL'."""
|
165
|
-
if isinstance(v, str):
|
166
|
-
# Handle the "ALL" case - return as is for now
|
167
|
-
return v
|
168
|
-
elif isinstance(v, list):
|
169
|
-
# Ensure all items are integers
|
170
|
-
return [int(item) if not isinstance(item, int) else item for item in v]
|
171
|
-
else:
|
172
|
-
# Default to empty list for other cases
|
173
|
-
return []
|
174
|
-
|
175
|
-
|
176
|
-
class CaseFilter(Filter):
|
177
|
-
"""Filter for case queries."""
|
178
|
-
|
179
|
-
name: Optional[str] = None
|
180
|
-
status: Optional[List[CaseStatus]] = None
|
181
|
-
owner_user_id: Optional[str] = None
|
182
|
-
assigned_user_ids: Optional[List[str]] = None
|
183
|
-
visibility: Optional[str] = None
|
184
|
-
source: Optional[str] = None
|
185
|
-
|
186
|
-
|
187
|
-
class CaseActivityFilter(Filter):
|
188
|
-
"""Filter for case activity queries."""
|
189
|
-
|
190
|
-
performed_by: Optional[List[str]] = None # User IDs who performed the activities
|
191
|
-
types: Optional[List[str]] = None # Activity types to filter
|
192
|
-
search_term: Optional[str] = None # Search term for activity descriptions
|
193
|
-
occurred_at: Optional[str] = None # Date range filter
|
194
|
-
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
195
|
-
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
196
|
-
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
197
|
-
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
198
|
-
|
199
|
-
|
200
|
-
class CaseEndpointFilter(Filter):
|
201
|
-
"""Filter for case endpoint queries."""
|
202
|
-
|
203
|
-
organization_ids: Optional[List[int]] = None # Required organization IDs
|
204
|
-
search_term: Optional[str] = None # Search term for endpoint names
|
205
|
-
name: Optional[str] = None # Endpoint name filter
|
206
|
-
ip_address: Optional[str] = None # IP address filter
|
207
|
-
group_id: Optional[str] = None # Group ID filter
|
208
|
-
group_full_path: Optional[str] = None # Group full path filter
|
209
|
-
label: Optional[str] = None # Label filter
|
210
|
-
last_seen: Optional[str] = None # Last seen date range (e.g., "2023-03-06T21:00:00.000Z,2023-03-24T21:00:00.000Z")
|
211
|
-
managed_status: Optional[List[str]] = None # Managed status filter (unmanaged, managed, off-network)
|
212
|
-
isolation_status: Optional[List[str]] = None # Isolation status filter (isolating, isolated, unisolating, unisolated)
|
213
|
-
platform: Optional[List[str]] = None # Platform filter (windows, linux, darwin)
|
214
|
-
issue: Optional[List[str]] = None # Issue filter (unreachable, old-version, update-required)
|
215
|
-
online_status: Optional[List[str]] = None # Online status filter (online, offline)
|
216
|
-
tags: Optional[List[str]] = None # Tags filter
|
217
|
-
version: Optional[str] = None # Version filter
|
218
|
-
policy: Optional[str] = None # Policy filter
|
219
|
-
included_endpoint_ids: Optional[List[str]] = None # Included endpoint IDs
|
220
|
-
excluded_endpoint_ids: Optional[List[str]] = None # Excluded endpoint IDs
|
221
|
-
aws_regions: Optional[List[str]] = None # AWS regions filter
|
222
|
-
azure_regions: Optional[List[str]] = None # Azure regions filter
|
223
|
-
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
224
|
-
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
225
|
-
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
226
|
-
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
227
|
-
|
228
|
-
|
229
|
-
class CaseTaskFilter(Filter):
|
230
|
-
"""Filter for case task queries."""
|
231
|
-
|
232
|
-
organization_ids: Optional[List[int]] = None # Required organization IDs
|
233
|
-
search_term: Optional[str] = None # Search term for task names
|
234
|
-
name: Optional[str] = None # Task name filter
|
235
|
-
endpoint_ids: Optional[List[str]] = None # Endpoint IDs filter
|
236
|
-
execution_type: Optional[str] = None # Execution type filter (instant, scheduled)
|
237
|
-
status: Optional[str] = None # Status filter (scheduled, assigned, processing, completed, failed, expired, cancelled, compressing, uploading, analyzing, partially-completed)
|
238
|
-
type: Optional[str] = None # Task type filter (acquisition, offline-acquisition, triage, offline-triage, investigation, interact-shell, baseline-comparison, baseline-acquisition, acquire-image)
|
239
|
-
asset_names: Optional[str] = None # Comma separated asset names
|
240
|
-
started_by: Optional[str] = None # Started by user filter
|
241
|
-
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
242
|
-
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
243
|
-
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
244
|
-
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
245
|
-
|
246
|
-
|
247
|
-
class CaseUserFilter(Filter):
|
248
|
-
"""Filter for case user queries."""
|
249
|
-
|
250
|
-
organization_ids: Optional[List[int]] = None # Required organization IDs
|
251
|
-
search_term: Optional[str] = None # Search term for user filtering
|
252
|
-
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
253
|
-
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
254
|
-
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
255
|
-
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
256
|
-
|
257
|
-
|
258
|
-
class CreateCaseRequest(AIRBaseModel):
|
259
|
-
"""Request model for creating a case."""
|
260
|
-
|
261
|
-
organization_id: int = 0
|
262
|
-
name: str
|
263
|
-
owner_user_id: str
|
264
|
-
visibility: str
|
265
|
-
assigned_user_ids: List[str] = []
|
266
|
-
|
267
|
-
|
268
|
-
class UpdateCaseRequest(AIRBaseModel):
|
269
|
-
"""Request model for updating a case."""
|
270
|
-
|
271
|
-
name: Optional[str] = None
|
272
|
-
owner_user_id: Optional[str] = None
|
273
|
-
visibility: Optional[str] = None
|
274
|
-
assigned_user_ids: Optional[List[str]] = None
|
275
|
-
status: Optional[CaseStatus] = None
|
1
|
+
"""
|
2
|
+
Case-related data models for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional, Dict, Any, Literal, Union
|
6
|
+
from datetime import datetime
|
7
|
+
from enum import Enum
|
8
|
+
from pydantic import Field, field_validator
|
9
|
+
|
10
|
+
from ..base import AIRBaseModel, Filter
|
11
|
+
|
12
|
+
|
13
|
+
class CaseStatus(str, Enum):
|
14
|
+
"""Case status."""
|
15
|
+
OPEN = "open"
|
16
|
+
CLOSED = "closed"
|
17
|
+
ARCHIVED = "archived"
|
18
|
+
|
19
|
+
|
20
|
+
class CaseNote(AIRBaseModel):
|
21
|
+
"""Case note model."""
|
22
|
+
|
23
|
+
id: str = Field(alias="_id")
|
24
|
+
case_id: str = Field(alias="caseId")
|
25
|
+
value: str
|
26
|
+
written_at: Optional[datetime] = Field(default=None, alias="writtenAt")
|
27
|
+
written_by: Optional[str] = Field(default=None, alias="writtenBy")
|
28
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
29
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
30
|
+
|
31
|
+
|
32
|
+
class Case(AIRBaseModel):
|
33
|
+
"""Case model."""
|
34
|
+
|
35
|
+
id: str = Field(alias="_id")
|
36
|
+
name: str
|
37
|
+
status: CaseStatus = CaseStatus.OPEN
|
38
|
+
owner_user_id: str = Field(alias="ownerUserId")
|
39
|
+
owner_user: Optional[Any] = Field(default=None, alias="ownerUser")
|
40
|
+
assigned_user_ids: List[str] = Field(default=[], alias="assignedUserIds")
|
41
|
+
assigned_users: List[Any] = Field(default=[], alias="assignedUsers")
|
42
|
+
visibility: str
|
43
|
+
organization_id: int = Field(default=0, alias="organizationId")
|
44
|
+
notes: List[Any] = []
|
45
|
+
endpoint_count: int = Field(default=0, alias="endpointCount")
|
46
|
+
task_count: int = Field(default=0, alias="taskCount")
|
47
|
+
acquisition_task_count: int = Field(default=0, alias="acquisitionTaskCount")
|
48
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
49
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
50
|
+
closed_at: Optional[datetime] = Field(default=None, alias="closedAt")
|
51
|
+
archived_at: Optional[datetime] = Field(default=None, alias="archivedAt")
|
52
|
+
# Optional fields that may not be in all responses
|
53
|
+
source: Optional[str] = None
|
54
|
+
started_on: Optional[datetime] = Field(default=None, alias="startedOn")
|
55
|
+
total_days: int = Field(default=0, alias="totalDays")
|
56
|
+
total_endpoints: int = Field(default=0, alias="totalEndpoints")
|
57
|
+
closed_on: Optional[datetime] = Field(default=None, alias="closedOn")
|
58
|
+
|
59
|
+
|
60
|
+
class CaseActivity(AIRBaseModel):
|
61
|
+
"""Case activity model."""
|
62
|
+
|
63
|
+
id: Optional[str] = Field(default=None, alias="_id")
|
64
|
+
case_id: Optional[str] = Field(default=None, alias="caseId")
|
65
|
+
user_id: Optional[str] = Field(default=None, alias="userId")
|
66
|
+
user: Optional[Any] = None
|
67
|
+
activity_type: Optional[str] = Field(default=None, alias="activityType")
|
68
|
+
description: Optional[str] = None
|
69
|
+
details: Dict[str, Any] = {}
|
70
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
71
|
+
# Legacy fields that may still exist
|
72
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
73
|
+
type: Optional[str] = None
|
74
|
+
performed_by: Optional[str] = Field(default=None, alias="performedBy")
|
75
|
+
data: Optional[Any] = None
|
76
|
+
organization_ids: List[int] = Field(default=[], alias="organizationIds")
|
77
|
+
|
78
|
+
|
79
|
+
class CaseEndpoint(AIRBaseModel):
|
80
|
+
"""Case endpoint model."""
|
81
|
+
|
82
|
+
platform: str
|
83
|
+
tags: List[str] = []
|
84
|
+
isolation_status: str = Field(alias="isolationStatus")
|
85
|
+
id: str = Field(alias="_id")
|
86
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
87
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
88
|
+
organization_id: int = Field(default=0, alias="organizationId")
|
89
|
+
ip_address: Optional[str] = Field(default=None, alias="ipAddress")
|
90
|
+
name: str
|
91
|
+
group_id: Optional[str] = Field(default=None, alias="groupId")
|
92
|
+
group_full_path: Optional[str] = Field(default=None, alias="groupFullPath")
|
93
|
+
os: str
|
94
|
+
is_server: bool = Field(default=False, alias="isServer")
|
95
|
+
is_managed: bool = Field(default=True, alias="isManaged")
|
96
|
+
last_seen: Optional[datetime] = Field(default=None, alias="lastSeen")
|
97
|
+
version: Optional[str] = None
|
98
|
+
version_no: Optional[int] = Field(default=None, alias="versionNo")
|
99
|
+
registered_at: Optional[datetime] = Field(default=None, alias="registeredAt")
|
100
|
+
security_token: Optional[str] = Field(default=None, alias="securityToken")
|
101
|
+
online_status: str = Field(alias="onlineStatus")
|
102
|
+
issues: List[str] = []
|
103
|
+
label: Optional[str] = None
|
104
|
+
waiting_for_version_update_fix: bool = Field(default=False, alias="waitingForVersionUpdateFix")
|
105
|
+
|
106
|
+
|
107
|
+
class CaseTask(AIRBaseModel):
|
108
|
+
"""Case task model."""
|
109
|
+
|
110
|
+
id: str = Field(alias="_id")
|
111
|
+
task_id: str = Field(alias="taskId")
|
112
|
+
name: str
|
113
|
+
type: str
|
114
|
+
endpoint_id: str = Field(alias="endpointId")
|
115
|
+
endpoint_name: str = Field(alias="endpointName")
|
116
|
+
organization_id: int = Field(default=0, alias="organizationId")
|
117
|
+
status: str
|
118
|
+
recurrence: Optional[str] = None
|
119
|
+
progress: int = 0
|
120
|
+
duration: Optional[int] = None
|
121
|
+
case_ids: List[str] = Field(default=[], alias="caseIds")
|
122
|
+
is_comparable: bool = Field(default=False, alias="isComparable")
|
123
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
124
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
125
|
+
response: Optional[Any] = None
|
126
|
+
|
127
|
+
|
128
|
+
class UserProfile(AIRBaseModel):
|
129
|
+
"""User profile model."""
|
130
|
+
|
131
|
+
name: str
|
132
|
+
surname: str
|
133
|
+
department: str
|
134
|
+
|
135
|
+
|
136
|
+
class Role(AIRBaseModel):
|
137
|
+
"""User role model."""
|
138
|
+
|
139
|
+
id: str = Field(alias="_id")
|
140
|
+
name: str
|
141
|
+
created_by: str = Field(alias="createdBy")
|
142
|
+
tag: str
|
143
|
+
privilege_types: List[str] = Field(default=[], alias="privilegeTypes")
|
144
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
145
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
146
|
+
|
147
|
+
|
148
|
+
class User(AIRBaseModel):
|
149
|
+
"""User model."""
|
150
|
+
|
151
|
+
id: str = Field(alias="_id")
|
152
|
+
email: str
|
153
|
+
username: str
|
154
|
+
organization_ids: Union[List[int], str] = Field(default=[], alias="organizationIds")
|
155
|
+
strategy: str
|
156
|
+
profile: UserProfile
|
157
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
158
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
159
|
+
roles: List[Role] = []
|
160
|
+
|
161
|
+
@field_validator('organization_ids', mode='before')
|
162
|
+
@classmethod
|
163
|
+
def parse_organization_ids(cls, v):
|
164
|
+
"""Handle organizationIds which can be a list of ints or the string 'ALL'."""
|
165
|
+
if isinstance(v, str):
|
166
|
+
# Handle the "ALL" case - return as is for now
|
167
|
+
return v
|
168
|
+
elif isinstance(v, list):
|
169
|
+
# Ensure all items are integers
|
170
|
+
return [int(item) if not isinstance(item, int) else item for item in v]
|
171
|
+
else:
|
172
|
+
# Default to empty list for other cases
|
173
|
+
return []
|
174
|
+
|
175
|
+
|
176
|
+
class CaseFilter(Filter):
|
177
|
+
"""Filter for case queries."""
|
178
|
+
|
179
|
+
name: Optional[str] = None
|
180
|
+
status: Optional[List[CaseStatus]] = None
|
181
|
+
owner_user_id: Optional[str] = None
|
182
|
+
assigned_user_ids: Optional[List[str]] = None
|
183
|
+
visibility: Optional[str] = None
|
184
|
+
source: Optional[str] = None
|
185
|
+
|
186
|
+
|
187
|
+
class CaseActivityFilter(Filter):
|
188
|
+
"""Filter for case activity queries."""
|
189
|
+
|
190
|
+
performed_by: Optional[List[str]] = None # User IDs who performed the activities
|
191
|
+
types: Optional[List[str]] = None # Activity types to filter
|
192
|
+
search_term: Optional[str] = None # Search term for activity descriptions
|
193
|
+
occurred_at: Optional[str] = None # Date range filter
|
194
|
+
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
195
|
+
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
196
|
+
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
197
|
+
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
198
|
+
|
199
|
+
|
200
|
+
class CaseEndpointFilter(Filter):
|
201
|
+
"""Filter for case endpoint queries."""
|
202
|
+
|
203
|
+
organization_ids: Optional[List[int]] = None # Required organization IDs
|
204
|
+
search_term: Optional[str] = None # Search term for endpoint names
|
205
|
+
name: Optional[str] = None # Endpoint name filter
|
206
|
+
ip_address: Optional[str] = None # IP address filter
|
207
|
+
group_id: Optional[str] = None # Group ID filter
|
208
|
+
group_full_path: Optional[str] = None # Group full path filter
|
209
|
+
label: Optional[str] = None # Label filter
|
210
|
+
last_seen: Optional[str] = None # Last seen date range (e.g., "2023-03-06T21:00:00.000Z,2023-03-24T21:00:00.000Z")
|
211
|
+
managed_status: Optional[List[str]] = None # Managed status filter (unmanaged, managed, off-network)
|
212
|
+
isolation_status: Optional[List[str]] = None # Isolation status filter (isolating, isolated, unisolating, unisolated)
|
213
|
+
platform: Optional[List[str]] = None # Platform filter (windows, linux, darwin)
|
214
|
+
issue: Optional[List[str]] = None # Issue filter (unreachable, old-version, update-required)
|
215
|
+
online_status: Optional[List[str]] = None # Online status filter (online, offline)
|
216
|
+
tags: Optional[List[str]] = None # Tags filter
|
217
|
+
version: Optional[str] = None # Version filter
|
218
|
+
policy: Optional[str] = None # Policy filter
|
219
|
+
included_endpoint_ids: Optional[List[str]] = None # Included endpoint IDs
|
220
|
+
excluded_endpoint_ids: Optional[List[str]] = None # Excluded endpoint IDs
|
221
|
+
aws_regions: Optional[List[str]] = None # AWS regions filter
|
222
|
+
azure_regions: Optional[List[str]] = None # Azure regions filter
|
223
|
+
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
224
|
+
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
225
|
+
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
226
|
+
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
227
|
+
|
228
|
+
|
229
|
+
class CaseTaskFilter(Filter):
|
230
|
+
"""Filter for case task queries."""
|
231
|
+
|
232
|
+
organization_ids: Optional[List[int]] = None # Required organization IDs
|
233
|
+
search_term: Optional[str] = None # Search term for task names
|
234
|
+
name: Optional[str] = None # Task name filter
|
235
|
+
endpoint_ids: Optional[List[str]] = None # Endpoint IDs filter
|
236
|
+
execution_type: Optional[str] = None # Execution type filter (instant, scheduled)
|
237
|
+
status: Optional[str] = None # Status filter (scheduled, assigned, processing, completed, failed, expired, cancelled, compressing, uploading, analyzing, partially-completed)
|
238
|
+
type: Optional[str] = None # Task type filter (acquisition, offline-acquisition, triage, offline-triage, investigation, interact-shell, baseline-comparison, baseline-acquisition, acquire-image)
|
239
|
+
asset_names: Optional[str] = None # Comma separated asset names
|
240
|
+
started_by: Optional[str] = None # Started by user filter
|
241
|
+
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
242
|
+
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
243
|
+
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
244
|
+
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
245
|
+
|
246
|
+
|
247
|
+
class CaseUserFilter(Filter):
|
248
|
+
"""Filter for case user queries."""
|
249
|
+
|
250
|
+
organization_ids: Optional[List[int]] = None # Required organization IDs
|
251
|
+
search_term: Optional[str] = None # Search term for user filtering
|
252
|
+
page_number: Optional[int] = Field(default=1, ge=1) # Page number (min: 1)
|
253
|
+
page_size: Optional[int] = Field(default=10, ge=1) # Page size (min: 1)
|
254
|
+
sort_by: Optional[str] = Field(default="createdAt") # Sort field
|
255
|
+
sort_type: Optional[Literal["ASC", "DESC"]] = Field(default="ASC") # Sort direction
|
256
|
+
|
257
|
+
|
258
|
+
class CreateCaseRequest(AIRBaseModel):
|
259
|
+
"""Request model for creating a case."""
|
260
|
+
|
261
|
+
organization_id: int = 0
|
262
|
+
name: str
|
263
|
+
owner_user_id: str
|
264
|
+
visibility: str
|
265
|
+
assigned_user_ids: List[str] = []
|
266
|
+
|
267
|
+
|
268
|
+
class UpdateCaseRequest(AIRBaseModel):
|
269
|
+
"""Request model for updating a case."""
|
270
|
+
|
271
|
+
name: Optional[str] = None
|
272
|
+
owner_user_id: Optional[str] = None
|
273
|
+
visibility: Optional[str] = None
|
274
|
+
assigned_user_ids: Optional[List[str]] = None
|
275
|
+
status: Optional[CaseStatus] = None
|
276
276
|
notes: Optional[List[Any]] = None
|