binalyze-air-sdk 1.0.1__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 -0
- binalyze_air/apis/__init__.py +27 -0
- binalyze_air/apis/authentication.py +27 -0
- binalyze_air/apis/auto_asset_tags.py +75 -0
- binalyze_air/apis/endpoints.py +22 -0
- binalyze_air/apis/event_subscription.py +97 -0
- binalyze_air/apis/evidence.py +53 -0
- binalyze_air/apis/evidences.py +216 -0
- binalyze_air/apis/interact.py +36 -0
- binalyze_air/apis/params.py +40 -0
- binalyze_air/apis/settings.py +27 -0
- binalyze_air/apis/user_management.py +74 -0
- binalyze_air/apis/users.py +68 -0
- binalyze_air/apis/webhooks.py +231 -0
- binalyze_air/base.py +133 -0
- binalyze_air/client.py +1338 -0
- binalyze_air/commands/__init__.py +146 -0
- binalyze_air/commands/acquisitions.py +387 -0
- binalyze_air/commands/assets.py +363 -0
- binalyze_air/commands/authentication.py +37 -0
- binalyze_air/commands/auto_asset_tags.py +231 -0
- binalyze_air/commands/baseline.py +396 -0
- binalyze_air/commands/cases.py +603 -0
- binalyze_air/commands/event_subscription.py +102 -0
- binalyze_air/commands/evidences.py +988 -0
- binalyze_air/commands/interact.py +58 -0
- binalyze_air/commands/organizations.py +221 -0
- binalyze_air/commands/policies.py +203 -0
- binalyze_air/commands/settings.py +29 -0
- binalyze_air/commands/tasks.py +56 -0
- binalyze_air/commands/triage.py +360 -0
- binalyze_air/commands/user_management.py +126 -0
- binalyze_air/commands/users.py +101 -0
- binalyze_air/config.py +245 -0
- binalyze_air/exceptions.py +50 -0
- binalyze_air/http_client.py +306 -0
- binalyze_air/models/__init__.py +285 -0
- binalyze_air/models/acquisitions.py +251 -0
- binalyze_air/models/assets.py +439 -0
- binalyze_air/models/audit.py +273 -0
- binalyze_air/models/authentication.py +70 -0
- binalyze_air/models/auto_asset_tags.py +117 -0
- binalyze_air/models/baseline.py +232 -0
- binalyze_air/models/cases.py +276 -0
- binalyze_air/models/endpoints.py +76 -0
- binalyze_air/models/event_subscription.py +172 -0
- binalyze_air/models/evidence.py +66 -0
- binalyze_air/models/evidences.py +349 -0
- binalyze_air/models/interact.py +136 -0
- binalyze_air/models/organizations.py +294 -0
- binalyze_air/models/params.py +128 -0
- binalyze_air/models/policies.py +250 -0
- binalyze_air/models/settings.py +84 -0
- binalyze_air/models/tasks.py +149 -0
- binalyze_air/models/triage.py +143 -0
- binalyze_air/models/user_management.py +97 -0
- binalyze_air/models/users.py +82 -0
- binalyze_air/queries/__init__.py +134 -0
- binalyze_air/queries/acquisitions.py +156 -0
- binalyze_air/queries/assets.py +105 -0
- binalyze_air/queries/audit.py +417 -0
- binalyze_air/queries/authentication.py +56 -0
- binalyze_air/queries/auto_asset_tags.py +60 -0
- binalyze_air/queries/baseline.py +185 -0
- binalyze_air/queries/cases.py +293 -0
- binalyze_air/queries/endpoints.py +25 -0
- binalyze_air/queries/event_subscription.py +55 -0
- binalyze_air/queries/evidence.py +140 -0
- binalyze_air/queries/evidences.py +280 -0
- binalyze_air/queries/interact.py +28 -0
- binalyze_air/queries/organizations.py +223 -0
- binalyze_air/queries/params.py +115 -0
- binalyze_air/queries/policies.py +150 -0
- binalyze_air/queries/settings.py +20 -0
- binalyze_air/queries/tasks.py +82 -0
- binalyze_air/queries/triage.py +231 -0
- binalyze_air/queries/user_management.py +83 -0
- binalyze_air/queries/users.py +69 -0
- binalyze_air_sdk-1.0.1.dist-info/METADATA +635 -0
- binalyze_air_sdk-1.0.1.dist-info/RECORD +82 -0
- binalyze_air_sdk-1.0.1.dist-info/WHEEL +5 -0
- binalyze_air_sdk-1.0.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,294 @@
|
|
1
|
+
"""
|
2
|
+
Organization-related data models for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional, Dict, Any, Union
|
6
|
+
from datetime import datetime
|
7
|
+
from enum import Enum
|
8
|
+
from pydantic import Field
|
9
|
+
|
10
|
+
from ..base import AIRBaseModel, Filter
|
11
|
+
|
12
|
+
|
13
|
+
class OrganizationStatus(str, Enum):
|
14
|
+
"""Organization status."""
|
15
|
+
ACTIVE = "active"
|
16
|
+
SUSPENDED = "suspended"
|
17
|
+
INACTIVE = "inactive"
|
18
|
+
|
19
|
+
|
20
|
+
class UserRoleType(str, Enum):
|
21
|
+
"""User role type in organization."""
|
22
|
+
ADMIN = "admin"
|
23
|
+
USER = "user"
|
24
|
+
VIEWER = "viewer"
|
25
|
+
ANALYST = "analyst"
|
26
|
+
|
27
|
+
|
28
|
+
class FilterOption(AIRBaseModel):
|
29
|
+
"""Filter option model for API response metadata."""
|
30
|
+
|
31
|
+
name: str
|
32
|
+
type: str # text, select, etc.
|
33
|
+
options: List[Any] = []
|
34
|
+
filter_url: Optional[str] = Field(default=None, alias="filterUrl")
|
35
|
+
|
36
|
+
|
37
|
+
class Organization(AIRBaseModel):
|
38
|
+
"""Organization model with complete field mapping."""
|
39
|
+
|
40
|
+
id: int = Field(alias="_id")
|
41
|
+
name: str
|
42
|
+
note: Optional[str] = None
|
43
|
+
owner: Optional[str] = None
|
44
|
+
is_default: bool = Field(default=False, alias="isDefault")
|
45
|
+
shareable_deployment_enabled: bool = Field(default=True, alias="shareableDeploymentEnabled")
|
46
|
+
deployment_token: Optional[str] = Field(default=None, alias="deploymentToken")
|
47
|
+
contact: Dict[str, Any] = {}
|
48
|
+
total_endpoints: int = Field(default=0, alias="totalEndpoints")
|
49
|
+
tags: List[str] = []
|
50
|
+
statistics: Optional[Dict[str, Any]] = None # Organization statistics
|
51
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
52
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
53
|
+
|
54
|
+
|
55
|
+
class UserProfile(AIRBaseModel):
|
56
|
+
"""User profile information."""
|
57
|
+
|
58
|
+
name: Optional[str] = None
|
59
|
+
surname: Optional[str] = None
|
60
|
+
department: Optional[str] = None
|
61
|
+
|
62
|
+
|
63
|
+
class UserGroup(AIRBaseModel):
|
64
|
+
"""User group information."""
|
65
|
+
|
66
|
+
id: str
|
67
|
+
name: str
|
68
|
+
organization_ids: List[int] = Field(default=[], alias="organizationIds")
|
69
|
+
|
70
|
+
|
71
|
+
class UserRole(AIRBaseModel):
|
72
|
+
"""User role information with full privileges."""
|
73
|
+
|
74
|
+
id: str = Field(alias="_id")
|
75
|
+
name: str
|
76
|
+
tag: str
|
77
|
+
created_by: str = Field(alias="createdBy")
|
78
|
+
privileges: List[str] = []
|
79
|
+
privilege_types: List[str] = Field(default=[], alias="privilegeTypes")
|
80
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
81
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
82
|
+
|
83
|
+
|
84
|
+
class OrganizationUser(AIRBaseModel):
|
85
|
+
"""Enhanced organization user model with complete field mapping."""
|
86
|
+
|
87
|
+
# Core fields
|
88
|
+
id: str = Field(alias="_id")
|
89
|
+
email: str
|
90
|
+
username: str
|
91
|
+
strategy: Optional[str] = None
|
92
|
+
|
93
|
+
# Profile information
|
94
|
+
profile: Optional[UserProfile] = None
|
95
|
+
|
96
|
+
# Role and permission information
|
97
|
+
roles: List[UserRole] = []
|
98
|
+
groups: List[UserGroup] = []
|
99
|
+
|
100
|
+
# Organization and permission data
|
101
|
+
organization_ids: Optional[Union[str, List[int]]] = Field(default=None, alias="organizationIds") # Can be "ALL" or list
|
102
|
+
|
103
|
+
# Boolean flags
|
104
|
+
has_password: bool = Field(default=False, alias="hasPassword")
|
105
|
+
tfa_enabled: bool = Field(default=False, alias="tfaEnabled")
|
106
|
+
is_authorized_for_all_organizations: bool = Field(default=False, alias="isAuthorizedForAllOrganizations")
|
107
|
+
is_global_admin: bool = Field(default=False, alias="isGlobalAdmin")
|
108
|
+
is_organization_admin: bool = Field(default=False, alias="isOrganizationAdmin")
|
109
|
+
is_not_in_organizations: bool = Field(default=False, alias="isNotInOrganizations")
|
110
|
+
|
111
|
+
# Timestamps
|
112
|
+
created_at: Optional[datetime] = Field(default=None, alias="createdAt")
|
113
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
114
|
+
|
115
|
+
# Legacy fields for backward compatibility
|
116
|
+
first_name: Optional[str] = None
|
117
|
+
last_name: Optional[str] = None
|
118
|
+
role: Optional[str] = None
|
119
|
+
organization_id: Optional[int] = None
|
120
|
+
last_login: Optional[datetime] = None
|
121
|
+
is_active: bool = True
|
122
|
+
permissions: List[str] = []
|
123
|
+
|
124
|
+
|
125
|
+
class OrganizationUsersPaginatedResponse(AIRBaseModel):
|
126
|
+
"""Complete paginated response for organization users endpoint."""
|
127
|
+
|
128
|
+
entities: List[OrganizationUser]
|
129
|
+
filters: List[FilterOption] = []
|
130
|
+
sortables: List[str] = []
|
131
|
+
total_entity_count: int = Field(default=0, alias="totalEntityCount")
|
132
|
+
current_page: int = Field(default=1, alias="currentPage")
|
133
|
+
page_size: int = Field(default=10, alias="pageSize")
|
134
|
+
previous_page: int = Field(default=0, alias="previousPage")
|
135
|
+
total_page_count: int = Field(default=1, alias="totalPageCount")
|
136
|
+
next_page: int = Field(default=2, alias="nextPage")
|
137
|
+
|
138
|
+
|
139
|
+
class OrganizationRole(AIRBaseModel):
|
140
|
+
"""Organization role model."""
|
141
|
+
|
142
|
+
id: str
|
143
|
+
name: str
|
144
|
+
description: Optional[str] = None
|
145
|
+
organization_id: int
|
146
|
+
permissions: List[str] = []
|
147
|
+
created_at: Optional[datetime] = None
|
148
|
+
updated_at: Optional[datetime] = None
|
149
|
+
created_by: Optional[str] = None
|
150
|
+
is_system: bool = False
|
151
|
+
user_count: int = 0
|
152
|
+
|
153
|
+
|
154
|
+
class OrganizationLicense(AIRBaseModel):
|
155
|
+
"""Organization license model."""
|
156
|
+
|
157
|
+
id: str
|
158
|
+
organization_id: int
|
159
|
+
license_type: str
|
160
|
+
total_licenses: int = 0
|
161
|
+
used_licenses: int = 0
|
162
|
+
valid_from: Optional[datetime] = None
|
163
|
+
valid_until: Optional[datetime] = None
|
164
|
+
features: List[str] = []
|
165
|
+
is_active: bool = True
|
166
|
+
|
167
|
+
|
168
|
+
class OrganizationSettings(AIRBaseModel):
|
169
|
+
"""Organization settings model."""
|
170
|
+
|
171
|
+
organization_id: int
|
172
|
+
retention_policy: Dict[str, Any] = {}
|
173
|
+
security_settings: Dict[str, Any] = {}
|
174
|
+
notification_settings: Dict[str, Any] = {}
|
175
|
+
api_settings: Dict[str, Any] = {}
|
176
|
+
custom_settings: Dict[str, Any] = {}
|
177
|
+
|
178
|
+
|
179
|
+
class OrganizationFilter(Filter):
|
180
|
+
"""Filter for organization queries with complete parameter support."""
|
181
|
+
|
182
|
+
name: Optional[str] = None
|
183
|
+
search_term: Optional[str] = None
|
184
|
+
|
185
|
+
def to_params(self) -> Dict[str, Any]:
|
186
|
+
"""Convert filter to API parameters."""
|
187
|
+
params = {}
|
188
|
+
if self.name:
|
189
|
+
params["filter[name]"] = self.name
|
190
|
+
if self.search_term:
|
191
|
+
params["filter[searchTerm]"] = self.search_term
|
192
|
+
return params
|
193
|
+
|
194
|
+
|
195
|
+
class OrganizationsPaginatedResponse(AIRBaseModel):
|
196
|
+
"""Complete paginated response for organizations list endpoint."""
|
197
|
+
|
198
|
+
entities: List[Organization]
|
199
|
+
filters: List[FilterOption] = []
|
200
|
+
sortables: List[str] = []
|
201
|
+
total_entity_count: int = Field(default=0, alias="totalEntityCount")
|
202
|
+
current_page: int = Field(default=1, alias="currentPage")
|
203
|
+
page_size: int = Field(default=10, alias="pageSize")
|
204
|
+
previous_page: int = Field(default=0, alias="previousPage")
|
205
|
+
total_page_count: int = Field(default=1, alias="totalPageCount")
|
206
|
+
next_page: int = Field(default=2, alias="nextPage")
|
207
|
+
|
208
|
+
|
209
|
+
# Request models for organization operations
|
210
|
+
class CreateOrganizationRequest(AIRBaseModel):
|
211
|
+
"""Create organization request model with complete field mapping."""
|
212
|
+
|
213
|
+
name: str
|
214
|
+
shareable_deployment_enabled: bool = Field(default=True, alias="shareableDeploymentEnabled")
|
215
|
+
note: Optional[str] = None
|
216
|
+
contact: Optional[Dict[str, Any]] = None
|
217
|
+
tags: Optional[List[str]] = None
|
218
|
+
|
219
|
+
|
220
|
+
class UpdateOrganizationRequest(AIRBaseModel):
|
221
|
+
"""Update organization request model with complete field mapping."""
|
222
|
+
|
223
|
+
name: Optional[str] = None
|
224
|
+
note: Optional[str] = None
|
225
|
+
owner: Optional[str] = None # Added missing owner field
|
226
|
+
contact: Optional[Dict[str, Any]] = None
|
227
|
+
tags: Optional[List[str]] = None
|
228
|
+
|
229
|
+
|
230
|
+
class AddUserToOrganizationRequest(AIRBaseModel):
|
231
|
+
"""Add user to organization request model."""
|
232
|
+
|
233
|
+
user_id: str
|
234
|
+
email: str
|
235
|
+
username: str
|
236
|
+
role: Optional[str] = None
|
237
|
+
|
238
|
+
|
239
|
+
class AssignUsersToOrganizationRequest(AIRBaseModel):
|
240
|
+
"""Assign multiple users to organization request model."""
|
241
|
+
|
242
|
+
user_ids: List[str] = Field(alias="userIds")
|
243
|
+
|
244
|
+
|
245
|
+
class AddTagsToOrganizationRequest(AIRBaseModel):
|
246
|
+
"""Add tags to organization request model."""
|
247
|
+
|
248
|
+
tags: List[str]
|
249
|
+
|
250
|
+
|
251
|
+
class DeleteTagsFromOrganizationRequest(AIRBaseModel):
|
252
|
+
"""Delete tags from organization request model."""
|
253
|
+
|
254
|
+
tags: List[str]
|
255
|
+
|
256
|
+
|
257
|
+
class UpdateShareableDeploymentSettingsRequest(AIRBaseModel):
|
258
|
+
"""Update shareable deployment settings request model."""
|
259
|
+
|
260
|
+
status: bool
|
261
|
+
|
262
|
+
|
263
|
+
class UpdateDeploymentTokenRequest(AIRBaseModel):
|
264
|
+
"""Update deployment token request model."""
|
265
|
+
|
266
|
+
# Empty request body - the API generates a new token automatically
|
267
|
+
pass
|
268
|
+
|
269
|
+
|
270
|
+
class CheckOrganizationNameExistsResponse(AIRBaseModel):
|
271
|
+
"""Response model for checking if organization name exists."""
|
272
|
+
|
273
|
+
success: bool
|
274
|
+
result: bool
|
275
|
+
status_code: int = Field(alias="statusCode")
|
276
|
+
errors: List[str] = []
|
277
|
+
|
278
|
+
|
279
|
+
class ShareableDeploymentInfoResponse(AIRBaseModel):
|
280
|
+
"""Response model for shareable deployment information."""
|
281
|
+
|
282
|
+
success: bool
|
283
|
+
result: Optional[Dict[str, Any]] = None
|
284
|
+
status_code: int = Field(alias="statusCode")
|
285
|
+
errors: List[str] = []
|
286
|
+
|
287
|
+
|
288
|
+
class DeploymentTokenUpdateResponse(AIRBaseModel):
|
289
|
+
"""Response model for deployment token update."""
|
290
|
+
|
291
|
+
success: bool
|
292
|
+
result: Optional[Dict[str, str]] = None # Contains new token
|
293
|
+
status_code: int = Field(alias="statusCode")
|
294
|
+
errors: List[str] = []
|
@@ -0,0 +1,128 @@
|
|
1
|
+
"""
|
2
|
+
Params API models for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional, Dict, Any
|
6
|
+
from enum import Enum
|
7
|
+
from pydantic import Field
|
8
|
+
|
9
|
+
from ..base import AIRBaseModel
|
10
|
+
|
11
|
+
|
12
|
+
class ArtifactType(str, Enum):
|
13
|
+
"""Acquisition artifact types."""
|
14
|
+
FILE = "file"
|
15
|
+
REGISTRY = "registry"
|
16
|
+
MEMORY = "memory"
|
17
|
+
NETWORK = "network"
|
18
|
+
PROCESS = "process"
|
19
|
+
EVENT_LOG = "event_log"
|
20
|
+
PREFETCH = "prefetch"
|
21
|
+
BROWSER = "browser"
|
22
|
+
SYSTEM = "system"
|
23
|
+
|
24
|
+
|
25
|
+
class ArtifactCategory(str, Enum):
|
26
|
+
"""Artifact categories."""
|
27
|
+
FORENSICS = "forensics"
|
28
|
+
MALWARE = "malware"
|
29
|
+
NETWORK = "network"
|
30
|
+
SYSTEM = "system"
|
31
|
+
BROWSER = "browser"
|
32
|
+
EMAIL = "email"
|
33
|
+
CHAT = "chat"
|
34
|
+
CLOUD = "cloud"
|
35
|
+
|
36
|
+
|
37
|
+
class Platform(str, Enum):
|
38
|
+
"""Supported platforms."""
|
39
|
+
WINDOWS = "windows"
|
40
|
+
LINUX = "linux"
|
41
|
+
DARWIN = "darwin"
|
42
|
+
MACOS = "macos"
|
43
|
+
|
44
|
+
|
45
|
+
class AcquisitionArtifact(AIRBaseModel):
|
46
|
+
"""Acquisition artifact model based on API response structure."""
|
47
|
+
|
48
|
+
name: str
|
49
|
+
desc: str = Field(alias="desc")
|
50
|
+
type: str = Field(alias="type")
|
51
|
+
|
52
|
+
# Additional fields for SDK processing
|
53
|
+
group: Optional[str] = None
|
54
|
+
platform: Optional[str] = None
|
55
|
+
|
56
|
+
|
57
|
+
class EDiscoveryPattern(AIRBaseModel):
|
58
|
+
"""E-Discovery pattern model based on API response structure."""
|
59
|
+
|
60
|
+
name: str
|
61
|
+
pattern: str
|
62
|
+
|
63
|
+
# Additional fields for SDK processing
|
64
|
+
category: Optional[str] = None
|
65
|
+
|
66
|
+
|
67
|
+
class AcquisitionEvidence(AIRBaseModel):
|
68
|
+
"""Acquisition evidence model based on API response structure."""
|
69
|
+
|
70
|
+
name: str
|
71
|
+
desc: str = Field(alias="desc")
|
72
|
+
type: str = Field(alias="type")
|
73
|
+
|
74
|
+
# Additional fields for SDK processing
|
75
|
+
group: Optional[str] = None
|
76
|
+
platform: Optional[str] = None
|
77
|
+
|
78
|
+
|
79
|
+
class DroneAnalyzer(AIRBaseModel):
|
80
|
+
"""Drone analyzer model with proper field mapping."""
|
81
|
+
|
82
|
+
id: str = Field(alias="Id")
|
83
|
+
name: str = Field(alias="Name")
|
84
|
+
default_enabled: bool = Field(alias="DefaultEnabled")
|
85
|
+
platforms: List[str] = Field(default=[], alias="Platforms")
|
86
|
+
o_ses: List[str] = Field(default=[], alias="OSes")
|
87
|
+
|
88
|
+
# Computed properties can be added as methods if needed
|
89
|
+
|
90
|
+
|
91
|
+
# API Response wrapper models for structured responses
|
92
|
+
class AcquisitionArtifactGroup(AIRBaseModel):
|
93
|
+
"""Group of acquisition artifacts."""
|
94
|
+
|
95
|
+
group: str
|
96
|
+
items: List[AcquisitionArtifact]
|
97
|
+
|
98
|
+
|
99
|
+
class AcquisitionArtifactsResponse(AIRBaseModel):
|
100
|
+
"""Full response structure for acquisition artifacts."""
|
101
|
+
|
102
|
+
windows: List[AcquisitionArtifactGroup] = []
|
103
|
+
linux: List[AcquisitionArtifactGroup] = []
|
104
|
+
macos: List[AcquisitionArtifactGroup] = []
|
105
|
+
aix: List[AcquisitionArtifactGroup] = []
|
106
|
+
|
107
|
+
|
108
|
+
class EDiscoveryCategory(AIRBaseModel):
|
109
|
+
"""E-Discovery pattern category."""
|
110
|
+
|
111
|
+
category: str
|
112
|
+
applications: List[EDiscoveryPattern]
|
113
|
+
|
114
|
+
|
115
|
+
class AcquisitionEvidenceGroup(AIRBaseModel):
|
116
|
+
"""Group of acquisition evidences."""
|
117
|
+
|
118
|
+
group: str
|
119
|
+
items: List[AcquisitionEvidence]
|
120
|
+
|
121
|
+
|
122
|
+
class AcquisitionEvidencesResponse(AIRBaseModel):
|
123
|
+
"""Full response structure for acquisition evidences."""
|
124
|
+
|
125
|
+
windows: List[AcquisitionEvidenceGroup] = []
|
126
|
+
linux: List[AcquisitionEvidenceGroup] = []
|
127
|
+
macos: List[AcquisitionEvidenceGroup] = []
|
128
|
+
aix: List[AcquisitionEvidenceGroup] = []
|
@@ -0,0 +1,250 @@
|
|
1
|
+
"""
|
2
|
+
Policy-related data 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, Filter, PaginatedResponse
|
11
|
+
|
12
|
+
|
13
|
+
class PolicyType(str, Enum):
|
14
|
+
"""Policy type."""
|
15
|
+
ACQUISITION = "acquisition"
|
16
|
+
SECURITY = "security"
|
17
|
+
COMPLIANCE = "compliance"
|
18
|
+
CUSTOM = "custom"
|
19
|
+
|
20
|
+
|
21
|
+
class PolicyStatus(str, Enum):
|
22
|
+
"""Policy status."""
|
23
|
+
ACTIVE = "active"
|
24
|
+
INACTIVE = "inactive"
|
25
|
+
DRAFT = "draft"
|
26
|
+
|
27
|
+
|
28
|
+
class PolicyCondition(AIRBaseModel):
|
29
|
+
"""Policy condition model based on API structure."""
|
30
|
+
|
31
|
+
# For leaf conditions
|
32
|
+
field: Optional[str] = None
|
33
|
+
operator: Optional[str] = None
|
34
|
+
value: Optional[Any] = None
|
35
|
+
|
36
|
+
# For nested conditions (when this is a group)
|
37
|
+
conditions: Optional[List['PolicyCondition']] = None
|
38
|
+
|
39
|
+
|
40
|
+
class PolicyAction(AIRBaseModel):
|
41
|
+
"""Policy action model."""
|
42
|
+
|
43
|
+
type: str
|
44
|
+
parameters: Dict[str, Any] = {}
|
45
|
+
enabled: bool = True
|
46
|
+
|
47
|
+
|
48
|
+
class PolicyRule(AIRBaseModel):
|
49
|
+
"""Policy rule model."""
|
50
|
+
|
51
|
+
id: str
|
52
|
+
name: str
|
53
|
+
description: Optional[str] = None
|
54
|
+
conditions: List[PolicyCondition] = []
|
55
|
+
actions: List[PolicyAction] = []
|
56
|
+
enabled: bool = True
|
57
|
+
priority: int = 0
|
58
|
+
|
59
|
+
|
60
|
+
class PolicyFilterStructure(AIRBaseModel):
|
61
|
+
"""Policy filter model based on API structure."""
|
62
|
+
|
63
|
+
operator: str
|
64
|
+
conditions: List[PolicyCondition]
|
65
|
+
|
66
|
+
|
67
|
+
class PolicyCpuSettings(AIRBaseModel):
|
68
|
+
"""Policy CPU settings."""
|
69
|
+
|
70
|
+
limit: int
|
71
|
+
|
72
|
+
|
73
|
+
class PolicySaveToSettings(AIRBaseModel):
|
74
|
+
"""Policy save-to settings for a platform."""
|
75
|
+
|
76
|
+
location: str
|
77
|
+
path: Optional[str] = None
|
78
|
+
repository_id: Optional[str] = Field(default=None, alias="repositoryId")
|
79
|
+
use_most_free_volume: bool = Field(default=True, alias="useMostFreeVolume")
|
80
|
+
volume: Optional[str] = None
|
81
|
+
tmp: Optional[str] = None
|
82
|
+
|
83
|
+
|
84
|
+
class PolicySaveTo(AIRBaseModel):
|
85
|
+
"""Policy save-to settings for all platforms."""
|
86
|
+
|
87
|
+
windows: Optional[PolicySaveToSettings] = None
|
88
|
+
linux: Optional[PolicySaveToSettings] = None
|
89
|
+
macos: Optional[PolicySaveToSettings] = None
|
90
|
+
|
91
|
+
|
92
|
+
class PolicyEncryption(AIRBaseModel):
|
93
|
+
"""Policy encryption settings."""
|
94
|
+
|
95
|
+
enabled: bool
|
96
|
+
password: Optional[str] = None
|
97
|
+
|
98
|
+
|
99
|
+
class PolicyCompression(AIRBaseModel):
|
100
|
+
"""Policy compression settings."""
|
101
|
+
|
102
|
+
enabled: bool
|
103
|
+
encryption: Optional[PolicyEncryption] = None
|
104
|
+
|
105
|
+
|
106
|
+
class PolicySendTo(AIRBaseModel):
|
107
|
+
"""Policy send-to settings."""
|
108
|
+
|
109
|
+
location: str
|
110
|
+
repository_id: Optional[str] = Field(default=None, alias="repositoryId")
|
111
|
+
|
112
|
+
|
113
|
+
class Policy(AIRBaseModel):
|
114
|
+
"""Policy model based on API response structure."""
|
115
|
+
|
116
|
+
id: str = Field(alias="_id")
|
117
|
+
name: str
|
118
|
+
organization_ids: List[int] = Field(default=[], alias="organizationIds")
|
119
|
+
default: Optional[bool] = None
|
120
|
+
order: Optional[int] = None
|
121
|
+
created_by: Optional[str] = Field(default=None, alias="createdBy")
|
122
|
+
updated_at: Optional[datetime] = Field(default=None, alias="updatedAt")
|
123
|
+
|
124
|
+
# Policy configuration
|
125
|
+
filter: Optional[PolicyFilterStructure] = None
|
126
|
+
cpu: Optional[PolicyCpuSettings] = None
|
127
|
+
save_to: Optional[PolicySaveTo] = Field(default=None, alias="saveTo")
|
128
|
+
send_to: Optional[PolicySendTo] = Field(default=None, alias="sendTo")
|
129
|
+
compression: Optional[PolicyCompression] = None
|
130
|
+
|
131
|
+
# Optional fields that may be present
|
132
|
+
bandwidth: Optional[Dict[str, Any]] = None
|
133
|
+
disk_space: Optional[Dict[str, Any]] = Field(default=None, alias="diskSpace")
|
134
|
+
triage_local_drives_only: Optional[Dict[str, Any]] = Field(default=None, alias="triageLocalDrivesOnly")
|
135
|
+
isolation_allowed_ips: Optional[List[str]] = Field(default=None, alias="isolationAllowedIps")
|
136
|
+
isolation_allowed_processes: Optional[List[str]] = Field(default=None, alias="isolationAllowedProcesses")
|
137
|
+
|
138
|
+
|
139
|
+
class PolicyPriority(AIRBaseModel):
|
140
|
+
"""Policy priority update model."""
|
141
|
+
|
142
|
+
id: str = Field(alias="_id")
|
143
|
+
order: int
|
144
|
+
|
145
|
+
|
146
|
+
class PolicyMatchStats(AIRBaseModel):
|
147
|
+
"""Policy match statistics model."""
|
148
|
+
|
149
|
+
total_matches: int = Field(alias="totalMatches")
|
150
|
+
policy_matches: List[Dict[str, Any]] = Field(default=[], alias="policyMatches")
|
151
|
+
|
152
|
+
|
153
|
+
class PolicyAssignment(AIRBaseModel):
|
154
|
+
"""Policy assignment model."""
|
155
|
+
|
156
|
+
id: str
|
157
|
+
policy_id: str
|
158
|
+
endpoint_id: str
|
159
|
+
assigned_at: Optional[datetime] = None
|
160
|
+
assigned_by: str
|
161
|
+
status: str = "active"
|
162
|
+
|
163
|
+
|
164
|
+
class PolicyExecution(AIRBaseModel):
|
165
|
+
"""Policy execution result model."""
|
166
|
+
|
167
|
+
id: str
|
168
|
+
policy_id: str
|
169
|
+
endpoint_id: str
|
170
|
+
executed_at: Optional[datetime] = None
|
171
|
+
status: str
|
172
|
+
result: Dict[str, Any] = {}
|
173
|
+
errors: List[str] = []
|
174
|
+
duration: Optional[int] = None
|
175
|
+
|
176
|
+
|
177
|
+
class CreatePolicyRequest(AIRBaseModel):
|
178
|
+
"""Request model for creating a policy."""
|
179
|
+
|
180
|
+
name: str
|
181
|
+
organization_ids: List[int] = Field(alias="organizationIds")
|
182
|
+
filter: PolicyFilterStructure
|
183
|
+
cpu: PolicyCpuSettings
|
184
|
+
save_to: PolicySaveTo = Field(alias="saveTo")
|
185
|
+
send_to: PolicySendTo = Field(alias="sendTo")
|
186
|
+
compression: PolicyCompression
|
187
|
+
|
188
|
+
# Optional fields
|
189
|
+
bandwidth: Optional[Dict[str, Any]] = None
|
190
|
+
disk_space: Optional[Dict[str, Any]] = Field(default=None, alias="diskSpace")
|
191
|
+
triage_local_drives_only: Optional[Dict[str, Any]] = Field(default=None, alias="triageLocalDrivesOnly")
|
192
|
+
isolation_allowed_ips: Optional[List[str]] = Field(default=None, alias="isolationAllowedIps")
|
193
|
+
isolation_allowed_processes: Optional[List[str]] = Field(default=None, alias="isolationAllowedProcesses")
|
194
|
+
|
195
|
+
|
196
|
+
class UpdatePolicyRequest(AIRBaseModel):
|
197
|
+
"""Request model for updating a policy."""
|
198
|
+
|
199
|
+
name: Optional[str] = None
|
200
|
+
organization_ids: Optional[List[int]] = Field(default=None, alias="organizationIds")
|
201
|
+
filter: Optional[PolicyFilterStructure] = None
|
202
|
+
cpu: Optional[PolicyCpuSettings] = None
|
203
|
+
save_to: Optional[PolicySaveTo] = Field(default=None, alias="saveTo")
|
204
|
+
send_to: Optional[PolicySendTo] = Field(default=None, alias="sendTo")
|
205
|
+
compression: Optional[PolicyCompression] = None
|
206
|
+
|
207
|
+
# Optional fields
|
208
|
+
bandwidth: Optional[Dict[str, Any]] = None
|
209
|
+
disk_space: Optional[Dict[str, Any]] = Field(default=None, alias="diskSpace")
|
210
|
+
triage_local_drives_only: Optional[Dict[str, Any]] = Field(default=None, alias="triageLocalDrivesOnly")
|
211
|
+
isolation_allowed_ips: Optional[List[str]] = Field(default=None, alias="isolationAllowedIps")
|
212
|
+
isolation_allowed_processes: Optional[List[str]] = Field(default=None, alias="isolationAllowedProcesses")
|
213
|
+
|
214
|
+
|
215
|
+
class UpdatePoliciesPrioritiesRequest(AIRBaseModel):
|
216
|
+
"""Request model for updating policy priorities."""
|
217
|
+
|
218
|
+
policies: List[PolicyPriority]
|
219
|
+
|
220
|
+
|
221
|
+
class PolicyFilter(Filter):
|
222
|
+
"""Filter for policy queries."""
|
223
|
+
|
224
|
+
organization_ids: Optional[List[int]] = None
|
225
|
+
|
226
|
+
def to_params(self) -> Dict[str, Any]:
|
227
|
+
"""Convert filter to query parameters."""
|
228
|
+
params = {}
|
229
|
+
if self.organization_ids:
|
230
|
+
params["filter[organizationIds]"] = ",".join(map(str, self.organization_ids))
|
231
|
+
return params
|
232
|
+
|
233
|
+
|
234
|
+
class PoliciesPaginatedResponse(PaginatedResponse[Policy]):
|
235
|
+
"""Paginated response for policies."""
|
236
|
+
|
237
|
+
# Add field aliases for pagination fields
|
238
|
+
total_entity_count: int = Field(alias="totalEntityCount")
|
239
|
+
current_page: int = Field(alias="currentPage")
|
240
|
+
page_size: int = Field(alias="pageSize")
|
241
|
+
total_page_count: int = Field(alias="totalPageCount")
|
242
|
+
|
243
|
+
|
244
|
+
class AssignPolicyRequest(AIRBaseModel):
|
245
|
+
"""Request model for assigning policy to endpoints."""
|
246
|
+
|
247
|
+
policy_id: str
|
248
|
+
endpoint_ids: List[str] = []
|
249
|
+
organization_ids: List[int] = []
|
250
|
+
filter_params: Optional[Dict[str, Any]] = None
|