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
binalyze_air/queries/tasks.py
CHANGED
@@ -1,82 +1,126 @@
|
|
1
|
-
"""
|
2
|
-
Task-related queries for the Binalyze AIR SDK.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from typing import List, Optional
|
6
|
-
|
7
|
-
from ..base import Query
|
8
|
-
from ..models.tasks import Task, TaskFilter, TaskData, PlatformEvidenceConfig, TaskConfig, DroneConfig, TaskAssignment
|
9
|
-
from ..http_client import HTTPClient
|
10
|
-
|
11
|
-
|
12
|
-
class ListTasksQuery(Query[List[Task]]):
|
13
|
-
"""Query to list tasks with optional filtering."""
|
14
|
-
|
15
|
-
def __init__(self, http_client: HTTPClient, filter_params: Optional[TaskFilter] = None, organization_ids: Optional[List[int]] = None):
|
16
|
-
self.http_client = http_client
|
17
|
-
self.filter_params = filter_params or TaskFilter()
|
18
|
-
self.organization_ids = organization_ids
|
19
|
-
|
20
|
-
def execute(self) -> List[Task]:
|
21
|
-
"""Execute the query to list tasks."""
|
22
|
-
params = self.filter_params.to_params()
|
23
|
-
|
24
|
-
# Add organization IDs
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
1
|
+
"""
|
2
|
+
Task-related queries for the Binalyze AIR SDK.
|
3
|
+
"""
|
4
|
+
|
5
|
+
from typing import List, Optional
|
6
|
+
|
7
|
+
from ..base import Query, ensure_organization_ids, format_organization_ids_param
|
8
|
+
from ..models.tasks import Task, TaskFilter, TaskData, PlatformEvidenceConfig, TaskConfig, DroneConfig, TaskAssignment
|
9
|
+
from ..http_client import HTTPClient
|
10
|
+
|
11
|
+
|
12
|
+
class ListTasksQuery(Query[List[Task]]):
|
13
|
+
"""Query to list tasks with optional filtering."""
|
14
|
+
|
15
|
+
def __init__(self, http_client: HTTPClient, filter_params: Optional[TaskFilter] = None, organization_ids: Optional[List[int]] = None):
|
16
|
+
self.http_client = http_client
|
17
|
+
self.filter_params = filter_params or TaskFilter()
|
18
|
+
self.organization_ids = ensure_organization_ids(organization_ids)
|
19
|
+
|
20
|
+
def execute(self) -> List[Task]:
|
21
|
+
"""Execute the query to list tasks."""
|
22
|
+
params = self.filter_params.to_params()
|
23
|
+
|
24
|
+
# Add organization IDs using utility function
|
25
|
+
org_params = format_organization_ids_param(self.organization_ids)
|
26
|
+
params.update(org_params)
|
27
|
+
|
28
|
+
# Ensure consistent sorting to match API defaults
|
29
|
+
if "sortBy" not in params:
|
30
|
+
params["sortBy"] = "createdAt"
|
31
|
+
if "sortType" not in params:
|
32
|
+
params["sortType"] = "ASC"
|
33
|
+
|
34
|
+
response = self.http_client.get("tasks", params=params)
|
35
|
+
|
36
|
+
entities = response.get("result", {}).get("entities", [])
|
37
|
+
|
38
|
+
# Use Pydantic parsing with proper field aliasing and error handling
|
39
|
+
tasks = []
|
40
|
+
for i, entity_data in enumerate(entities):
|
41
|
+
try:
|
42
|
+
# Validate data field structure before parsing
|
43
|
+
if "data" in entity_data and isinstance(entity_data["data"], list):
|
44
|
+
# Fix: API sometimes returns data as list instead of object
|
45
|
+
if len(entity_data["data"]) == 1:
|
46
|
+
entity_data["data"] = entity_data["data"][0]
|
47
|
+
elif len(entity_data["data"]) == 0:
|
48
|
+
entity_data["data"] = None
|
49
|
+
# If multiple items, keep as is and let validation handle it
|
50
|
+
|
51
|
+
task = Task.model_validate(entity_data)
|
52
|
+
tasks.append(task)
|
53
|
+
except Exception as e:
|
54
|
+
# Log validation error but continue processing other tasks
|
55
|
+
print(f"[WARN] Failed to parse task {i}: {e}")
|
56
|
+
print(f"[DEBUG] Task data structure: {type(entity_data.get('data', 'missing'))}")
|
57
|
+
# Create a minimal task object to avoid complete failure
|
58
|
+
try:
|
59
|
+
minimal_data = {
|
60
|
+
"_id": entity_data.get("_id", f"unknown-{i}"),
|
61
|
+
"name": entity_data.get("name", "Unknown Task"),
|
62
|
+
"type": entity_data.get("type", "unknown"),
|
63
|
+
"status": entity_data.get("status", "unknown"),
|
64
|
+
"createdBy": entity_data.get("createdBy", "unknown"),
|
65
|
+
"organizationId": entity_data.get("organizationId", 0),
|
66
|
+
# Skip the problematic data field
|
67
|
+
"data": None
|
68
|
+
}
|
69
|
+
task = Task.model_validate(minimal_data)
|
70
|
+
tasks.append(task)
|
71
|
+
except Exception as inner_e:
|
72
|
+
print(f"[ERROR] Could not create minimal task object: {inner_e}")
|
73
|
+
continue
|
74
|
+
|
75
|
+
return tasks
|
76
|
+
|
77
|
+
|
78
|
+
class GetTaskQuery(Query[Task]):
|
79
|
+
"""Query to get a specific task by ID."""
|
80
|
+
|
81
|
+
def __init__(self, http_client: HTTPClient, task_id: str):
|
82
|
+
self.http_client = http_client
|
83
|
+
self.task_id = task_id
|
84
|
+
|
85
|
+
def execute(self) -> Task:
|
86
|
+
"""Execute the query to get a task."""
|
87
|
+
response = self.http_client.get(f"tasks/{self.task_id}")
|
88
|
+
|
89
|
+
task_data = response.get("result", {})
|
90
|
+
|
91
|
+
# Validate and fix data field structure if needed
|
92
|
+
if "data" in task_data and isinstance(task_data["data"], list):
|
93
|
+
if len(task_data["data"]) == 1:
|
94
|
+
task_data["data"] = task_data["data"][0]
|
95
|
+
elif len(task_data["data"]) == 0:
|
96
|
+
task_data["data"] = None
|
97
|
+
|
98
|
+
# Use Pydantic parsing with proper field aliasing
|
99
|
+
return Task.model_validate(task_data)
|
100
|
+
|
101
|
+
|
102
|
+
class GetTaskAssignmentsQuery(Query[List[TaskAssignment]]):
|
103
|
+
"""Query to get task assignments for a specific task."""
|
104
|
+
|
105
|
+
def __init__(self, http_client: HTTPClient, task_id: str):
|
106
|
+
self.http_client = http_client
|
107
|
+
self.task_id = task_id
|
108
|
+
|
109
|
+
def execute(self) -> List[TaskAssignment]:
|
110
|
+
"""Execute the query to get task assignments."""
|
111
|
+
response = self.http_client.get(f"tasks/{self.task_id}/assignments")
|
112
|
+
|
113
|
+
entities = response.get("result", {}).get("entities", [])
|
114
|
+
|
115
|
+
# Use Pydantic parsing with proper field aliasing and error handling
|
116
|
+
assignments = []
|
117
|
+
for i, entity_data in enumerate(entities):
|
118
|
+
try:
|
119
|
+
assignment = TaskAssignment.model_validate(entity_data)
|
120
|
+
assignments.append(assignment)
|
121
|
+
except Exception as e:
|
122
|
+
print(f"[WARN] Failed to parse task assignment {i}: {e}")
|
123
|
+
# Continue processing other assignments
|
124
|
+
continue
|
125
|
+
|
82
126
|
return assignments
|