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,58 @@
|
|
1
|
+
"""
|
2
|
+
Interact commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any, Union
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..models.interact import (
|
9
|
+
InteractiveShellTaskResponse, AssignInteractiveShellTaskRequest,
|
10
|
+
ShellTaskResponse, AssignShellTaskRequest # Legacy models
|
11
|
+
)
|
12
|
+
from ..http_client import HTTPClient
|
13
|
+
|
14
|
+
|
15
|
+
class AssignInteractiveShellTaskCommand(Command[InteractiveShellTaskResponse]):
|
16
|
+
"""Command to assign an interactive shell task."""
|
17
|
+
|
18
|
+
def __init__(self, http_client: HTTPClient, request: Union[AssignInteractiveShellTaskRequest, Dict[str, Any]]):
|
19
|
+
self.http_client = http_client
|
20
|
+
self.request = request
|
21
|
+
|
22
|
+
def execute(self) -> InteractiveShellTaskResponse:
|
23
|
+
"""Execute the command to assign an interactive shell task."""
|
24
|
+
# Handle both dict and model objects
|
25
|
+
if isinstance(self.request, dict):
|
26
|
+
payload = self.request
|
27
|
+
else:
|
28
|
+
payload = self.request.model_dump(exclude_none=True, by_alias=True)
|
29
|
+
|
30
|
+
response = self.http_client.post("interact/shell/assign-task", json_data=payload)
|
31
|
+
|
32
|
+
if response.get("success"):
|
33
|
+
result_data = response.get("result", {})
|
34
|
+
# Use Pydantic parsing with proper field aliasing
|
35
|
+
return InteractiveShellTaskResponse.model_validate(result_data)
|
36
|
+
|
37
|
+
raise Exception(f"Failed to assign interactive shell task: {response.get('errors', [])}")
|
38
|
+
|
39
|
+
|
40
|
+
# Legacy command for backward compatibility (deprecated)
|
41
|
+
class AssignShellTaskCommand(Command[ShellTaskResponse]):
|
42
|
+
"""Command to assign a shell interaction task (legacy)."""
|
43
|
+
|
44
|
+
def __init__(self, http_client: HTTPClient, request: Union[AssignShellTaskRequest, Dict[str, Any]]):
|
45
|
+
self.http_client = http_client
|
46
|
+
self.request = request
|
47
|
+
|
48
|
+
def execute(self) -> ShellTaskResponse:
|
49
|
+
"""Execute the command to assign a shell task (legacy)."""
|
50
|
+
# Handle both dict and model objects
|
51
|
+
if isinstance(self.request, dict):
|
52
|
+
payload = self.request
|
53
|
+
else:
|
54
|
+
payload = self.request.model_dump(exclude_none=True)
|
55
|
+
|
56
|
+
response = self.http_client.post("interact/shell/assign-task", json_data=payload)
|
57
|
+
|
58
|
+
return ShellTaskResponse(**response.get("result", {}))
|
@@ -0,0 +1,221 @@
|
|
1
|
+
"""
|
2
|
+
Organization-related commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any, List
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..models.organizations import (
|
9
|
+
Organization, OrganizationUser, CreateOrganizationRequest,
|
10
|
+
UpdateOrganizationRequest, AddUserToOrganizationRequest, OrganizationSettings,
|
11
|
+
AssignUsersToOrganizationRequest, AddTagsToOrganizationRequest,
|
12
|
+
DeleteTagsFromOrganizationRequest, UpdateShareableDeploymentSettingsRequest,
|
13
|
+
UpdateDeploymentTokenRequest, DeploymentTokenUpdateResponse
|
14
|
+
)
|
15
|
+
from ..http_client import HTTPClient
|
16
|
+
|
17
|
+
|
18
|
+
class CreateOrganizationCommand(Command[Organization]):
|
19
|
+
"""Command to create a new organization."""
|
20
|
+
|
21
|
+
def __init__(self, http_client: HTTPClient, request: CreateOrganizationRequest):
|
22
|
+
self.http_client = http_client
|
23
|
+
self.request = request
|
24
|
+
|
25
|
+
def execute(self) -> Organization:
|
26
|
+
"""Execute the command to create an organization."""
|
27
|
+
data = self.request.model_dump(exclude_none=True, by_alias=True)
|
28
|
+
|
29
|
+
response = self.http_client.post("organizations", json_data=data)
|
30
|
+
|
31
|
+
entity_data = response.get("result", {})
|
32
|
+
|
33
|
+
# Use Pydantic model_validate for automatic field mapping via aliases
|
34
|
+
return Organization.model_validate(entity_data)
|
35
|
+
|
36
|
+
|
37
|
+
class UpdateOrganizationCommand(Command[Organization]):
|
38
|
+
"""Command to update an existing organization."""
|
39
|
+
|
40
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, request: UpdateOrganizationRequest):
|
41
|
+
self.http_client = http_client
|
42
|
+
self.organization_id = organization_id
|
43
|
+
self.request = request
|
44
|
+
|
45
|
+
def execute(self) -> Organization:
|
46
|
+
"""Execute the command to update an organization."""
|
47
|
+
data = self.request.model_dump(exclude_none=True, by_alias=True)
|
48
|
+
|
49
|
+
response = self.http_client.patch(f"organizations/{self.organization_id}", json_data=data)
|
50
|
+
|
51
|
+
entity_data = response.get("result", {})
|
52
|
+
|
53
|
+
# Use Pydantic model_validate for automatic field mapping via aliases
|
54
|
+
return Organization.model_validate(entity_data)
|
55
|
+
|
56
|
+
|
57
|
+
class DeleteOrganizationCommand(Command[Dict[str, Any]]):
|
58
|
+
"""Command to delete an organization."""
|
59
|
+
|
60
|
+
def __init__(self, http_client: HTTPClient, organization_id: str):
|
61
|
+
self.http_client = http_client
|
62
|
+
self.organization_id = organization_id
|
63
|
+
|
64
|
+
def execute(self) -> Dict[str, Any]:
|
65
|
+
"""Execute the command to delete an organization."""
|
66
|
+
response = self.http_client.delete(f"organizations/{self.organization_id}")
|
67
|
+
return response
|
68
|
+
|
69
|
+
|
70
|
+
class AssignUsersToOrganizationCommand(Command[bool]):
|
71
|
+
"""Command to assign multiple users to an organization using the /assign-users endpoint."""
|
72
|
+
|
73
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, request: AssignUsersToOrganizationRequest):
|
74
|
+
self.http_client = http_client
|
75
|
+
self.organization_id = organization_id
|
76
|
+
self.request = request
|
77
|
+
|
78
|
+
def execute(self) -> bool:
|
79
|
+
"""Execute the command to assign users to organization."""
|
80
|
+
data = self.request.model_dump(exclude_none=True, by_alias=True)
|
81
|
+
|
82
|
+
response = self.http_client.post(f"organizations/{self.organization_id}/assign-users", json_data=data)
|
83
|
+
|
84
|
+
return response.get("success", False)
|
85
|
+
|
86
|
+
|
87
|
+
class RemoveUserFromOrganizationCommand(Command[Dict[str, Any]]):
|
88
|
+
"""Command to remove a user from an organization using the /remove-user/{userId} endpoint."""
|
89
|
+
|
90
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, user_id: str):
|
91
|
+
self.http_client = http_client
|
92
|
+
self.organization_id = organization_id
|
93
|
+
self.user_id = user_id
|
94
|
+
|
95
|
+
def execute(self) -> Dict[str, Any]:
|
96
|
+
"""Execute the command to remove user from organization."""
|
97
|
+
response = self.http_client.delete(f"organizations/{self.organization_id}/remove-user/{self.user_id}")
|
98
|
+
|
99
|
+
return response
|
100
|
+
|
101
|
+
|
102
|
+
class AddTagsToOrganizationCommand(Command[Organization]):
|
103
|
+
"""Command to add tags to an organization."""
|
104
|
+
|
105
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, request: AddTagsToOrganizationRequest):
|
106
|
+
self.http_client = http_client
|
107
|
+
self.organization_id = organization_id
|
108
|
+
self.request = request
|
109
|
+
|
110
|
+
def execute(self) -> Organization:
|
111
|
+
"""Execute the command to add tags to organization."""
|
112
|
+
data = self.request.model_dump(exclude_none=True, by_alias=True)
|
113
|
+
|
114
|
+
response = self.http_client.patch(f"organizations/{self.organization_id}/tags", json_data=data)
|
115
|
+
|
116
|
+
entity_data = response.get("result", {})
|
117
|
+
|
118
|
+
# Use Pydantic model_validate for automatic field mapping
|
119
|
+
return Organization.model_validate(entity_data)
|
120
|
+
|
121
|
+
|
122
|
+
class DeleteTagsFromOrganizationCommand(Command[Organization]):
|
123
|
+
"""Command to delete tags from an organization."""
|
124
|
+
|
125
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, request: DeleteTagsFromOrganizationRequest):
|
126
|
+
self.http_client = http_client
|
127
|
+
self.organization_id = organization_id
|
128
|
+
self.request = request
|
129
|
+
|
130
|
+
def execute(self) -> Organization:
|
131
|
+
"""Execute the command to delete tags from organization."""
|
132
|
+
data = self.request.model_dump(exclude_none=True, by_alias=True)
|
133
|
+
|
134
|
+
response = self.http_client.delete(f"organizations/{self.organization_id}/tags", json_data=data)
|
135
|
+
|
136
|
+
entity_data = response.get("result", {})
|
137
|
+
|
138
|
+
# Use Pydantic model_validate for automatic field mapping
|
139
|
+
return Organization.model_validate(entity_data)
|
140
|
+
|
141
|
+
|
142
|
+
class UpdateShareableDeploymentSettingsCommand(Command[bool]):
|
143
|
+
"""Command to update organization shareable deployment settings."""
|
144
|
+
|
145
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, request: UpdateShareableDeploymentSettingsRequest):
|
146
|
+
self.http_client = http_client
|
147
|
+
self.organization_id = organization_id
|
148
|
+
self.request = request
|
149
|
+
|
150
|
+
def execute(self) -> bool:
|
151
|
+
"""Execute the command to update shareable deployment settings."""
|
152
|
+
data = self.request.model_dump(exclude_none=True, by_alias=True)
|
153
|
+
|
154
|
+
response = self.http_client.post(f"organizations/{self.organization_id}/shareable-deployment", json_data=data)
|
155
|
+
|
156
|
+
return response.get("success", False)
|
157
|
+
|
158
|
+
|
159
|
+
class UpdateDeploymentTokenCommand(Command[DeploymentTokenUpdateResponse]):
|
160
|
+
"""Command to update organization deployment token."""
|
161
|
+
|
162
|
+
def __init__(self, http_client: HTTPClient, organization_id: str):
|
163
|
+
self.http_client = http_client
|
164
|
+
self.organization_id = organization_id
|
165
|
+
|
166
|
+
def execute(self) -> DeploymentTokenUpdateResponse:
|
167
|
+
"""Execute the command to update deployment token."""
|
168
|
+
response = self.http_client.post(f"organizations/{self.organization_id}/deployment-token")
|
169
|
+
|
170
|
+
# Use Pydantic model_validate for automatic field mapping
|
171
|
+
return DeploymentTokenUpdateResponse.model_validate(response)
|
172
|
+
|
173
|
+
|
174
|
+
class UpdateOrganizationSettingsCommand(Command[OrganizationSettings]):
|
175
|
+
"""Command to update organization settings."""
|
176
|
+
|
177
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, settings: Dict[str, Any]):
|
178
|
+
self.http_client = http_client
|
179
|
+
self.organization_id = organization_id
|
180
|
+
self.settings = settings
|
181
|
+
|
182
|
+
def execute(self) -> OrganizationSettings:
|
183
|
+
"""Execute the command to update organization settings."""
|
184
|
+
response = self.http_client.put(f"organizations/{self.organization_id}/settings", json_data=self.settings)
|
185
|
+
|
186
|
+
entity_data = response.get("result", {})
|
187
|
+
|
188
|
+
mapped_data = {
|
189
|
+
"organization_id": entity_data.get("organizationId"),
|
190
|
+
"retention_policy": entity_data.get("retentionPolicy", {}),
|
191
|
+
"security_settings": entity_data.get("securitySettings", {}),
|
192
|
+
"notification_settings": entity_data.get("notificationSettings", {}),
|
193
|
+
"api_settings": entity_data.get("apiSettings", {}),
|
194
|
+
"custom_settings": entity_data.get("customSettings", {}),
|
195
|
+
}
|
196
|
+
|
197
|
+
# Remove None values
|
198
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
199
|
+
|
200
|
+
return OrganizationSettings(**mapped_data)
|
201
|
+
|
202
|
+
|
203
|
+
# Legacy command for backward compatibility
|
204
|
+
class AddUserToOrganizationCommand(Command[OrganizationUser]):
|
205
|
+
"""Legacy command to add a user to an organization (use AssignUsersToOrganizationCommand for new implementations)."""
|
206
|
+
|
207
|
+
def __init__(self, http_client: HTTPClient, organization_id: str, request: AddUserToOrganizationRequest):
|
208
|
+
self.http_client = http_client
|
209
|
+
self.organization_id = organization_id
|
210
|
+
self.request = request
|
211
|
+
|
212
|
+
def execute(self) -> OrganizationUser:
|
213
|
+
"""Execute the command to add user to organization."""
|
214
|
+
data = self.request.model_dump(exclude_none=True)
|
215
|
+
|
216
|
+
response = self.http_client.post(f"organizations/{self.organization_id}/users", json_data=data)
|
217
|
+
|
218
|
+
entity_data = response.get("result", {})
|
219
|
+
|
220
|
+
# Use Pydantic model_validate for automatic field mapping
|
221
|
+
return OrganizationUser.model_validate(entity_data)
|
@@ -0,0 +1,203 @@
|
|
1
|
+
"""
|
2
|
+
Policy-related commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any, List, Optional, Union
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..models.policies import (
|
9
|
+
CreatePolicyRequest, UpdatePolicyRequest, UpdatePoliciesPrioritiesRequest,
|
10
|
+
Policy, PolicyPriority, AssignPolicyRequest
|
11
|
+
)
|
12
|
+
from ..http_client import HTTPClient
|
13
|
+
|
14
|
+
|
15
|
+
class CreatePolicyCommand(Command[Policy]):
|
16
|
+
"""Command to create a new policy."""
|
17
|
+
|
18
|
+
def __init__(self, http_client: HTTPClient, policy_data: Union[CreatePolicyRequest, Dict[str, Any]]):
|
19
|
+
self.http_client = http_client
|
20
|
+
self.policy_data = policy_data
|
21
|
+
|
22
|
+
def execute(self) -> Policy:
|
23
|
+
"""Execute the create policy command."""
|
24
|
+
# Handle both dict and model objects
|
25
|
+
if isinstance(self.policy_data, dict):
|
26
|
+
payload = self.policy_data.copy()
|
27
|
+
else:
|
28
|
+
# Convert model to dict using model_dump with aliases
|
29
|
+
payload = self.policy_data.model_dump(by_alias=True, exclude_none=True)
|
30
|
+
|
31
|
+
response = self.http_client.post("policies", json_data=payload)
|
32
|
+
|
33
|
+
# Parse using Pydantic models with automatic field mapping
|
34
|
+
return Policy.model_validate(response.get("result", {}))
|
35
|
+
|
36
|
+
|
37
|
+
class UpdatePolicyCommand(Command[Policy]):
|
38
|
+
"""Command to update an existing policy."""
|
39
|
+
|
40
|
+
def __init__(self, http_client: HTTPClient, policy_id: str, update_data: Union[UpdatePolicyRequest, Dict[str, Any]]):
|
41
|
+
self.http_client = http_client
|
42
|
+
self.policy_id = policy_id
|
43
|
+
self.update_data = update_data
|
44
|
+
|
45
|
+
def execute(self) -> Policy:
|
46
|
+
"""Execute the update policy command."""
|
47
|
+
# Handle both dict and model objects
|
48
|
+
if isinstance(self.update_data, dict):
|
49
|
+
payload = self.update_data.copy()
|
50
|
+
else:
|
51
|
+
# Convert model to dict using model_dump with aliases
|
52
|
+
payload = self.update_data.model_dump(by_alias=True, exclude_none=True)
|
53
|
+
|
54
|
+
response = self.http_client.put(f"policies/{self.policy_id}", json_data=payload)
|
55
|
+
|
56
|
+
# Parse using Pydantic models with automatic field mapping
|
57
|
+
return Policy.model_validate(response.get("result", {}))
|
58
|
+
|
59
|
+
|
60
|
+
class UpdatePoliciesPrioritiesCommand(Command[Dict[str, Any]]):
|
61
|
+
"""Command to update policy priorities."""
|
62
|
+
|
63
|
+
def __init__(self, http_client: HTTPClient, priorities_data: Union[UpdatePoliciesPrioritiesRequest, Dict[str, Any]]):
|
64
|
+
self.http_client = http_client
|
65
|
+
self.priorities_data = priorities_data
|
66
|
+
|
67
|
+
def execute(self) -> Dict[str, Any]:
|
68
|
+
"""Execute the update policy priorities command."""
|
69
|
+
# Handle both dict and model objects
|
70
|
+
if isinstance(self.priorities_data, dict):
|
71
|
+
payload = self.priorities_data.copy()
|
72
|
+
else:
|
73
|
+
# Convert model to dict using model_dump with aliases
|
74
|
+
payload = self.priorities_data.model_dump(by_alias=True, exclude_none=True)
|
75
|
+
|
76
|
+
return self.http_client.put("policies/priorities", json_data=payload)
|
77
|
+
|
78
|
+
|
79
|
+
class DeletePolicyCommand(Command[Dict[str, Any]]):
|
80
|
+
"""Command to delete a policy."""
|
81
|
+
|
82
|
+
def __init__(self, http_client: HTTPClient, policy_id: str):
|
83
|
+
self.http_client = http_client
|
84
|
+
self.policy_id = policy_id
|
85
|
+
|
86
|
+
def execute(self) -> Dict[str, Any]:
|
87
|
+
"""Execute the delete policy command."""
|
88
|
+
return self.http_client.delete(f"policies/{self.policy_id}")
|
89
|
+
|
90
|
+
|
91
|
+
class AssignPolicyCommand(Command[Dict[str, Any]]):
|
92
|
+
"""Command to assign policy to endpoints."""
|
93
|
+
|
94
|
+
def __init__(self, http_client: HTTPClient, assignment_data: Union[AssignPolicyRequest, Dict[str, Any]]):
|
95
|
+
self.http_client = http_client
|
96
|
+
self.assignment_data = assignment_data
|
97
|
+
|
98
|
+
def execute(self) -> Dict[str, Any]:
|
99
|
+
"""Execute the assign policy command."""
|
100
|
+
# Handle both dict and model objects
|
101
|
+
if isinstance(self.assignment_data, dict):
|
102
|
+
payload = self.assignment_data.copy()
|
103
|
+
else:
|
104
|
+
payload = {
|
105
|
+
"policyId": self.assignment_data.policy_id,
|
106
|
+
"endpointIds": self.assignment_data.endpoint_ids,
|
107
|
+
"organizationIds": self.assignment_data.organization_ids,
|
108
|
+
}
|
109
|
+
|
110
|
+
if self.assignment_data.filter_params:
|
111
|
+
payload["filter"] = self.assignment_data.filter_params
|
112
|
+
|
113
|
+
return self.http_client.post("policies/assign", json_data=payload)
|
114
|
+
|
115
|
+
|
116
|
+
class UnassignPolicyCommand(Command[Dict[str, Any]]):
|
117
|
+
"""Command to unassign policy from endpoints."""
|
118
|
+
|
119
|
+
def __init__(self, http_client: HTTPClient, policy_id: str, endpoint_ids: List[str]):
|
120
|
+
self.http_client = http_client
|
121
|
+
self.policy_id = policy_id
|
122
|
+
self.endpoint_ids = endpoint_ids
|
123
|
+
|
124
|
+
def execute(self) -> Dict[str, Any]:
|
125
|
+
"""Execute the unassign policy command."""
|
126
|
+
payload = {
|
127
|
+
"policyId": self.policy_id,
|
128
|
+
"endpointIds": self.endpoint_ids,
|
129
|
+
}
|
130
|
+
|
131
|
+
return self.http_client.post("policies/unassign", json_data=payload)
|
132
|
+
|
133
|
+
|
134
|
+
class ExecutePolicyCommand(Command[Dict[str, Any]]):
|
135
|
+
"""Command to execute a policy on assigned endpoints."""
|
136
|
+
|
137
|
+
def __init__(self, http_client: HTTPClient, policy_id: str, endpoint_ids: Optional[List[str]] = None):
|
138
|
+
self.http_client = http_client
|
139
|
+
self.policy_id = policy_id
|
140
|
+
self.endpoint_ids = endpoint_ids
|
141
|
+
|
142
|
+
def execute(self) -> Dict[str, Any]:
|
143
|
+
"""Execute the policy execution command."""
|
144
|
+
payload = {"policyId": self.policy_id}
|
145
|
+
|
146
|
+
if self.endpoint_ids:
|
147
|
+
payload["endpointIds"] = self.endpoint_ids
|
148
|
+
|
149
|
+
return self.http_client.post("policies/execute", json_data=payload)
|
150
|
+
|
151
|
+
|
152
|
+
class ActivatePolicyCommand(Command[Policy]):
|
153
|
+
"""Command to activate a policy."""
|
154
|
+
|
155
|
+
def __init__(self, http_client: HTTPClient, policy_id: str):
|
156
|
+
self.http_client = http_client
|
157
|
+
self.policy_id = policy_id
|
158
|
+
|
159
|
+
def execute(self) -> Policy:
|
160
|
+
"""Execute the activate policy command."""
|
161
|
+
payload = {"status": "active"}
|
162
|
+
response = self.http_client.put(f"policies/{self.policy_id}", json_data=payload)
|
163
|
+
|
164
|
+
entity_data = response.get("result", {})
|
165
|
+
return Policy(
|
166
|
+
id=entity_data.get("_id", self.policy_id),
|
167
|
+
name=entity_data.get("name", ""),
|
168
|
+
description=entity_data.get("description"),
|
169
|
+
type=entity_data.get("type", "custom"),
|
170
|
+
status=entity_data.get("status", "active"),
|
171
|
+
organization_ids=entity_data.get("organizationIds", [0]),
|
172
|
+
created_by=entity_data.get("createdBy", ""),
|
173
|
+
created_at=entity_data.get("createdAt"),
|
174
|
+
rules=entity_data.get("rules", []),
|
175
|
+
tags=entity_data.get("tags", [])
|
176
|
+
)
|
177
|
+
|
178
|
+
|
179
|
+
class DeactivatePolicyCommand(Command[Policy]):
|
180
|
+
"""Command to deactivate a policy."""
|
181
|
+
|
182
|
+
def __init__(self, http_client: HTTPClient, policy_id: str):
|
183
|
+
self.http_client = http_client
|
184
|
+
self.policy_id = policy_id
|
185
|
+
|
186
|
+
def execute(self) -> Policy:
|
187
|
+
"""Execute the deactivate policy command."""
|
188
|
+
payload = {"status": "inactive"}
|
189
|
+
response = self.http_client.put(f"policies/{self.policy_id}", json_data=payload)
|
190
|
+
|
191
|
+
entity_data = response.get("result", {})
|
192
|
+
return Policy(
|
193
|
+
id=entity_data.get("_id", self.policy_id),
|
194
|
+
name=entity_data.get("name", ""),
|
195
|
+
description=entity_data.get("description"),
|
196
|
+
type=entity_data.get("type", "custom"),
|
197
|
+
status=entity_data.get("status", "inactive"),
|
198
|
+
organization_ids=entity_data.get("organizationIds", [0]),
|
199
|
+
created_by=entity_data.get("createdBy", ""),
|
200
|
+
created_at=entity_data.get("createdAt"),
|
201
|
+
rules=entity_data.get("rules", []),
|
202
|
+
tags=entity_data.get("tags", [])
|
203
|
+
)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
"""
|
2
|
+
Settings commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any, Union
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..models.settings import BannerSettings, UpdateBannerSettingsRequest
|
9
|
+
from ..http_client import HTTPClient
|
10
|
+
|
11
|
+
|
12
|
+
class UpdateBannerSettingsCommand(Command[BannerSettings]):
|
13
|
+
"""Command to update banner settings."""
|
14
|
+
|
15
|
+
def __init__(self, http_client: HTTPClient, request: Union[UpdateBannerSettingsRequest, Dict[str, Any]]):
|
16
|
+
self.http_client = http_client
|
17
|
+
self.request = request
|
18
|
+
|
19
|
+
def execute(self):
|
20
|
+
"""Execute the update banner settings command."""
|
21
|
+
# Handle both dict and model objects
|
22
|
+
if isinstance(self.request, dict):
|
23
|
+
payload = self.request
|
24
|
+
else:
|
25
|
+
# Use by_alias=True to ensure field aliases are properly mapped to API field names
|
26
|
+
payload = self.request.model_dump(exclude_none=True, by_alias=True)
|
27
|
+
|
28
|
+
response = self.http_client.put("settings/banner", json_data=payload)
|
29
|
+
return response
|
@@ -0,0 +1,56 @@
|
|
1
|
+
"""
|
2
|
+
Task-related commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..http_client import HTTPClient
|
9
|
+
|
10
|
+
|
11
|
+
class CancelTaskCommand(Command[Dict[str, Any]]):
|
12
|
+
"""Command to cancel a task."""
|
13
|
+
|
14
|
+
def __init__(self, http_client: HTTPClient, task_id: str):
|
15
|
+
self.http_client = http_client
|
16
|
+
self.task_id = task_id
|
17
|
+
|
18
|
+
def execute(self) -> Dict[str, Any]:
|
19
|
+
"""Execute the cancel task command."""
|
20
|
+
return self.http_client.post(f"tasks/{self.task_id}/cancel", json_data={})
|
21
|
+
|
22
|
+
|
23
|
+
class CancelTaskAssignmentCommand(Command[Dict[str, Any]]):
|
24
|
+
"""Command to cancel a task assignment."""
|
25
|
+
|
26
|
+
def __init__(self, http_client: HTTPClient, assignment_id: str):
|
27
|
+
self.http_client = http_client
|
28
|
+
self.assignment_id = assignment_id
|
29
|
+
|
30
|
+
def execute(self) -> Dict[str, Any]:
|
31
|
+
"""Execute the cancel task assignment command."""
|
32
|
+
return self.http_client.post(f"tasks/assignments/{self.assignment_id}/cancel", json_data={})
|
33
|
+
|
34
|
+
|
35
|
+
class DeleteTaskAssignmentCommand(Command[Dict[str, Any]]):
|
36
|
+
"""Command to delete a task assignment."""
|
37
|
+
|
38
|
+
def __init__(self, http_client: HTTPClient, assignment_id: str):
|
39
|
+
self.http_client = http_client
|
40
|
+
self.assignment_id = assignment_id
|
41
|
+
|
42
|
+
def execute(self) -> Dict[str, Any]:
|
43
|
+
"""Execute the delete task assignment command."""
|
44
|
+
return self.http_client.delete(f"tasks/assignments/{self.assignment_id}")
|
45
|
+
|
46
|
+
|
47
|
+
class DeleteTaskCommand(Command[Dict[str, Any]]):
|
48
|
+
"""Command to delete a task."""
|
49
|
+
|
50
|
+
def __init__(self, http_client: HTTPClient, task_id: str):
|
51
|
+
self.http_client = http_client
|
52
|
+
self.task_id = task_id
|
53
|
+
|
54
|
+
def execute(self) -> Dict[str, Any]:
|
55
|
+
"""Execute the delete task command."""
|
56
|
+
return self.http_client.delete(f"tasks/{self.task_id}")
|