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,360 @@
|
|
1
|
+
"""
|
2
|
+
Triage-related commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any, Union
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..models.triage import (
|
9
|
+
TriageRule, TriageTag, TriageProfile, CreateTriageRuleRequest,
|
10
|
+
UpdateTriageRuleRequest, CreateTriageTagRequest, CreateTriageProfileRequest
|
11
|
+
)
|
12
|
+
from ..http_client import HTTPClient
|
13
|
+
|
14
|
+
|
15
|
+
class CreateTriageRuleCommand(Command[TriageRule]):
|
16
|
+
"""Command to create a new triage rule."""
|
17
|
+
|
18
|
+
def __init__(self, http_client: HTTPClient, request: Union[CreateTriageRuleRequest, Dict[str, Any]]):
|
19
|
+
self.http_client = http_client
|
20
|
+
self.request = request
|
21
|
+
|
22
|
+
def execute(self) -> TriageRule:
|
23
|
+
"""Execute the command to create a triage rule."""
|
24
|
+
# Handle both dict and model objects
|
25
|
+
if isinstance(self.request, dict):
|
26
|
+
data = self.request.copy()
|
27
|
+
else:
|
28
|
+
# Convert SDK model fields to API fields
|
29
|
+
request_dict = self.request.model_dump(exclude_none=True)
|
30
|
+
data = {
|
31
|
+
"description": request_dict.get("description") or request_dict.get("name", ""),
|
32
|
+
"rule": request_dict.get("rule_content", ""),
|
33
|
+
"engine": request_dict.get("type", "yara"),
|
34
|
+
"searchIn": request_dict.get("search_in", "filesystem"),
|
35
|
+
"organizationIds": [request_dict.get("organization_id", 0)]
|
36
|
+
}
|
37
|
+
|
38
|
+
response = self.http_client.post("triages/rules", json_data=data)
|
39
|
+
|
40
|
+
entity_data = response.get("result", {})
|
41
|
+
|
42
|
+
mapped_data = {
|
43
|
+
"id": entity_data.get("_id"),
|
44
|
+
"name": entity_data.get("description", ""), # API uses description as name
|
45
|
+
"description": entity_data.get("description"),
|
46
|
+
"type": entity_data.get("engine"), # API uses engine field
|
47
|
+
"rule_content": entity_data.get("rule", ""),
|
48
|
+
"search_in": entity_data.get("searchIn"),
|
49
|
+
"enabled": entity_data.get("enabled", True),
|
50
|
+
"severity": entity_data.get("severity", "medium"),
|
51
|
+
"tags": entity_data.get("tags", []),
|
52
|
+
"organization_id": entity_data.get("organizationIds", [0])[0] if entity_data.get("organizationIds") else 0,
|
53
|
+
"organization_ids": entity_data.get("organizationIds", []),
|
54
|
+
"created_at": entity_data.get("createdAt"),
|
55
|
+
"updated_at": entity_data.get("updatedAt"),
|
56
|
+
"created_by": entity_data.get("createdBy"),
|
57
|
+
"updated_by": entity_data.get("updatedBy"),
|
58
|
+
"match_count": entity_data.get("matchCount", 0),
|
59
|
+
"last_match": entity_data.get("lastMatch"),
|
60
|
+
"deletable": entity_data.get("deletable"),
|
61
|
+
}
|
62
|
+
|
63
|
+
# Remove None values
|
64
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
65
|
+
|
66
|
+
return TriageRule(**mapped_data)
|
67
|
+
|
68
|
+
|
69
|
+
class UpdateTriageRuleCommand(Command[TriageRule]):
|
70
|
+
"""Command to update an existing triage rule."""
|
71
|
+
|
72
|
+
def __init__(self, http_client: HTTPClient, rule_id: str, request: Union[UpdateTriageRuleRequest, Dict[str, Any]]):
|
73
|
+
self.http_client = http_client
|
74
|
+
self.rule_id = rule_id
|
75
|
+
self.request = request
|
76
|
+
|
77
|
+
def execute(self) -> TriageRule:
|
78
|
+
"""Execute the command to update a triage rule."""
|
79
|
+
# Handle both dict and model objects
|
80
|
+
if isinstance(self.request, dict):
|
81
|
+
data = self.request.copy()
|
82
|
+
else:
|
83
|
+
# Convert SDK model fields to API fields
|
84
|
+
request_dict = self.request.model_dump(exclude_none=True)
|
85
|
+
data = {}
|
86
|
+
|
87
|
+
# Map SDK fields to API fields for update
|
88
|
+
if "description" in request_dict or "name" in request_dict:
|
89
|
+
data["description"] = request_dict.get("description") or request_dict.get("name", "")
|
90
|
+
if "rule_content" in request_dict:
|
91
|
+
data["rule"] = request_dict.get("rule_content")
|
92
|
+
if "type" in request_dict:
|
93
|
+
data["engine"] = request_dict.get("type")
|
94
|
+
if "search_in" in request_dict:
|
95
|
+
data["searchIn"] = request_dict.get("search_in")
|
96
|
+
if "organization_id" in request_dict:
|
97
|
+
data["organizationIds"] = [request_dict.get("organization_id")]
|
98
|
+
if "enabled" in request_dict:
|
99
|
+
data["enabled"] = request_dict.get("enabled")
|
100
|
+
|
101
|
+
response = self.http_client.put(f"triages/rules/{self.rule_id}", json_data=data)
|
102
|
+
|
103
|
+
entity_data = response.get("result", {})
|
104
|
+
|
105
|
+
mapped_data = {
|
106
|
+
"id": entity_data.get("_id"),
|
107
|
+
"name": entity_data.get("description", ""), # API uses description as name
|
108
|
+
"description": entity_data.get("description"),
|
109
|
+
"type": entity_data.get("engine"), # API uses engine field
|
110
|
+
"rule_content": entity_data.get("rule", ""),
|
111
|
+
"search_in": entity_data.get("searchIn"),
|
112
|
+
"enabled": entity_data.get("enabled", True),
|
113
|
+
"severity": entity_data.get("severity", "medium"),
|
114
|
+
"tags": entity_data.get("tags", []),
|
115
|
+
"organization_id": entity_data.get("organizationIds", [0])[0] if entity_data.get("organizationIds") else 0,
|
116
|
+
"organization_ids": entity_data.get("organizationIds", []),
|
117
|
+
"created_at": entity_data.get("createdAt"),
|
118
|
+
"updated_at": entity_data.get("updatedAt"),
|
119
|
+
"created_by": entity_data.get("createdBy"),
|
120
|
+
"updated_by": entity_data.get("updatedBy"),
|
121
|
+
"match_count": entity_data.get("matchCount", 0),
|
122
|
+
"last_match": entity_data.get("lastMatch"),
|
123
|
+
"deletable": entity_data.get("deletable"),
|
124
|
+
}
|
125
|
+
|
126
|
+
# Remove None values
|
127
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
128
|
+
|
129
|
+
return TriageRule(**mapped_data)
|
130
|
+
|
131
|
+
|
132
|
+
class DeleteTriageRuleCommand(Command[Dict[str, Any]]):
|
133
|
+
"""Command to delete a triage rule."""
|
134
|
+
|
135
|
+
def __init__(self, http_client: HTTPClient, rule_id: str):
|
136
|
+
self.http_client = http_client
|
137
|
+
self.rule_id = rule_id
|
138
|
+
|
139
|
+
def execute(self) -> Dict[str, Any]:
|
140
|
+
"""Execute the command to delete a triage rule."""
|
141
|
+
response = self.http_client.delete(f"triages/rules/{self.rule_id}")
|
142
|
+
return response
|
143
|
+
|
144
|
+
|
145
|
+
class EnableTriageRuleCommand(Command[TriageRule]):
|
146
|
+
"""Command to enable a triage rule."""
|
147
|
+
|
148
|
+
def __init__(self, http_client: HTTPClient, rule_id: str):
|
149
|
+
self.http_client = http_client
|
150
|
+
self.rule_id = rule_id
|
151
|
+
|
152
|
+
def execute(self) -> TriageRule:
|
153
|
+
"""Execute the command to enable a triage rule."""
|
154
|
+
data = {"enabled": True}
|
155
|
+
|
156
|
+
response = self.http_client.put(f"triages/rules/{self.rule_id}", json_data=data)
|
157
|
+
|
158
|
+
entity_data = response.get("result", {})
|
159
|
+
|
160
|
+
mapped_data = {
|
161
|
+
"id": entity_data.get("_id"),
|
162
|
+
"name": entity_data.get("name"),
|
163
|
+
"description": entity_data.get("description"),
|
164
|
+
"type": entity_data.get("type"),
|
165
|
+
"rule_content": entity_data.get("ruleContent", ""),
|
166
|
+
"enabled": entity_data.get("enabled", True),
|
167
|
+
"severity": entity_data.get("severity", "medium"),
|
168
|
+
"tags": entity_data.get("tags", []),
|
169
|
+
"organization_id": entity_data.get("organizationId", 0),
|
170
|
+
"created_at": entity_data.get("createdAt"),
|
171
|
+
"updated_at": entity_data.get("updatedAt"),
|
172
|
+
"created_by": entity_data.get("createdBy"),
|
173
|
+
"updated_by": entity_data.get("updatedBy"),
|
174
|
+
"match_count": entity_data.get("matchCount", 0),
|
175
|
+
"last_match": entity_data.get("lastMatch"),
|
176
|
+
}
|
177
|
+
|
178
|
+
# Remove None values
|
179
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
180
|
+
|
181
|
+
return TriageRule(**mapped_data)
|
182
|
+
|
183
|
+
|
184
|
+
class DisableTriageRuleCommand(Command[TriageRule]):
|
185
|
+
"""Command to disable a triage rule."""
|
186
|
+
|
187
|
+
def __init__(self, http_client: HTTPClient, rule_id: str):
|
188
|
+
self.http_client = http_client
|
189
|
+
self.rule_id = rule_id
|
190
|
+
|
191
|
+
def execute(self) -> TriageRule:
|
192
|
+
"""Execute the command to disable a triage rule."""
|
193
|
+
data = {"enabled": False}
|
194
|
+
|
195
|
+
response = self.http_client.put(f"triages/rules/{self.rule_id}", json_data=data)
|
196
|
+
|
197
|
+
entity_data = response.get("result", {})
|
198
|
+
|
199
|
+
mapped_data = {
|
200
|
+
"id": entity_data.get("_id"),
|
201
|
+
"name": entity_data.get("name"),
|
202
|
+
"description": entity_data.get("description"),
|
203
|
+
"type": entity_data.get("type"),
|
204
|
+
"rule_content": entity_data.get("ruleContent", ""),
|
205
|
+
"enabled": entity_data.get("enabled", True),
|
206
|
+
"severity": entity_data.get("severity", "medium"),
|
207
|
+
"tags": entity_data.get("tags", []),
|
208
|
+
"organization_id": entity_data.get("organizationId", 0),
|
209
|
+
"created_at": entity_data.get("createdAt"),
|
210
|
+
"updated_at": entity_data.get("updatedAt"),
|
211
|
+
"created_by": entity_data.get("createdBy"),
|
212
|
+
"updated_by": entity_data.get("updatedBy"),
|
213
|
+
"match_count": entity_data.get("matchCount", 0),
|
214
|
+
"last_match": entity_data.get("lastMatch"),
|
215
|
+
}
|
216
|
+
|
217
|
+
# Remove None values
|
218
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
219
|
+
|
220
|
+
return TriageRule(**mapped_data)
|
221
|
+
|
222
|
+
|
223
|
+
class CreateTriageTagCommand(Command[TriageTag]):
|
224
|
+
"""Command to create a new triage tag."""
|
225
|
+
|
226
|
+
def __init__(self, http_client: HTTPClient, request: Union[CreateTriageTagRequest, Dict[str, Any]]):
|
227
|
+
self.http_client = http_client
|
228
|
+
self.request = request
|
229
|
+
|
230
|
+
def execute(self) -> TriageTag:
|
231
|
+
"""Execute the command to create a triage tag."""
|
232
|
+
# Handle both dict and model objects
|
233
|
+
if isinstance(self.request, dict):
|
234
|
+
data = self.request
|
235
|
+
else:
|
236
|
+
data = self.request.model_dump(exclude_none=True)
|
237
|
+
|
238
|
+
response = self.http_client.post("triages/tags", json_data=data)
|
239
|
+
|
240
|
+
entity_data = response.get("result", {})
|
241
|
+
|
242
|
+
mapped_data = {
|
243
|
+
"id": entity_data.get("id") or entity_data.get("_id"), # Handle both id and _id
|
244
|
+
"name": entity_data.get("name"),
|
245
|
+
"description": entity_data.get("description"),
|
246
|
+
"color": entity_data.get("color", "#3498db"),
|
247
|
+
"organization_id": entity_data.get("organizationId", 0),
|
248
|
+
"created_at": entity_data.get("createdAt"),
|
249
|
+
"updated_at": entity_data.get("updatedAt"),
|
250
|
+
"created_by": entity_data.get("createdBy", "Unknown"), # Provide default for required field
|
251
|
+
"usage_count": entity_data.get("usageCount") or entity_data.get("count", 0), # Handle both count and usageCount
|
252
|
+
}
|
253
|
+
|
254
|
+
# Remove None values but keep defaults for required fields
|
255
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
256
|
+
|
257
|
+
return TriageTag(**mapped_data)
|
258
|
+
|
259
|
+
|
260
|
+
class DeleteTriageTagCommand(Command[Dict[str, Any]]):
|
261
|
+
"""Command to delete a triage tag."""
|
262
|
+
|
263
|
+
def __init__(self, http_client: HTTPClient, tag_id: str):
|
264
|
+
self.http_client = http_client
|
265
|
+
self.tag_id = tag_id
|
266
|
+
|
267
|
+
def execute(self) -> Dict[str, Any]:
|
268
|
+
"""Execute the command to delete a triage tag."""
|
269
|
+
response = self.http_client.delete(f"triage/tags/{self.tag_id}")
|
270
|
+
return response
|
271
|
+
|
272
|
+
|
273
|
+
class CreateTriageProfileCommand(Command[TriageProfile]):
|
274
|
+
"""Command to create a new triage profile."""
|
275
|
+
|
276
|
+
def __init__(self, http_client: HTTPClient, request: Union[CreateTriageProfileRequest, Dict[str, Any]]):
|
277
|
+
self.http_client = http_client
|
278
|
+
self.request = request
|
279
|
+
|
280
|
+
def execute(self) -> TriageProfile:
|
281
|
+
"""Execute the command to create a triage profile."""
|
282
|
+
# Handle both dict and model objects
|
283
|
+
if isinstance(self.request, dict):
|
284
|
+
data = self.request
|
285
|
+
else:
|
286
|
+
data = self.request.model_dump(exclude_none=True)
|
287
|
+
|
288
|
+
response = self.http_client.post("triage/profiles", json_data=data)
|
289
|
+
|
290
|
+
entity_data = response.get("result", {})
|
291
|
+
|
292
|
+
mapped_data = {
|
293
|
+
"id": entity_data.get("_id"),
|
294
|
+
"name": entity_data.get("name"),
|
295
|
+
"description": entity_data.get("description"),
|
296
|
+
"rules": entity_data.get("rules", []),
|
297
|
+
"enabled": entity_data.get("enabled", True),
|
298
|
+
"organization_id": entity_data.get("organizationId", 0),
|
299
|
+
"created_at": entity_data.get("createdAt"),
|
300
|
+
"updated_at": entity_data.get("updatedAt"),
|
301
|
+
"created_by": entity_data.get("createdBy"),
|
302
|
+
"updated_by": entity_data.get("updatedBy"),
|
303
|
+
}
|
304
|
+
|
305
|
+
# Remove None values
|
306
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
307
|
+
|
308
|
+
return TriageProfile(**mapped_data)
|
309
|
+
|
310
|
+
|
311
|
+
class UpdateTriageProfileCommand(Command[TriageProfile]):
|
312
|
+
"""Command to update an existing triage profile."""
|
313
|
+
|
314
|
+
def __init__(self, http_client: HTTPClient, profile_id: str, request: Union[CreateTriageProfileRequest, Dict[str, Any]]):
|
315
|
+
self.http_client = http_client
|
316
|
+
self.profile_id = profile_id
|
317
|
+
self.request = request
|
318
|
+
|
319
|
+
def execute(self) -> TriageProfile:
|
320
|
+
"""Execute the command to update a triage profile."""
|
321
|
+
# Handle both dict and model objects
|
322
|
+
if isinstance(self.request, dict):
|
323
|
+
data = self.request
|
324
|
+
else:
|
325
|
+
data = self.request.model_dump(exclude_none=True)
|
326
|
+
|
327
|
+
response = self.http_client.put(f"triage/profiles/{self.profile_id}", json_data=data)
|
328
|
+
|
329
|
+
entity_data = response.get("result", {})
|
330
|
+
|
331
|
+
mapped_data = {
|
332
|
+
"id": entity_data.get("_id"),
|
333
|
+
"name": entity_data.get("name"),
|
334
|
+
"description": entity_data.get("description"),
|
335
|
+
"rules": entity_data.get("rules", []),
|
336
|
+
"enabled": entity_data.get("enabled", True),
|
337
|
+
"organization_id": entity_data.get("organizationId", 0),
|
338
|
+
"created_at": entity_data.get("createdAt"),
|
339
|
+
"updated_at": entity_data.get("updatedAt"),
|
340
|
+
"created_by": entity_data.get("createdBy"),
|
341
|
+
"updated_by": entity_data.get("updatedBy"),
|
342
|
+
}
|
343
|
+
|
344
|
+
# Remove None values
|
345
|
+
mapped_data = {k: v for k, v in mapped_data.items() if v is not None}
|
346
|
+
|
347
|
+
return TriageProfile(**mapped_data)
|
348
|
+
|
349
|
+
|
350
|
+
class DeleteTriageProfileCommand(Command[Dict[str, Any]]):
|
351
|
+
"""Command to delete a triage profile."""
|
352
|
+
|
353
|
+
def __init__(self, http_client: HTTPClient, profile_id: str):
|
354
|
+
self.http_client = http_client
|
355
|
+
self.profile_id = profile_id
|
356
|
+
|
357
|
+
def execute(self) -> Dict[str, Any]:
|
358
|
+
"""Execute the command to delete a triage profile."""
|
359
|
+
response = self.http_client.delete(f"triage/profiles/{self.profile_id}")
|
360
|
+
return response
|
@@ -0,0 +1,126 @@
|
|
1
|
+
"""
|
2
|
+
User Management-related commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any, Union
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..models.user_management import (
|
9
|
+
UserManagementUser, CreateUserRequest, UpdateUserRequest,
|
10
|
+
AIUser, CreateAIUserRequest, APIUser, CreateAPIUserRequest
|
11
|
+
)
|
12
|
+
from ..http_client import HTTPClient
|
13
|
+
|
14
|
+
|
15
|
+
class CreateUserCommand(Command[UserManagementUser]):
|
16
|
+
"""Command to create user."""
|
17
|
+
|
18
|
+
def __init__(self, http_client: HTTPClient, request: Union[CreateUserRequest, Dict[str, Any]]):
|
19
|
+
self.http_client = http_client
|
20
|
+
self.request = request
|
21
|
+
|
22
|
+
def execute(self) -> UserManagementUser:
|
23
|
+
"""Execute the create user command."""
|
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)
|
29
|
+
|
30
|
+
response = self.http_client.post("user-management/users", json_data=payload)
|
31
|
+
|
32
|
+
if response.get("success"):
|
33
|
+
user_data = response.get("result", {})
|
34
|
+
return UserManagementUser(**user_data)
|
35
|
+
|
36
|
+
raise Exception(f"Failed to create user: {response.get('error', 'Unknown error')}")
|
37
|
+
|
38
|
+
|
39
|
+
class UpdateUserCommand(Command[UserManagementUser]):
|
40
|
+
"""Command to update user."""
|
41
|
+
|
42
|
+
def __init__(self, http_client: HTTPClient, user_id: str, request: Union[UpdateUserRequest, Dict[str, Any]]):
|
43
|
+
self.http_client = http_client
|
44
|
+
self.user_id = user_id
|
45
|
+
self.request = request
|
46
|
+
|
47
|
+
def execute(self) -> UserManagementUser:
|
48
|
+
"""Execute the update user command."""
|
49
|
+
# Handle both dict and model objects
|
50
|
+
if isinstance(self.request, dict):
|
51
|
+
payload = self.request
|
52
|
+
else:
|
53
|
+
payload = self.request.model_dump(exclude_none=True)
|
54
|
+
|
55
|
+
response = self.http_client.put(f"user-management/users/{self.user_id}", json_data=payload)
|
56
|
+
|
57
|
+
if response.get("success"):
|
58
|
+
user_data = response.get("result", {})
|
59
|
+
return UserManagementUser(**user_data)
|
60
|
+
|
61
|
+
raise Exception(f"Failed to update user: {response.get('error', 'Unknown error')}")
|
62
|
+
|
63
|
+
|
64
|
+
class DeleteUserCommand(Command[Dict[str, Any]]):
|
65
|
+
"""Command to delete user."""
|
66
|
+
|
67
|
+
def __init__(self, http_client: HTTPClient, user_id: str):
|
68
|
+
self.http_client = http_client
|
69
|
+
self.user_id = user_id
|
70
|
+
|
71
|
+
def execute(self) -> Dict[str, Any]:
|
72
|
+
"""Execute the delete user command."""
|
73
|
+
response = self.http_client.delete(f"user-management/users/{self.user_id}")
|
74
|
+
|
75
|
+
if response.get("success"):
|
76
|
+
return response
|
77
|
+
|
78
|
+
raise Exception(f"Failed to delete user: {response.get('error', 'Unknown error')}")
|
79
|
+
|
80
|
+
|
81
|
+
class CreateAIUserCommand(Command[AIUser]):
|
82
|
+
"""Command to create AI user."""
|
83
|
+
|
84
|
+
def __init__(self, http_client: HTTPClient, request: Union[CreateAIUserRequest, Dict[str, Any]]):
|
85
|
+
self.http_client = http_client
|
86
|
+
self.request = request
|
87
|
+
|
88
|
+
def execute(self) -> AIUser:
|
89
|
+
"""Execute the create AI user command."""
|
90
|
+
# Handle both dict and model objects
|
91
|
+
if isinstance(self.request, dict):
|
92
|
+
payload = self.request
|
93
|
+
else:
|
94
|
+
payload = self.request.model_dump(exclude_none=True)
|
95
|
+
|
96
|
+
response = self.http_client.post("user-management/users/ai-user", json_data=payload)
|
97
|
+
|
98
|
+
if response.get("success"):
|
99
|
+
ai_user_data = response.get("result", {})
|
100
|
+
return AIUser(**ai_user_data)
|
101
|
+
|
102
|
+
raise Exception(f"Failed to create AI user: {response.get('error', 'Unknown error')}")
|
103
|
+
|
104
|
+
|
105
|
+
class CreateAPIUserCommand(Command[APIUser]):
|
106
|
+
"""Command to create API user."""
|
107
|
+
|
108
|
+
def __init__(self, http_client: HTTPClient, request: Union[CreateAPIUserRequest, Dict[str, Any]]):
|
109
|
+
self.http_client = http_client
|
110
|
+
self.request = request
|
111
|
+
|
112
|
+
def execute(self) -> APIUser:
|
113
|
+
"""Execute the create API user command."""
|
114
|
+
# Handle both dict and model objects
|
115
|
+
if isinstance(self.request, dict):
|
116
|
+
payload = self.request
|
117
|
+
else:
|
118
|
+
payload = self.request.model_dump(exclude_none=True)
|
119
|
+
|
120
|
+
response = self.http_client.post("user-management/users/api-user", json_data=payload)
|
121
|
+
|
122
|
+
if response.get("success"):
|
123
|
+
api_user_data = response.get("result", {})
|
124
|
+
return APIUser(**api_user_data)
|
125
|
+
|
126
|
+
raise Exception(f"Failed to create API user: {response.get('error', 'Unknown error')}")
|
@@ -0,0 +1,101 @@
|
|
1
|
+
"""
|
2
|
+
Users-related commands for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import Dict, Any, Union
|
6
|
+
|
7
|
+
from ..base import Command
|
8
|
+
from ..models.users import (
|
9
|
+
User, CreateUserRequest, UpdateUserRequest,
|
10
|
+
APIUser, CreateAPIUserRequest
|
11
|
+
)
|
12
|
+
from ..http_client import HTTPClient
|
13
|
+
|
14
|
+
|
15
|
+
class CreateUserCommand(Command[User]):
|
16
|
+
"""Command to create user."""
|
17
|
+
|
18
|
+
def __init__(self, http_client: HTTPClient, request: Union[CreateUserRequest, Dict[str, Any]]):
|
19
|
+
self.http_client = http_client
|
20
|
+
self.request = request
|
21
|
+
|
22
|
+
def execute(self) -> User:
|
23
|
+
"""Execute the create user command."""
|
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)
|
29
|
+
|
30
|
+
# Use the correct endpoint path from API JSON files
|
31
|
+
response = self.http_client.post("user-management/users", json_data=payload)
|
32
|
+
|
33
|
+
if response.get("success"):
|
34
|
+
user_data = response.get("result", {})
|
35
|
+
return User(**user_data)
|
36
|
+
|
37
|
+
raise Exception(f"Failed to create user: {response.get('error', 'Unknown error')}")
|
38
|
+
|
39
|
+
|
40
|
+
class UpdateUserCommand(Command[User]):
|
41
|
+
"""Command to update user."""
|
42
|
+
|
43
|
+
def __init__(self, http_client: HTTPClient, user_id: str, request: Union[UpdateUserRequest, Dict[str, Any]]):
|
44
|
+
self.http_client = http_client
|
45
|
+
self.user_id = user_id
|
46
|
+
self.request = request
|
47
|
+
|
48
|
+
def execute(self) -> User:
|
49
|
+
"""Execute the update user command."""
|
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
|
+
# Use the correct endpoint path from API JSON files
|
57
|
+
response = self.http_client.put(f"user-management/users/{self.user_id}", json_data=payload)
|
58
|
+
|
59
|
+
if response.get("success"):
|
60
|
+
user_data = response.get("result", {})
|
61
|
+
return User(**user_data)
|
62
|
+
|
63
|
+
raise Exception(f"Failed to update user: {response.get('error', 'Unknown error')}")
|
64
|
+
|
65
|
+
|
66
|
+
class DeleteUserCommand(Command[Dict[str, Any]]):
|
67
|
+
"""Command to delete user."""
|
68
|
+
|
69
|
+
def __init__(self, http_client: HTTPClient, user_id: str):
|
70
|
+
self.http_client = http_client
|
71
|
+
self.user_id = user_id
|
72
|
+
|
73
|
+
def execute(self) -> Dict[str, Any]:
|
74
|
+
"""Execute the delete user command."""
|
75
|
+
# Use the correct endpoint path from API JSON files
|
76
|
+
response = self.http_client.delete(f"user-management/users/{self.user_id}")
|
77
|
+
|
78
|
+
if response.get("success"):
|
79
|
+
return response
|
80
|
+
|
81
|
+
raise Exception(f"Failed to delete user: {response.get('error', 'Unknown error')}")
|
82
|
+
|
83
|
+
|
84
|
+
class CreateAPIUserCommand(Command[Dict[str, Any]]):
|
85
|
+
"""Command to create API user."""
|
86
|
+
|
87
|
+
def __init__(self, http_client: HTTPClient, request: Union[Dict[str, Any], CreateAPIUserRequest]):
|
88
|
+
self.http_client = http_client
|
89
|
+
self.request = request
|
90
|
+
|
91
|
+
def execute(self) -> Dict[str, Any]:
|
92
|
+
"""Execute the create API user command."""
|
93
|
+
# Handle both dict and model objects
|
94
|
+
if isinstance(self.request, dict):
|
95
|
+
payload = self.request
|
96
|
+
else:
|
97
|
+
payload = self.request.model_dump(exclude_none=True)
|
98
|
+
|
99
|
+
# Use the correct endpoint path from API JSON files
|
100
|
+
response = self.http_client.post("user-management/users/api-user", json_data=payload)
|
101
|
+
return response
|