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.
- 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.2.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.2.dist-info/METADATA +0 -706
- binalyze_air_sdk-1.0.2.dist-info/RECORD +0 -82
- {binalyze_air_sdk-1.0.2.dist-info → binalyze_air_sdk-1.0.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,197 @@
|
|
1
|
+
"""
|
2
|
+
Triage API for the Binalyze AIR SDK using CQRS pattern.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional, Dict, Any, Union
|
6
|
+
from ..http_client import HTTPClient
|
7
|
+
from ..models.triage import (
|
8
|
+
TriageRule, TriageTag, TriageFilter,
|
9
|
+
CreateTriageRuleRequest, UpdateTriageRuleRequest, CreateTriageTagRequest
|
10
|
+
)
|
11
|
+
from ..queries.triage import (
|
12
|
+
ListTriageRulesQuery,
|
13
|
+
GetTriageRuleQuery,
|
14
|
+
ListTriageTagsQuery,
|
15
|
+
)
|
16
|
+
from ..commands.triage import (
|
17
|
+
CreateTriageRuleCommand,
|
18
|
+
UpdateTriageRuleCommand,
|
19
|
+
DeleteTriageRuleCommand,
|
20
|
+
CreateTriageTagCommand,
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
class TriageAPI:
|
25
|
+
"""Triage API with CQRS pattern - separated queries and commands."""
|
26
|
+
|
27
|
+
def __init__(self, http_client: HTTPClient):
|
28
|
+
self.http_client = http_client
|
29
|
+
|
30
|
+
# QUERIES (Read operations)
|
31
|
+
def list_rules(self, filter_params: Optional[TriageFilter] = None, organization_ids: Optional[List[int]] = None) -> List[TriageRule]:
|
32
|
+
"""List triage rules with optional filtering."""
|
33
|
+
query = ListTriageRulesQuery(self.http_client, filter_params, organization_ids)
|
34
|
+
return query.execute()
|
35
|
+
|
36
|
+
def get_rule(self, rule_id: str) -> TriageRule:
|
37
|
+
"""Get a specific triage rule by ID."""
|
38
|
+
query = GetTriageRuleQuery(self.http_client, rule_id)
|
39
|
+
return query.execute()
|
40
|
+
|
41
|
+
def get_rule_by_id(self, rule_id: str) -> TriageRule:
|
42
|
+
"""Get a specific triage rule by ID - alias for get_rule."""
|
43
|
+
return self.get_rule(rule_id)
|
44
|
+
|
45
|
+
def list_tags(self, organization_id: Optional[int] = None) -> List[TriageTag]:
|
46
|
+
"""List triage tags."""
|
47
|
+
query = ListTriageTagsQuery(self.http_client, organization_id)
|
48
|
+
return query.execute()
|
49
|
+
|
50
|
+
def validate_rule(self, rule_content: str, engine: str = "yara") -> Dict[str, Any]:
|
51
|
+
"""Validate triage rule syntax."""
|
52
|
+
try:
|
53
|
+
# Prepare validation data
|
54
|
+
validation_data = {
|
55
|
+
"rule": rule_content,
|
56
|
+
"engine": engine
|
57
|
+
}
|
58
|
+
|
59
|
+
# Call the API validation endpoint
|
60
|
+
response = self.http_client.post("triages/rules/validate", json_data=validation_data)
|
61
|
+
return response
|
62
|
+
|
63
|
+
except Exception as e:
|
64
|
+
# Return error response format matching API
|
65
|
+
return {
|
66
|
+
"success": False,
|
67
|
+
"result": None,
|
68
|
+
"statusCode": 500,
|
69
|
+
"errors": [str(e)]
|
70
|
+
}
|
71
|
+
|
72
|
+
# COMMANDS (Write operations)
|
73
|
+
def create_rule(self, request: Union[CreateTriageRuleRequest, Dict[str, Any]]) -> TriageRule:
|
74
|
+
"""Create a new triage rule."""
|
75
|
+
command = CreateTriageRuleCommand(self.http_client, request)
|
76
|
+
return command.execute()
|
77
|
+
|
78
|
+
def update_rule(self, rule_id_or_data: Union[str, Dict[str, Any]], request: Optional[Union[UpdateTriageRuleRequest, Dict[str, Any]]] = None) -> TriageRule:
|
79
|
+
"""Update an existing triage rule."""
|
80
|
+
# Handle both signatures: update_rule(rule_id, request) and update_rule(data_dict)
|
81
|
+
if isinstance(rule_id_or_data, str) and request is not None:
|
82
|
+
# Traditional signature: update_rule(rule_id, request)
|
83
|
+
command = UpdateTriageRuleCommand(self.http_client, rule_id_or_data, request)
|
84
|
+
elif isinstance(rule_id_or_data, dict):
|
85
|
+
# Dict signature: update_rule(data_dict) where data_dict contains 'id'
|
86
|
+
rule_id = rule_id_or_data.get('id')
|
87
|
+
if not rule_id:
|
88
|
+
raise ValueError("Rule ID must be provided in data dict or as separate parameter")
|
89
|
+
command = UpdateTriageRuleCommand(self.http_client, rule_id, rule_id_or_data)
|
90
|
+
else:
|
91
|
+
raise ValueError("Invalid arguments for update_rule")
|
92
|
+
|
93
|
+
return command.execute()
|
94
|
+
|
95
|
+
def delete_rule(self, rule_id: str) -> Dict[str, Any]:
|
96
|
+
"""Delete a triage rule."""
|
97
|
+
command = DeleteTriageRuleCommand(self.http_client, rule_id)
|
98
|
+
return command.execute()
|
99
|
+
|
100
|
+
def create_tag(self, request: Union[CreateTriageTagRequest, Dict[str, Any]]) -> TriageTag:
|
101
|
+
"""Create a new triage tag."""
|
102
|
+
command = CreateTriageTagCommand(self.http_client, request)
|
103
|
+
return command.execute()
|
104
|
+
|
105
|
+
def assign_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
106
|
+
"""Assign a triage task to endpoints."""
|
107
|
+
try:
|
108
|
+
# Call the correct API endpoint for triage task assignment
|
109
|
+
response = self.http_client.post("triages/triage", json_data=task_data)
|
110
|
+
return response
|
111
|
+
except Exception as e:
|
112
|
+
# Import specific exception types
|
113
|
+
from ..exceptions import AuthorizationError, AuthenticationError, ValidationError, AIRAPIError
|
114
|
+
|
115
|
+
# Handle specific API errors and preserve status codes
|
116
|
+
if isinstance(e, (AuthorizationError, AuthenticationError, ValidationError, AIRAPIError)):
|
117
|
+
# Return the actual API error response if available
|
118
|
+
if hasattr(e, 'response_data') and e.response_data:
|
119
|
+
return e.response_data
|
120
|
+
else:
|
121
|
+
# Create response matching API format with actual status code
|
122
|
+
return {
|
123
|
+
"success": False,
|
124
|
+
"result": None,
|
125
|
+
"statusCode": getattr(e, 'status_code', 500),
|
126
|
+
"errors": [str(e)]
|
127
|
+
}
|
128
|
+
else:
|
129
|
+
# For unexpected errors, use 500
|
130
|
+
return {
|
131
|
+
"success": False,
|
132
|
+
"result": None,
|
133
|
+
"statusCode": 500,
|
134
|
+
"errors": [str(e)]
|
135
|
+
}
|
136
|
+
|
137
|
+
def update_scheduled_triage(self, triage_id: str, update_data: Dict[str, Any]) -> Dict[str, Any]:
|
138
|
+
"""Update a scheduled triage task."""
|
139
|
+
try:
|
140
|
+
response = self.http_client.put(f"triages/schedule/triage/{triage_id}", json_data=update_data)
|
141
|
+
return response
|
142
|
+
except Exception as e:
|
143
|
+
# Import specific exception types
|
144
|
+
from ..exceptions import AuthorizationError, AuthenticationError, ValidationError, AIRAPIError
|
145
|
+
|
146
|
+
# Handle specific API errors and preserve status codes
|
147
|
+
if isinstance(e, (AuthorizationError, AuthenticationError, ValidationError, AIRAPIError)):
|
148
|
+
# Return the actual API error response if available
|
149
|
+
if hasattr(e, 'response_data') and e.response_data:
|
150
|
+
return e.response_data
|
151
|
+
else:
|
152
|
+
# Create response matching API format with actual status code
|
153
|
+
return {
|
154
|
+
"success": False,
|
155
|
+
"result": None,
|
156
|
+
"statusCode": getattr(e, 'status_code', 500),
|
157
|
+
"errors": [str(e)]
|
158
|
+
}
|
159
|
+
else:
|
160
|
+
# For unexpected errors, use 500
|
161
|
+
return {
|
162
|
+
"success": False,
|
163
|
+
"result": None,
|
164
|
+
"statusCode": 500,
|
165
|
+
"errors": [str(e)]
|
166
|
+
}
|
167
|
+
|
168
|
+
def create_off_network_triage_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
169
|
+
"""Create an off-network triage task file."""
|
170
|
+
try:
|
171
|
+
response = self.http_client.post("triages/triage/off-network", json_data=task_data)
|
172
|
+
return response
|
173
|
+
except Exception as e:
|
174
|
+
# Import specific exception types
|
175
|
+
from ..exceptions import AuthorizationError, AuthenticationError, ValidationError, AIRAPIError
|
176
|
+
|
177
|
+
# Handle specific API errors and preserve status codes
|
178
|
+
if isinstance(e, (AuthorizationError, AuthenticationError, ValidationError, AIRAPIError)):
|
179
|
+
# Return the actual API error response if available
|
180
|
+
if hasattr(e, 'response_data') and e.response_data:
|
181
|
+
return e.response_data
|
182
|
+
else:
|
183
|
+
# Create response matching API format with actual status code
|
184
|
+
return {
|
185
|
+
"success": False,
|
186
|
+
"result": None,
|
187
|
+
"statusCode": getattr(e, 'status_code', 500),
|
188
|
+
"errors": [str(e)]
|
189
|
+
}
|
190
|
+
else:
|
191
|
+
# For unexpected errors, use 500
|
192
|
+
return {
|
193
|
+
"success": False,
|
194
|
+
"result": None,
|
195
|
+
"statusCode": 500,
|
196
|
+
"errors": [str(e)]
|
197
|
+
}
|
@@ -1,74 +1,183 @@
|
|
1
|
-
"""
|
2
|
-
User Management API for the Binalyze AIR SDK.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from typing import List, Optional, Dict, Any
|
6
|
-
|
7
|
-
from ..http_client import HTTPClient
|
8
|
-
from ..models.user_management import (
|
9
|
-
UserManagementUser, UserFilter, CreateUserRequest, UpdateUserRequest,
|
10
|
-
AIUser, CreateAIUserRequest, APIUser, CreateAPIUserRequest
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
)
|
15
|
-
from ..
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
command
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
1
|
+
"""
|
2
|
+
User Management API for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional, Dict, Any
|
6
|
+
|
7
|
+
from ..http_client import HTTPClient
|
8
|
+
from ..models.user_management import (
|
9
|
+
UserManagementUser, UserFilter, CreateUserRequest, UpdateUserRequest,
|
10
|
+
AIUser, CreateAIUserRequest, APIUser, CreateAPIUserRequest,
|
11
|
+
ChangePasswordRequest, SetAPIUserPasswordRequest, ResetPasswordRequest,
|
12
|
+
Role, CreateRoleRequest, UpdateRoleRequest, Privilege,
|
13
|
+
UserGroup, CreateUserGroupRequest, UpdateUserGroupRequest, UserGroupFilter
|
14
|
+
)
|
15
|
+
from ..queries.user_management import (
|
16
|
+
ListUsersQuery, GetUserQuery, GetAIUserQuery, GetAPIUserQuery,
|
17
|
+
GetPrivilegesQuery, ListRolesQuery, GetRoleQuery,
|
18
|
+
ListUserGroupsQuery, GetUserGroupQuery
|
19
|
+
)
|
20
|
+
from ..commands.user_management import (
|
21
|
+
CreateUserCommand, UpdateUserCommand, DeleteUserCommand,
|
22
|
+
CreateAIUserCommand, CreateAPIUserCommand,
|
23
|
+
ChangeCurrentUserPasswordCommand, SetAPIUserPasswordCommand,
|
24
|
+
ResetPasswordCommand, ResetTFACommand,
|
25
|
+
CreateRoleCommand, UpdateRoleCommand, DeleteRoleCommand,
|
26
|
+
CreateUserGroupCommand, UpdateUserGroupCommand, DeleteUserGroupCommand
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
class UserManagementAPI:
|
31
|
+
"""User Management API with CQRS pattern - separated queries and commands."""
|
32
|
+
|
33
|
+
def __init__(self, http_client: HTTPClient):
|
34
|
+
self.http_client = http_client
|
35
|
+
|
36
|
+
# USER QUERIES (Read operations)
|
37
|
+
def list_users(self, filter_params: Optional[UserFilter] = None) -> List[UserManagementUser]:
|
38
|
+
"""List users with optional filtering."""
|
39
|
+
query = ListUsersQuery(self.http_client, filter_params)
|
40
|
+
return query.execute()
|
41
|
+
|
42
|
+
def get_user(self, user_id: str) -> UserManagementUser:
|
43
|
+
"""Get a specific user by ID."""
|
44
|
+
query = GetUserQuery(self.http_client, user_id)
|
45
|
+
return query.execute()
|
46
|
+
|
47
|
+
# USER COMMANDS (Write operations)
|
48
|
+
def create_user(self, request: CreateUserRequest) -> UserManagementUser:
|
49
|
+
"""Create a new user."""
|
50
|
+
command = CreateUserCommand(self.http_client, request)
|
51
|
+
return command.execute()
|
52
|
+
|
53
|
+
def update_user(self, user_id: str, request: UpdateUserRequest) -> UserManagementUser:
|
54
|
+
"""Update an existing user."""
|
55
|
+
command = UpdateUserCommand(self.http_client, user_id, request)
|
56
|
+
return command.execute()
|
57
|
+
|
58
|
+
def delete_user(self, user_id: str) -> Dict[str, Any]:
|
59
|
+
"""Delete a user."""
|
60
|
+
command = DeleteUserCommand(self.http_client, user_id)
|
61
|
+
return command.execute()
|
62
|
+
|
63
|
+
# PASSWORD MANAGEMENT COMMANDS
|
64
|
+
def change_current_user_password(self, request: ChangePasswordRequest) -> Dict[str, Any]:
|
65
|
+
"""Change current user password."""
|
66
|
+
command = ChangeCurrentUserPasswordCommand(self.http_client, request)
|
67
|
+
return command.execute()
|
68
|
+
|
69
|
+
def set_current_api_user_password_by_id(self, request: SetAPIUserPasswordRequest) -> Dict[str, Any]:
|
70
|
+
"""Set current API user password by ID."""
|
71
|
+
command = SetAPIUserPasswordCommand(self.http_client, request)
|
72
|
+
return command.execute()
|
73
|
+
|
74
|
+
def reset_password_by_id(self, user_id: str, request: ResetPasswordRequest) -> Dict[str, Any]:
|
75
|
+
"""Reset password by user ID."""
|
76
|
+
command = ResetPasswordCommand(self.http_client, user_id, request)
|
77
|
+
return command.execute()
|
78
|
+
|
79
|
+
def reset_tfa(self, user_id: str) -> Dict[str, Any]:
|
80
|
+
"""Reset TFA for user."""
|
81
|
+
command = ResetTFACommand(self.http_client, user_id)
|
82
|
+
return command.execute()
|
83
|
+
|
84
|
+
# AI USER OPERATIONS
|
85
|
+
def get_ai_user(self) -> AIUser:
|
86
|
+
"""Get the AI user."""
|
87
|
+
query = GetAIUserQuery(self.http_client)
|
88
|
+
return query.execute()
|
89
|
+
|
90
|
+
def create_ai_user(self, request: CreateAIUserRequest) -> AIUser:
|
91
|
+
"""Create a new AI user."""
|
92
|
+
command = CreateAIUserCommand(self.http_client, request)
|
93
|
+
return command.execute()
|
94
|
+
|
95
|
+
# API USER OPERATIONS
|
96
|
+
def get_api_user(self) -> APIUser:
|
97
|
+
"""Get the API user."""
|
98
|
+
query = GetAPIUserQuery(self.http_client)
|
99
|
+
return query.execute()
|
100
|
+
|
101
|
+
def create_api_user(self, request: CreateAPIUserRequest) -> APIUser:
|
102
|
+
"""Create a new API user."""
|
103
|
+
command = CreateAPIUserCommand(self.http_client, request)
|
104
|
+
return command.execute()
|
105
|
+
|
106
|
+
# PRIVILEGE MANAGEMENT
|
107
|
+
def get_privileges(self) -> List[Privilege]:
|
108
|
+
"""Get all privileges."""
|
109
|
+
query = GetPrivilegesQuery(self.http_client)
|
110
|
+
return query.execute()
|
111
|
+
|
112
|
+
# ROLE MANAGEMENT OPERATIONS
|
113
|
+
def get_roles(self) -> List[Role]:
|
114
|
+
"""Get all roles."""
|
115
|
+
query = ListRolesQuery(self.http_client)
|
116
|
+
return query.execute()
|
117
|
+
|
118
|
+
def create_role(self, request: CreateRoleRequest) -> Role:
|
119
|
+
"""Create a new role."""
|
120
|
+
command = CreateRoleCommand(self.http_client, request)
|
121
|
+
return command.execute()
|
122
|
+
|
123
|
+
def get_role_by_id(self, role_id: str) -> Role:
|
124
|
+
"""Get a specific role by ID."""
|
125
|
+
query = GetRoleQuery(self.http_client, role_id)
|
126
|
+
return query.execute()
|
127
|
+
|
128
|
+
def update_role_by_id(self, role_id: str, request: UpdateRoleRequest) -> Role:
|
129
|
+
"""Update an existing role."""
|
130
|
+
command = UpdateRoleCommand(self.http_client, role_id, request)
|
131
|
+
return command.execute()
|
132
|
+
|
133
|
+
def delete_role_by_id(self, role_id: str) -> Dict[str, Any]:
|
134
|
+
"""Delete a role."""
|
135
|
+
command = DeleteRoleCommand(self.http_client, role_id)
|
136
|
+
return command.execute()
|
137
|
+
|
138
|
+
# USER GROUP MANAGEMENT OPERATIONS
|
139
|
+
def get_user_groups(self, filter_params: Optional[UserGroupFilter] = None) -> List[UserGroup]:
|
140
|
+
"""Get all user groups with optional filtering."""
|
141
|
+
query = ListUserGroupsQuery(self.http_client, filter_params)
|
142
|
+
return query.execute()
|
143
|
+
|
144
|
+
def create_user_group(self, request: CreateUserGroupRequest) -> UserGroup:
|
145
|
+
"""Create a new user group."""
|
146
|
+
command = CreateUserGroupCommand(self.http_client, request)
|
147
|
+
return command.execute()
|
148
|
+
|
149
|
+
def get_user_group_by_id(self, group_id: str) -> UserGroup:
|
150
|
+
"""Get a specific user group by ID."""
|
151
|
+
query = GetUserGroupQuery(self.http_client, group_id)
|
152
|
+
return query.execute()
|
153
|
+
|
154
|
+
def delete_user_group_by_id(self, group_id: str) -> Dict[str, Any]:
|
155
|
+
"""Delete a user group."""
|
156
|
+
command = DeleteUserGroupCommand(self.http_client, group_id)
|
157
|
+
return command.execute()
|
158
|
+
|
159
|
+
def update_user_group_by_id(self, group_id: str, request: UpdateUserGroupRequest) -> UserGroup:
|
160
|
+
"""Update an existing user group."""
|
161
|
+
command = UpdateUserGroupCommand(self.http_client, group_id, request)
|
162
|
+
return command.execute()
|
163
|
+
|
164
|
+
# CONVENIENCE ALIASES
|
165
|
+
def list(self, filter_params: Optional[UserFilter] = None) -> List[UserManagementUser]:
|
166
|
+
"""Alias for list_users."""
|
167
|
+
return self.list_users(filter_params)
|
168
|
+
|
169
|
+
def get(self, user_id: str) -> UserManagementUser:
|
170
|
+
"""Alias for get_user."""
|
171
|
+
return self.get_user(user_id)
|
172
|
+
|
173
|
+
def create(self, request: CreateUserRequest) -> UserManagementUser:
|
174
|
+
"""Alias for create_user."""
|
175
|
+
return self.create_user(request)
|
176
|
+
|
177
|
+
def update(self, user_id: str, request: UpdateUserRequest) -> UserManagementUser:
|
178
|
+
"""Alias for update_user."""
|
179
|
+
return self.update_user(user_id, request)
|
180
|
+
|
181
|
+
def delete(self, user_id: str) -> Dict[str, Any]:
|
182
|
+
"""Alias for delete_user."""
|
183
|
+
return self.delete_user(user_id)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
"""
|
2
|
+
Webhook Executions API for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Optional, Dict, Any
|
6
|
+
|
7
|
+
from ..http_client import HTTPClient
|
8
|
+
from ..models.webhook_executions import WebhookExecutionResponse, WebhookPostRequest, TaskDetailsData
|
9
|
+
from ..queries.webhook_executions import GetTaskDetailsQuery
|
10
|
+
from ..commands.webhook_executions import ExecuteWebhookGetCommand, ExecuteWebhookPostCommand, RetryWebhookExecutionCommand
|
11
|
+
|
12
|
+
|
13
|
+
class WebhookExecutionsAPI:
|
14
|
+
"""Webhook Executions API with CQRS pattern - separated queries and commands."""
|
15
|
+
|
16
|
+
def __init__(self, http_client: HTTPClient):
|
17
|
+
self.http_client = http_client
|
18
|
+
|
19
|
+
# QUERIES (Read operations)
|
20
|
+
def get_task_details(self, slug: str, task_id: str, token: str) -> TaskDetailsData:
|
21
|
+
"""Get task details data for a webhook execution."""
|
22
|
+
query = GetTaskDetailsQuery(self.http_client, slug, task_id, token)
|
23
|
+
return query.execute()
|
24
|
+
|
25
|
+
# COMMANDS (Write operations)
|
26
|
+
def execute_webhook_get(self, slug: str, data: str, token: str) -> WebhookExecutionResponse:
|
27
|
+
"""Execute webhook via GET request."""
|
28
|
+
command = ExecuteWebhookGetCommand(self.http_client, slug, data, token)
|
29
|
+
return command.execute()
|
30
|
+
|
31
|
+
def execute_webhook_post(self, slug: str, token: str, request_data: WebhookPostRequest) -> WebhookExecutionResponse:
|
32
|
+
"""Execute webhook via POST request."""
|
33
|
+
command = ExecuteWebhookPostCommand(self.http_client, slug, token, request_data)
|
34
|
+
return command.execute()
|
35
|
+
|
36
|
+
def retry_execution(self, execution_id: str) -> Dict[str, Any]:
|
37
|
+
"""Retry a failed webhook execution."""
|
38
|
+
command = RetryWebhookExecutionCommand(self.http_client, execution_id)
|
39
|
+
return command.execute()
|
40
|
+
|
41
|
+
# Convenience methods
|
42
|
+
def execute_webhook_with_hostnames(self, slug: str, hostnames: list, token: str) -> WebhookExecutionResponse:
|
43
|
+
"""Execute webhook with comma-separated hostnames."""
|
44
|
+
data = ",".join(hostnames)
|
45
|
+
return self.execute_webhook_get(slug, data, token)
|
46
|
+
|
47
|
+
def execute_webhook_with_ips(self, slug: str, ip_addresses: list, token: str) -> WebhookExecutionResponse:
|
48
|
+
"""Execute webhook with comma-separated IP addresses."""
|
49
|
+
data = ",".join(ip_addresses)
|
50
|
+
return self.execute_webhook_get(slug, data, token)
|