binalyze-air-sdk 1.0.1__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.
Files changed (142) hide show
  1. binalyze_air/__init__.py +77 -77
  2. binalyze_air/apis/__init__.py +67 -27
  3. binalyze_air/apis/acquisitions.py +107 -0
  4. binalyze_air/apis/api_tokens.py +49 -0
  5. binalyze_air/apis/assets.py +161 -0
  6. binalyze_air/apis/audit_logs.py +26 -0
  7. binalyze_air/apis/{authentication.py → auth.py} +29 -27
  8. binalyze_air/apis/auto_asset_tags.py +79 -75
  9. binalyze_air/apis/backup.py +177 -0
  10. binalyze_air/apis/baseline.py +46 -0
  11. binalyze_air/apis/cases.py +225 -0
  12. binalyze_air/apis/cloud_forensics.py +116 -0
  13. binalyze_air/apis/event_subscription.py +96 -96
  14. binalyze_air/apis/evidence.py +249 -53
  15. binalyze_air/apis/interact.py +153 -36
  16. binalyze_air/apis/investigation_hub.py +234 -0
  17. binalyze_air/apis/license.py +104 -0
  18. binalyze_air/apis/logger.py +83 -0
  19. binalyze_air/apis/multipart_upload.py +201 -0
  20. binalyze_air/apis/notifications.py +115 -0
  21. binalyze_air/apis/organizations.py +267 -0
  22. binalyze_air/apis/params.py +44 -39
  23. binalyze_air/apis/policies.py +186 -0
  24. binalyze_air/apis/preset_filters.py +79 -0
  25. binalyze_air/apis/recent_activities.py +71 -0
  26. binalyze_air/apis/relay_server.py +104 -0
  27. binalyze_air/apis/settings.py +395 -27
  28. binalyze_air/apis/tasks.py +80 -0
  29. binalyze_air/apis/triage.py +197 -0
  30. binalyze_air/apis/user_management.py +183 -74
  31. binalyze_air/apis/webhook_executions.py +50 -0
  32. binalyze_air/apis/webhooks.py +322 -230
  33. binalyze_air/base.py +207 -133
  34. binalyze_air/client.py +217 -1337
  35. binalyze_air/commands/__init__.py +175 -145
  36. binalyze_air/commands/acquisitions.py +661 -387
  37. binalyze_air/commands/api_tokens.py +55 -0
  38. binalyze_air/commands/assets.py +324 -362
  39. binalyze_air/commands/{authentication.py → auth.py} +36 -36
  40. binalyze_air/commands/auto_asset_tags.py +230 -230
  41. binalyze_air/commands/backup.py +47 -0
  42. binalyze_air/commands/baseline.py +32 -396
  43. binalyze_air/commands/cases.py +609 -602
  44. binalyze_air/commands/cloud_forensics.py +88 -0
  45. binalyze_air/commands/event_subscription.py +101 -101
  46. binalyze_air/commands/evidences.py +918 -988
  47. binalyze_air/commands/interact.py +172 -58
  48. binalyze_air/commands/investigation_hub.py +315 -0
  49. binalyze_air/commands/license.py +183 -0
  50. binalyze_air/commands/logger.py +126 -0
  51. binalyze_air/commands/multipart_upload.py +363 -0
  52. binalyze_air/commands/notifications.py +45 -0
  53. binalyze_air/commands/organizations.py +200 -221
  54. binalyze_air/commands/policies.py +175 -203
  55. binalyze_air/commands/preset_filters.py +55 -0
  56. binalyze_air/commands/recent_activities.py +32 -0
  57. binalyze_air/commands/relay_server.py +144 -0
  58. binalyze_air/commands/settings.py +431 -29
  59. binalyze_air/commands/tasks.py +95 -56
  60. binalyze_air/commands/triage.py +224 -360
  61. binalyze_air/commands/user_management.py +351 -126
  62. binalyze_air/commands/webhook_executions.py +77 -0
  63. binalyze_air/config.py +244 -244
  64. binalyze_air/exceptions.py +49 -49
  65. binalyze_air/http_client.py +426 -305
  66. binalyze_air/models/__init__.py +287 -285
  67. binalyze_air/models/acquisitions.py +365 -250
  68. binalyze_air/models/api_tokens.py +73 -0
  69. binalyze_air/models/assets.py +438 -438
  70. binalyze_air/models/audit.py +247 -272
  71. binalyze_air/models/audit_logs.py +14 -0
  72. binalyze_air/models/{authentication.py → auth.py} +69 -69
  73. binalyze_air/models/auto_asset_tags.py +227 -116
  74. binalyze_air/models/backup.py +138 -0
  75. binalyze_air/models/baseline.py +231 -231
  76. binalyze_air/models/cases.py +275 -275
  77. binalyze_air/models/cloud_forensics.py +145 -0
  78. binalyze_air/models/event_subscription.py +170 -171
  79. binalyze_air/models/evidence.py +65 -65
  80. binalyze_air/models/evidences.py +367 -348
  81. binalyze_air/models/interact.py +266 -135
  82. binalyze_air/models/investigation_hub.py +265 -0
  83. binalyze_air/models/license.py +150 -0
  84. binalyze_air/models/logger.py +83 -0
  85. binalyze_air/models/multipart_upload.py +352 -0
  86. binalyze_air/models/notifications.py +138 -0
  87. binalyze_air/models/organizations.py +293 -293
  88. binalyze_air/models/params.py +153 -127
  89. binalyze_air/models/policies.py +260 -249
  90. binalyze_air/models/preset_filters.py +79 -0
  91. binalyze_air/models/recent_activities.py +70 -0
  92. binalyze_air/models/relay_server.py +121 -0
  93. binalyze_air/models/settings.py +538 -84
  94. binalyze_air/models/tasks.py +215 -149
  95. binalyze_air/models/triage.py +141 -142
  96. binalyze_air/models/user_management.py +200 -97
  97. binalyze_air/models/webhook_executions.py +33 -0
  98. binalyze_air/queries/__init__.py +121 -133
  99. binalyze_air/queries/acquisitions.py +155 -155
  100. binalyze_air/queries/api_tokens.py +46 -0
  101. binalyze_air/queries/assets.py +186 -105
  102. binalyze_air/queries/audit.py +400 -416
  103. binalyze_air/queries/{authentication.py → auth.py} +55 -55
  104. binalyze_air/queries/auto_asset_tags.py +59 -59
  105. binalyze_air/queries/backup.py +66 -0
  106. binalyze_air/queries/baseline.py +21 -185
  107. binalyze_air/queries/cases.py +292 -292
  108. binalyze_air/queries/cloud_forensics.py +137 -0
  109. binalyze_air/queries/event_subscription.py +54 -54
  110. binalyze_air/queries/evidence.py +139 -139
  111. binalyze_air/queries/evidences.py +279 -279
  112. binalyze_air/queries/interact.py +140 -28
  113. binalyze_air/queries/investigation_hub.py +329 -0
  114. binalyze_air/queries/license.py +85 -0
  115. binalyze_air/queries/logger.py +58 -0
  116. binalyze_air/queries/multipart_upload.py +180 -0
  117. binalyze_air/queries/notifications.py +71 -0
  118. binalyze_air/queries/organizations.py +222 -222
  119. binalyze_air/queries/params.py +154 -115
  120. binalyze_air/queries/policies.py +149 -149
  121. binalyze_air/queries/preset_filters.py +60 -0
  122. binalyze_air/queries/recent_activities.py +44 -0
  123. binalyze_air/queries/relay_server.py +42 -0
  124. binalyze_air/queries/settings.py +533 -20
  125. binalyze_air/queries/tasks.py +125 -81
  126. binalyze_air/queries/triage.py +230 -230
  127. binalyze_air/queries/user_management.py +193 -83
  128. binalyze_air/queries/webhook_executions.py +39 -0
  129. binalyze_air_sdk-1.0.3.dist-info/METADATA +752 -0
  130. binalyze_air_sdk-1.0.3.dist-info/RECORD +132 -0
  131. {binalyze_air_sdk-1.0.1.dist-info → binalyze_air_sdk-1.0.3.dist-info}/WHEEL +1 -1
  132. binalyze_air/apis/endpoints.py +0 -22
  133. binalyze_air/apis/evidences.py +0 -216
  134. binalyze_air/apis/users.py +0 -68
  135. binalyze_air/commands/users.py +0 -101
  136. binalyze_air/models/endpoints.py +0 -76
  137. binalyze_air/models/users.py +0 -82
  138. binalyze_air/queries/endpoints.py +0 -25
  139. binalyze_air/queries/users.py +0 -69
  140. binalyze_air_sdk-1.0.1.dist-info/METADATA +0 -635
  141. binalyze_air_sdk-1.0.1.dist-info/RECORD +0 -82
  142. {binalyze_air_sdk-1.0.1.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
- from ..queries.user_management import (
13
- ListUsersQuery, GetUserQuery, GetAIUserQuery, GetAPIUserQuery
14
- )
15
- from ..commands.user_management import (
16
- CreateUserCommand, UpdateUserCommand, DeleteUserCommand,
17
- CreateAIUserCommand, CreateAPIUserCommand
18
- )
19
-
20
-
21
- class UserManagementAPI:
22
- """User Management API with CQRS pattern - separated queries and commands."""
23
-
24
- def __init__(self, http_client: HTTPClient):
25
- self.http_client = http_client
26
-
27
- # USER QUERIES (Read operations)
28
- def list_users(self, filter_params: Optional[UserFilter] = None) -> List[UserManagementUser]:
29
- """List users with optional filtering."""
30
- query = ListUsersQuery(self.http_client, filter_params)
31
- return query.execute()
32
-
33
- def get_user(self, user_id: str) -> UserManagementUser:
34
- """Get a specific user by ID."""
35
- query = GetUserQuery(self.http_client, user_id)
36
- return query.execute()
37
-
38
- # USER COMMANDS (Write operations)
39
- def create_user(self, request: CreateUserRequest) -> UserManagementUser:
40
- """Create a new user."""
41
- command = CreateUserCommand(self.http_client, request)
42
- return command.execute()
43
-
44
- def update_user(self, user_id: str, request: UpdateUserRequest) -> UserManagementUser:
45
- """Update an existing user."""
46
- command = UpdateUserCommand(self.http_client, user_id, request)
47
- return command.execute()
48
-
49
- def delete_user(self, user_id: str) -> Dict[str, Any]:
50
- """Delete a user."""
51
- command = DeleteUserCommand(self.http_client, user_id)
52
- return command.execute()
53
-
54
- # AI USER OPERATIONS
55
- def get_ai_user(self) -> AIUser:
56
- """Get the AI user."""
57
- query = GetAIUserQuery(self.http_client)
58
- return query.execute()
59
-
60
- def create_ai_user(self, request: CreateAIUserRequest) -> AIUser:
61
- """Create a new AI user."""
62
- command = CreateAIUserCommand(self.http_client, request)
63
- return command.execute()
64
-
65
- # API USER OPERATIONS
66
- def get_api_user(self) -> APIUser:
67
- """Get the API user."""
68
- query = GetAPIUserQuery(self.http_client)
69
- return query.execute()
70
-
71
- def create_api_user(self, request: CreateAPIUserRequest) -> APIUser:
72
- """Create a new API user."""
73
- command = CreateAPIUserCommand(self.http_client, request)
74
- return command.execute()
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)