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,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