pangea-sdk 6.2.0b1__py3-none-any.whl → 6.2.0b2__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.
- pangea/__init__.py +9 -1
- pangea/asyncio/__init__.py +1 -0
- pangea/asyncio/file_uploader.py +4 -2
- pangea/asyncio/request.py +51 -21
- pangea/asyncio/services/__init__.py +2 -0
- pangea/asyncio/services/ai_guard.py +91 -2
- pangea/asyncio/services/audit.py +14 -8
- pangea/asyncio/services/authn.py +33 -23
- pangea/asyncio/services/authz.py +6 -6
- pangea/asyncio/services/base.py +4 -0
- pangea/asyncio/services/file_scan.py +8 -2
- pangea/asyncio/services/intel.py +6 -2
- pangea/asyncio/services/prompt_guard.py +112 -2
- pangea/asyncio/services/redact.py +7 -3
- pangea/asyncio/services/sanitize.py +5 -1
- pangea/asyncio/services/share.py +5 -1
- pangea/asyncio/services/vault.py +19 -15
- pangea/audit_logger.py +3 -1
- pangea/deep_verify.py +13 -13
- pangea/deprecated.py +1 -1
- pangea/dump_audit.py +2 -3
- pangea/exceptions.py +8 -5
- pangea/file_uploader.py +4 -0
- pangea/request.py +58 -41
- pangea/response.py +15 -12
- pangea/services/__init__.py +2 -0
- pangea/services/ai_guard.py +497 -16
- pangea/services/audit/audit.py +15 -13
- pangea/services/audit/models.py +4 -0
- pangea/services/audit/signing.py +1 -1
- pangea/services/audit/util.py +10 -10
- pangea/services/authn/authn.py +33 -23
- pangea/services/authn/models.py +3 -0
- pangea/services/authz.py +10 -6
- pangea/services/base.py +5 -1
- pangea/services/embargo.py +6 -0
- pangea/services/file_scan.py +8 -2
- pangea/services/intel.py +4 -0
- pangea/services/management.py +8 -8
- pangea/services/prompt_guard.py +193 -2
- pangea/services/redact.py +7 -3
- pangea/services/sanitize.py +5 -1
- pangea/services/share/share.py +13 -7
- pangea/services/vault/models/asymmetric.py +4 -0
- pangea/services/vault/models/common.py +4 -0
- pangea/services/vault/models/symmetric.py +4 -0
- pangea/services/vault/vault.py +17 -19
- pangea/tools.py +13 -9
- pangea/utils.py +3 -5
- pangea/verify_audit.py +23 -27
- {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/METADATA +6 -6
- pangea_sdk-6.2.0b2.dist-info/RECORD +62 -0
- {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/WHEEL +1 -1
- pangea_sdk-6.2.0b1.dist-info/RECORD +0 -62
pangea/__init__.py
CHANGED
@@ -1,7 +1,15 @@
|
|
1
|
-
__version__ = "6.2.
|
1
|
+
__version__ = "6.2.0beta2"
|
2
2
|
|
3
3
|
from pangea.asyncio.request import PangeaRequestAsync
|
4
4
|
from pangea.config import PangeaConfig
|
5
5
|
from pangea.file_uploader import FileUploader
|
6
6
|
from pangea.request import PangeaRequest
|
7
7
|
from pangea.response import PangeaResponse
|
8
|
+
|
9
|
+
__all__ = (
|
10
|
+
"FileUploader",
|
11
|
+
"PangeaConfig",
|
12
|
+
"PangeaRequest",
|
13
|
+
"PangeaRequestAsync",
|
14
|
+
"PangeaResponse",
|
15
|
+
)
|
pangea/asyncio/__init__.py
CHANGED
pangea/asyncio/file_uploader.py
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
from __future__ import annotations
|
5
|
+
|
3
6
|
import io
|
4
7
|
import logging
|
5
|
-
from typing import Dict, Optional
|
6
8
|
|
7
9
|
from pangea.asyncio.request import PangeaRequestAsync
|
8
10
|
from pangea.request import PangeaConfig
|
@@ -24,7 +26,7 @@ class FileUploaderAsync:
|
|
24
26
|
url: str,
|
25
27
|
file: io.BufferedReader,
|
26
28
|
transfer_method: TransferMethod = TransferMethod.PUT_URL,
|
27
|
-
file_details:
|
29
|
+
file_details: dict | None = None,
|
28
30
|
) -> None:
|
29
31
|
if transfer_method == TransferMethod.PUT_URL:
|
30
32
|
files = [("file", ("filename", file, "application/octet-stream"))]
|
pangea/asyncio/request.py
CHANGED
@@ -1,24 +1,39 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Modernize.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import asyncio
|
6
10
|
import json
|
7
11
|
import time
|
8
12
|
from collections.abc import Iterable, Mapping
|
9
|
-
from typing import Dict, List,
|
13
|
+
from typing import Dict, List, Optional, Sequence, Tuple, Type, Union, cast, overload
|
10
14
|
|
11
15
|
import aiohttp
|
12
16
|
from aiohttp import FormData
|
13
17
|
from pydantic import BaseModel, TypeAdapter
|
14
18
|
from pydantic_core import to_jsonable_python
|
15
|
-
from typing_extensions import Any, TypeVar
|
19
|
+
from typing_extensions import Any, Literal, TypeAlias, TypeVar, override
|
16
20
|
|
17
21
|
import pangea.exceptions as pe
|
18
22
|
from pangea.request import MultipartResponse, PangeaRequestBase
|
19
23
|
from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
|
20
24
|
from pangea.utils import default_encoder
|
21
25
|
|
26
|
+
_FileName: TypeAlias = Union[str, None]
|
27
|
+
_FileContent: TypeAlias = Union[str, bytes]
|
28
|
+
_FileContentType: TypeAlias = str
|
29
|
+
_FileCustomHeaders: TypeAlias = Mapping[str, str]
|
30
|
+
_FileSpecTuple2: TypeAlias = tuple[_FileName, _FileContent]
|
31
|
+
_FileSpecTuple3: TypeAlias = tuple[_FileName, _FileContent, _FileContentType]
|
32
|
+
_FileSpecTuple4: TypeAlias = tuple[_FileName, _FileContent, _FileContentType, _FileCustomHeaders]
|
33
|
+
_FileSpec: TypeAlias = Union[_FileContent, _FileSpecTuple2, _FileSpecTuple3, _FileSpecTuple4]
|
34
|
+
_Files: TypeAlias = Union[Mapping[str, _FileSpec], Iterable[tuple[str, _FileSpec]]]
|
35
|
+
|
36
|
+
|
22
37
|
TResult = TypeVar("TResult", bound=PangeaResponseResult)
|
23
38
|
|
24
39
|
|
@@ -53,7 +68,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
53
68
|
self,
|
54
69
|
endpoint: str,
|
55
70
|
result_class: Type[TResult],
|
56
|
-
data: str | BaseModel |
|
71
|
+
data: str | BaseModel | Mapping[str, Any] | None = None,
|
57
72
|
files: Optional[List[Tuple]] = None,
|
58
73
|
poll_result: bool = True,
|
59
74
|
url: Optional[str] = None,
|
@@ -77,7 +92,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
77
92
|
self,
|
78
93
|
endpoint: str,
|
79
94
|
result_class: Type[TResult],
|
80
|
-
data: str | BaseModel |
|
95
|
+
data: str | BaseModel | Mapping[str, Any] | None = None,
|
81
96
|
files: Optional[List[Tuple]] = None,
|
82
97
|
poll_result: bool = True,
|
83
98
|
url: Optional[str] = None,
|
@@ -96,7 +111,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
96
111
|
self,
|
97
112
|
endpoint: str,
|
98
113
|
result_class: Type[TResult],
|
99
|
-
data: str | BaseModel |
|
114
|
+
data: str | BaseModel | Mapping[str, Any] | None = None,
|
100
115
|
files: Optional[List[Tuple]] = None,
|
101
116
|
poll_result: bool = True,
|
102
117
|
url: Optional[str] = None,
|
@@ -122,7 +137,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
122
137
|
data = {}
|
123
138
|
|
124
139
|
# Normalize.
|
125
|
-
data = cast(dict[str, Any], to_jsonable_python(data))
|
140
|
+
data = cast(dict[str, Any], to_jsonable_python(data, exclude_none=True))
|
126
141
|
|
127
142
|
if url is None:
|
128
143
|
url = self._url(endpoint)
|
@@ -141,8 +156,11 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
141
156
|
endpoint, result_class=result_class, data=data, files=files
|
142
157
|
)
|
143
158
|
else:
|
159
|
+
headers = self._headers()
|
160
|
+
if transfer_method == TransferMethod.MULTIPART.value:
|
161
|
+
del headers["Content-Type"]
|
144
162
|
requests_response = await self._http_post(
|
145
|
-
url, headers=
|
163
|
+
url, headers=headers, data=data, files=files, presigned_url_post=False
|
146
164
|
)
|
147
165
|
|
148
166
|
await self._check_http_errors(requests_response)
|
@@ -168,7 +186,9 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
168
186
|
|
169
187
|
pangea_response_obj = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
|
170
188
|
except aiohttp.ContentTypeError as e:
|
171
|
-
raise pe.PangeaException(
|
189
|
+
raise pe.PangeaException(
|
190
|
+
f"Failed to decode json response. {e}. Body: {await requests_response.text()}"
|
191
|
+
) from e
|
172
192
|
|
173
193
|
if poll_result:
|
174
194
|
pangea_response_obj = await self._handle_queued_result(pangea_response_obj)
|
@@ -290,7 +310,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
290
310
|
|
291
311
|
return await self.poll_result_by_id(request_id, response.result_class, check_response=check_response)
|
292
312
|
|
293
|
-
async def post_presigned_url(self, url: str, data:
|
313
|
+
async def post_presigned_url(self, url: str, data: dict[Any, Any], files: Sequence[Tuple]):
|
294
314
|
# Send form request with file and upload_details as body
|
295
315
|
resp = await self._http_post(url=url, data=data, files=files, presigned_url_post=True)
|
296
316
|
self.logger.debug(
|
@@ -412,35 +432,44 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
412
432
|
async def _http_post(
|
413
433
|
self,
|
414
434
|
url: str,
|
415
|
-
headers: Mapping[str, str
|
416
|
-
data:
|
417
|
-
files:
|
435
|
+
headers: Mapping[str, str] = {},
|
436
|
+
data: str | dict[str, Any] | None = None,
|
437
|
+
files: _Files | None = None,
|
418
438
|
presigned_url_post: bool = False,
|
419
439
|
) -> aiohttp.ClientResponse:
|
440
|
+
if data is None:
|
441
|
+
data = {}
|
442
|
+
|
420
443
|
if files:
|
421
444
|
form = FormData()
|
422
445
|
if presigned_url_post:
|
423
|
-
|
446
|
+
assert isinstance(data, dict)
|
447
|
+
assert isinstance(files, list)
|
448
|
+
for k, v in data.items():
|
424
449
|
form.add_field(k, v)
|
425
|
-
for
|
450
|
+
for _name, value in files:
|
426
451
|
form.add_field("file", value[1], filename=value[0], content_type=value[2])
|
427
452
|
else:
|
428
|
-
|
453
|
+
assert isinstance(files, list)
|
454
|
+
data_send: str | FormData = (
|
455
|
+
json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
|
456
|
+
)
|
429
457
|
form.add_field("request", data_send, content_type="application/json")
|
430
458
|
for name, value in files:
|
431
459
|
form.add_field(name, value[1], filename=value[0], content_type=value[2])
|
432
460
|
|
433
|
-
data_send = form
|
461
|
+
data_send = form
|
434
462
|
else:
|
435
463
|
data_send = json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
|
436
464
|
|
465
|
+
assert isinstance(self.session, aiohttp.ClientSession)
|
437
466
|
return await self.session.post(url, headers=headers, data=data_send)
|
438
467
|
|
439
468
|
async def _http_put(
|
440
469
|
self,
|
441
470
|
url: str,
|
442
471
|
files: Sequence[Tuple],
|
443
|
-
headers:
|
472
|
+
headers: Mapping[str, str] = {},
|
444
473
|
) -> aiohttp.ClientResponse:
|
445
474
|
self.logger.debug(
|
446
475
|
json.dumps({"service": self.service, "action": "http_put", "url": url}, default=default_encoder)
|
@@ -452,8 +481,8 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
452
481
|
self,
|
453
482
|
endpoint: str,
|
454
483
|
result_class: Type[PangeaResponseResult],
|
455
|
-
data: Union[str,
|
456
|
-
files:
|
484
|
+
data: Union[str, Mapping[str, Any]] = {},
|
485
|
+
files: Sequence[Tuple] = [],
|
457
486
|
):
|
458
487
|
if len(files) == 0:
|
459
488
|
raise AttributeError("files attribute should have at least 1 file")
|
@@ -477,7 +506,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
477
506
|
self,
|
478
507
|
endpoint: str,
|
479
508
|
result_class: Type[PangeaResponseResult],
|
480
|
-
data: Union[str,
|
509
|
+
data: Union[str, Mapping[str, Any]] = {},
|
481
510
|
) -> PangeaResponse:
|
482
511
|
# Send request
|
483
512
|
try:
|
@@ -528,7 +557,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
528
557
|
{"service": self.service, "action": "poll_presigned_url", "step": "exit", "cause": {str(e)}}
|
529
558
|
)
|
530
559
|
)
|
531
|
-
raise pe.PresignedURLException("Failed to pull Presigned URL", loop_exc.response, e)
|
560
|
+
raise pe.PresignedURLException("Failed to pull Presigned URL", loop_exc.response, e) from e
|
532
561
|
|
533
562
|
self.logger.debug(json.dumps({"service": self.service, "action": "poll_presigned_url", "step": "exit"}))
|
534
563
|
|
@@ -560,6 +589,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
560
589
|
self.logger.debug(json.dumps({"service": self.service, "action": "poll_result_retry", "step": "exit"}))
|
561
590
|
return self._check_response(response)
|
562
591
|
|
592
|
+
@override
|
563
593
|
def _init_session(self) -> aiohttp.ClientSession:
|
564
594
|
# retry_config = Retry(
|
565
595
|
# total=self.config.request_retries,
|
@@ -1,13 +1,24 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
from collections.abc import Mapping
|
3
4
|
from typing import overload
|
4
5
|
|
5
|
-
from typing_extensions import TypeVar
|
6
|
+
from typing_extensions import Literal, TypeVar
|
6
7
|
|
7
8
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
8
9
|
from pangea.config import PangeaConfig
|
9
10
|
from pangea.response import PangeaResponse
|
10
|
-
from pangea.services.ai_guard import
|
11
|
+
from pangea.services.ai_guard import (
|
12
|
+
AuditDataActivityConfig,
|
13
|
+
ConnectionsConfig,
|
14
|
+
LogFields,
|
15
|
+
Overrides,
|
16
|
+
RecipeConfig,
|
17
|
+
ServiceConfig,
|
18
|
+
ServiceConfigFilter,
|
19
|
+
ServiceConfigsPage,
|
20
|
+
TextGuardResult,
|
21
|
+
)
|
11
22
|
|
12
23
|
_T = TypeVar("_T")
|
13
24
|
|
@@ -170,3 +181,81 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
170
181
|
"log_fields": log_fields,
|
171
182
|
},
|
172
183
|
)
|
184
|
+
|
185
|
+
async def get_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
|
186
|
+
"""
|
187
|
+
OperationId: ai_guard_post_v1beta_config
|
188
|
+
"""
|
189
|
+
return await self.request.post("v1beta/config", data={"id": id}, result_class=ServiceConfig)
|
190
|
+
|
191
|
+
async def create_service_config(
|
192
|
+
self,
|
193
|
+
name: str,
|
194
|
+
*,
|
195
|
+
id: str | None = None,
|
196
|
+
audit_data_activity: AuditDataActivityConfig | None = None,
|
197
|
+
connections: ConnectionsConfig | None = None,
|
198
|
+
recipes: Mapping[str, RecipeConfig] | None = None,
|
199
|
+
) -> PangeaResponse[ServiceConfig]:
|
200
|
+
"""
|
201
|
+
OperationId: ai_guard_post_v1beta_config_create
|
202
|
+
"""
|
203
|
+
return await self.request.post(
|
204
|
+
"v1beta/config/create",
|
205
|
+
data={
|
206
|
+
"name": name,
|
207
|
+
"id": id,
|
208
|
+
"audit_data_activity": audit_data_activity,
|
209
|
+
"connections": connections,
|
210
|
+
"recipes": recipes,
|
211
|
+
},
|
212
|
+
result_class=ServiceConfig,
|
213
|
+
)
|
214
|
+
|
215
|
+
async def update_service_config(
|
216
|
+
self,
|
217
|
+
id: str,
|
218
|
+
name: str,
|
219
|
+
*,
|
220
|
+
audit_data_activity: AuditDataActivityConfig | None = None,
|
221
|
+
connections: ConnectionsConfig | None = None,
|
222
|
+
recipes: Mapping[str, RecipeConfig] | None = None,
|
223
|
+
) -> PangeaResponse[ServiceConfig]:
|
224
|
+
"""
|
225
|
+
OperationId: ai_guard_post_v1beta_config_update
|
226
|
+
"""
|
227
|
+
return await self.request.post(
|
228
|
+
"v1beta/config/update",
|
229
|
+
data={
|
230
|
+
"id": id,
|
231
|
+
"name": name,
|
232
|
+
"audit_data_activity": audit_data_activity,
|
233
|
+
"connections": connections,
|
234
|
+
"recipes": recipes,
|
235
|
+
},
|
236
|
+
result_class=ServiceConfig,
|
237
|
+
)
|
238
|
+
|
239
|
+
async def delete_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
|
240
|
+
"""
|
241
|
+
OperationId: ai_guard_post_v1beta_config_delete
|
242
|
+
"""
|
243
|
+
return await self.request.post("v1beta/config/delete", data={"id": id}, result_class=ServiceConfig)
|
244
|
+
|
245
|
+
async def list_service_configs(
|
246
|
+
self,
|
247
|
+
*,
|
248
|
+
filter: ServiceConfigFilter | None = None,
|
249
|
+
last: str | None = None,
|
250
|
+
order: Literal["asc", "desc"] | None = None,
|
251
|
+
order_by: Literal["id", "created_at", "updated_at"] | None = None,
|
252
|
+
size: int | None = None,
|
253
|
+
) -> PangeaResponse[ServiceConfigsPage]:
|
254
|
+
"""
|
255
|
+
OperationId: ai_guard_post_v1beta_config_list
|
256
|
+
"""
|
257
|
+
return await self.request.post(
|
258
|
+
"v1beta/config/list",
|
259
|
+
data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
|
260
|
+
result_class=ServiceConfigsPage,
|
261
|
+
)
|
pangea/asyncio/services/audit.py
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Modernize.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import datetime
|
6
|
-
from
|
10
|
+
from collections.abc import Mapping
|
11
|
+
from typing import Any, Dict, Iterable, List, Optional, Sequence, Union, cast, overload
|
7
12
|
|
8
13
|
from pydantic import TypeAdapter
|
14
|
+
from typing_extensions import Literal
|
9
15
|
|
10
16
|
import pangea.exceptions as pexc
|
11
17
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
@@ -70,7 +76,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
70
76
|
token: str,
|
71
77
|
config: PangeaConfig | None = None,
|
72
78
|
private_key_file: str = "",
|
73
|
-
public_key_info:
|
79
|
+
public_key_info: Mapping[str, str] = {},
|
74
80
|
tenant_id: str | None = None,
|
75
81
|
logger_name: str = "pangea",
|
76
82
|
config_id: str | None = None,
|
@@ -142,7 +148,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
142
148
|
A PangeaResponse where the hash of event data and optional verbose
|
143
149
|
results are returned in the response.result field.
|
144
150
|
Available response fields can be found in our
|
145
|
-
[API documentation](https://pangea.cloud/docs/api/audit
|
151
|
+
[API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
|
146
152
|
|
147
153
|
Examples:
|
148
154
|
try:
|
@@ -193,7 +199,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
193
199
|
Returns:
|
194
200
|
A PangeaResponse where the hash of event data and optional verbose
|
195
201
|
results are returned in the response.result field.
|
196
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit
|
202
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
|
197
203
|
|
198
204
|
Examples:
|
199
205
|
response = await audit.log_event({"message": "hello world"}, verbose=True)
|
@@ -229,7 +235,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
229
235
|
Returns:
|
230
236
|
A PangeaResponse where the hash of event data and optional verbose
|
231
237
|
results are returned in the response.result field.
|
232
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit
|
238
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
|
233
239
|
|
234
240
|
Examples:
|
235
241
|
FIXME:
|
@@ -266,7 +272,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
266
272
|
Returns:
|
267
273
|
A PangeaResponse where the hash of event data and optional verbose
|
268
274
|
results are returned in the response.result field.
|
269
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit
|
275
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
|
270
276
|
|
271
277
|
Examples:
|
272
278
|
FIXME:
|
@@ -335,8 +341,8 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
335
341
|
|
336
342
|
Returns:
|
337
343
|
A PangeaResponse[SearchOutput] where the first page of matched events is returned in the
|
338
|
-
response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit
|
339
|
-
Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit
|
344
|
+
response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/results-post).
|
345
|
+
Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit#/v1/download_results-post).
|
340
346
|
|
341
347
|
Examples:
|
342
348
|
response: PangeaResponse[SearchOutput] = audit.search(query="message:test", search_restriction={'source': ["monitor"]}, limit=1, verify_consistency=True, verify_events=True)
|
pangea/asyncio/services/authn.py
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Modernize.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
from typing import Dict, List, Literal, Optional, Union
|
@@ -127,7 +131,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
127
131
|
Returns:
|
128
132
|
A PangeaResponse with a list of sessions in the response.result field.
|
129
133
|
Available response fields can be found in our
|
130
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list).
|
134
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list-post).
|
131
135
|
|
132
136
|
Examples:
|
133
137
|
response = authn.session.list()
|
@@ -192,7 +196,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
192
196
|
Returns:
|
193
197
|
A PangeaResponse with credentials for a login session in the response.result field.
|
194
198
|
Available response fields can be found in our
|
195
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo).
|
199
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo-post).
|
196
200
|
|
197
201
|
Examples:
|
198
202
|
response = authn.client.userinfo(
|
@@ -217,7 +221,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
217
221
|
Returns:
|
218
222
|
A PangeaResponse with jwt verification keys in the response.result field.
|
219
223
|
Available response fields can be found in our
|
220
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks).
|
224
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks-post).
|
221
225
|
|
222
226
|
Examples:
|
223
227
|
response = authn.client.jwks()
|
@@ -290,7 +294,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
290
294
|
Returns:
|
291
295
|
A PangeaResponse with a list of sessions in the response.result field.
|
292
296
|
Available response fields can be found in our
|
293
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list).
|
297
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list-post).
|
294
298
|
|
295
299
|
Examples:
|
296
300
|
response = authn.client.session.list(
|
@@ -348,7 +352,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
348
352
|
Returns:
|
349
353
|
A PangeaResponse with credentials for a login session in the response.result field.
|
350
354
|
Available response fields can be found in our
|
351
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh).
|
355
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh-post).
|
352
356
|
|
353
357
|
Examples:
|
354
358
|
response = authn.client.session.refresh(
|
@@ -446,7 +450,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
446
450
|
Returns:
|
447
451
|
A PangeaResponse with a token and its information in the response.result field.
|
448
452
|
Available response fields can be found in our
|
449
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check).
|
453
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check-post).
|
450
454
|
|
451
455
|
Examples:
|
452
456
|
response = authn.client.token_endpoints.check(
|
@@ -494,7 +498,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
494
498
|
Returns:
|
495
499
|
A PangeaResponse with a user and its information in the response.result field.
|
496
500
|
Available response fields can be found in our
|
497
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create).
|
501
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create-post).
|
498
502
|
|
499
503
|
Examples:
|
500
504
|
response = authn.user.create(
|
@@ -563,7 +567,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
563
567
|
Returns:
|
564
568
|
A PangeaResponse with a pending user invitation in the response.result field.
|
565
569
|
Available response fields can be found in our
|
566
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite).
|
570
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite-post).
|
567
571
|
|
568
572
|
Examples:
|
569
573
|
response = authn.user.invite(
|
@@ -608,7 +612,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
608
612
|
Returns:
|
609
613
|
A PangeaResponse with a user and its information in the response.result field.
|
610
614
|
Available response fields can be found in our
|
611
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update).
|
615
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update-post).
|
612
616
|
|
613
617
|
Examples:
|
614
618
|
response = authn.user.update(
|
@@ -652,7 +656,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
652
656
|
Returns:
|
653
657
|
A PangeaResponse with a list of users in the response.result field.
|
654
658
|
Available response fields can be found in our
|
655
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list).
|
659
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list-post).
|
656
660
|
|
657
661
|
Examples:
|
658
662
|
response = authn.user.list()
|
@@ -705,7 +709,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
705
709
|
Returns:
|
706
710
|
A PangeaResponse with a list of pending user invitations in the response.result field.
|
707
711
|
Available response fields can be found in our
|
708
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list).
|
712
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list-post).
|
709
713
|
Examples:
|
710
714
|
response = authn.user.invites.list()
|
711
715
|
"""
|
@@ -809,7 +813,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
809
813
|
Returns:
|
810
814
|
A PangeaResponse with a list of authenticators in the response.result field.
|
811
815
|
Available response fields can be found in our
|
812
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list).
|
816
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list-post).
|
813
817
|
|
814
818
|
Examples:
|
815
819
|
response = authn.user.authenticators.list(
|
@@ -852,7 +856,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
852
856
|
Returns:
|
853
857
|
A PangeaResponse with a user and its information in the response.result field.
|
854
858
|
Available response fields can be found in our
|
855
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get).
|
859
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get-post).
|
856
860
|
|
857
861
|
Examples:
|
858
862
|
response = authn.user.profile.get(
|
@@ -888,7 +892,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
888
892
|
Returns:
|
889
893
|
A PangeaResponse with a user and its information in the response.result field.
|
890
894
|
Available response fields can be found in our
|
891
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update).
|
895
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update-post).
|
892
896
|
|
893
897
|
Examples:
|
894
898
|
response = authn.user.profile.update(
|
@@ -982,7 +986,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
982
986
|
Returns:
|
983
987
|
A PangeaResponse with credentials for a login session in the response.result field.
|
984
988
|
Available response fields can be found in our
|
985
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete).
|
989
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete-post).
|
986
990
|
|
987
991
|
Examples:
|
988
992
|
response = authn.flow.complete(
|
@@ -995,7 +999,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
995
999
|
)
|
996
1000
|
|
997
1001
|
async def restart(
|
998
|
-
self,
|
1002
|
+
self,
|
1003
|
+
flow_id: str,
|
1004
|
+
choice: m.FlowChoice,
|
1005
|
+
data: m.FlowRestartData = {}, # noqa: B006
|
999
1006
|
) -> PangeaResponse[m.FlowRestartResult]:
|
1000
1007
|
"""
|
1001
1008
|
Restart a sign-up/sign-in flow
|
@@ -1013,7 +1020,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1013
1020
|
A PangeaResponse with information about next steps needed
|
1014
1021
|
to complete a flow in the response.result field.
|
1015
1022
|
Available response fields can be found in our
|
1016
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart).
|
1023
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart-post).
|
1017
1024
|
|
1018
1025
|
Examples:
|
1019
1026
|
response = authn.flow.restart(
|
@@ -1052,7 +1059,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1052
1059
|
A PangeaResponse with information about next steps needed
|
1053
1060
|
to complete a flow in the response.result field.
|
1054
1061
|
Available response fields can be found in our
|
1055
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start).
|
1062
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start-post).
|
1056
1063
|
|
1057
1064
|
Examples:
|
1058
1065
|
response = authn.flow.start(
|
@@ -1068,7 +1075,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1068
1075
|
return await self.request.post("v2/flow/start", m.FlowStartResult, data=input.model_dump(exclude_none=True))
|
1069
1076
|
|
1070
1077
|
async def update(
|
1071
|
-
self,
|
1078
|
+
self,
|
1079
|
+
flow_id: str,
|
1080
|
+
choice: m.FlowChoice,
|
1081
|
+
data: m.FlowUpdateData = {}, # noqa: B006
|
1072
1082
|
) -> PangeaResponse[m.FlowUpdateResult]:
|
1073
1083
|
"""
|
1074
1084
|
Update a sign-up/sign-in flow
|
@@ -1086,7 +1096,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1086
1096
|
A PangeaResponse with information about next steps needed
|
1087
1097
|
to complete a flow in the response.result field.
|
1088
1098
|
Available response fields can be found in our
|
1089
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update).
|
1099
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update-post).
|
1090
1100
|
|
1091
1101
|
Examples:
|
1092
1102
|
response = authn.flow.update(
|
@@ -1133,7 +1143,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1133
1143
|
Returns:
|
1134
1144
|
A PangeaResponse with a EULA object in the response.result field.
|
1135
1145
|
Available response fields can be found in our
|
1136
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create).
|
1146
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create-post).
|
1137
1147
|
|
1138
1148
|
Examples:
|
1139
1149
|
response = authn.agreements.create(
|
@@ -1200,7 +1210,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1200
1210
|
Returns:
|
1201
1211
|
A PangeaResponse with a list of EULA objects in the response.result field.
|
1202
1212
|
Available response fields can be found in our
|
1203
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list).
|
1213
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list-post).
|
1204
1214
|
|
1205
1215
|
Examples:
|
1206
1216
|
response = authn.agreements.list()
|
@@ -1238,7 +1248,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1238
1248
|
Returns:
|
1239
1249
|
A PangeaResponse with the updated EULA object in the response.result field.
|
1240
1250
|
Available response fields can be found in our
|
1241
|
-
[API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update).
|
1251
|
+
[API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update-post).
|
1242
1252
|
|
1243
1253
|
Examples:
|
1244
1254
|
response = authn.agreements.update(
|