pangea-sdk 3.8.0__py3-none-any.whl → 3.8.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 +2 -1
- pangea/asyncio/__init__.py +1 -0
- pangea/asyncio/file_uploader.py +39 -0
- pangea/asyncio/request.py +19 -14
- pangea/asyncio/services/__init__.py +2 -1
- pangea/asyncio/services/audit.py +14 -149
- pangea/asyncio/services/authn.py +48 -64
- pangea/asyncio/services/intel.py +4 -4
- pangea/asyncio/services/redact.py +1 -20
- pangea/asyncio/services/sanitize.py +185 -0
- pangea/asyncio/services/share.py +573 -0
- pangea/asyncio/services/vault.py +4 -21
- pangea/file_uploader.py +35 -0
- pangea/request.py +21 -24
- pangea/response.py +28 -27
- pangea/services/__init__.py +2 -1
- pangea/services/audit/audit.py +16 -151
- pangea/services/audit/models.py +5 -44
- pangea/services/authn/authn.py +4 -20
- pangea/services/base.py +6 -23
- pangea/services/file_scan.py +0 -1
- pangea/services/intel.py +2 -2
- pangea/services/redact.py +1 -20
- pangea/services/sanitize.py +275 -0
- pangea/services/share/file_format.py +170 -0
- pangea/services/share/share.py +877 -0
- pangea/services/vault/vault.py +6 -23
- pangea/utils.py +91 -19
- {pangea_sdk-3.8.0.dist-info → pangea_sdk-3.8.0b2.dist-info}/METADATA +15 -31
- pangea_sdk-3.8.0b2.dist-info/RECORD +52 -0
- pangea/asyncio/services/authz.py +0 -259
- pangea/services/authz.py +0 -377
- pangea_sdk-3.8.0.dist-info/RECORD +0 -46
- {pangea_sdk-3.8.0.dist-info → pangea_sdk-3.8.0b2.dist-info}/WHEEL +0 -0
pangea/__init__.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
__version__ = "3.8.
|
1
|
+
__version__ = "3.8.0beta2"
|
2
2
|
|
3
3
|
from pangea.asyncio.request import PangeaRequestAsync
|
4
4
|
from pangea.config import PangeaConfig
|
5
|
+
from pangea.file_uploader import FileUploader
|
5
6
|
from pangea.request import PangeaRequest
|
6
7
|
from pangea.response import PangeaResponse
|
@@ -0,0 +1 @@
|
|
1
|
+
from .file_uploader import FileUploaderAsync
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright 2022 Pangea Cyber Corporation
|
2
|
+
# Author: Pangea Cyber Corporation
|
3
|
+
import io
|
4
|
+
import logging
|
5
|
+
from typing import Dict, Optional
|
6
|
+
|
7
|
+
from pangea.asyncio.request import PangeaRequestAsync
|
8
|
+
from pangea.request import PangeaConfig
|
9
|
+
from pangea.response import TransferMethod
|
10
|
+
|
11
|
+
|
12
|
+
class FileUploaderAsync:
|
13
|
+
def __init__(self) -> None:
|
14
|
+
self.logger = logging.getLogger("pangea")
|
15
|
+
self._request: PangeaRequestAsync = PangeaRequestAsync(
|
16
|
+
config=PangeaConfig(),
|
17
|
+
token="",
|
18
|
+
service="FileUploader",
|
19
|
+
logger=self.logger,
|
20
|
+
)
|
21
|
+
|
22
|
+
async def upload_file(
|
23
|
+
self,
|
24
|
+
url: str,
|
25
|
+
file: io.BufferedReader,
|
26
|
+
transfer_method: TransferMethod = TransferMethod.PUT_URL,
|
27
|
+
file_details: Optional[Dict] = None,
|
28
|
+
) -> None:
|
29
|
+
if transfer_method == TransferMethod.PUT_URL:
|
30
|
+
files = [("file", ("filename", file, "application/octet-stream"))]
|
31
|
+
await self._request.put_presigned_url(url=url, files=files) # type: ignore[arg-type]
|
32
|
+
elif transfer_method == TransferMethod.POST_URL:
|
33
|
+
files = [("file", ("filename", file, "application/octet-stream"))]
|
34
|
+
await self._request.post_presigned_url(url=url, data=file_details, files=files) # type: ignore[arg-type]
|
35
|
+
else:
|
36
|
+
raise ValueError(f"Transfer method not supported: {transfer_method}")
|
37
|
+
|
38
|
+
async def close(self) -> None:
|
39
|
+
await self._request.session.close()
|
pangea/asyncio/request.py
CHANGED
@@ -3,20 +3,18 @@
|
|
3
3
|
|
4
4
|
import asyncio
|
5
5
|
import json
|
6
|
+
import os
|
6
7
|
import time
|
7
8
|
from typing import Dict, List, Optional, Tuple, Type, Union
|
8
9
|
|
9
10
|
import aiohttp
|
10
11
|
from aiohttp import FormData
|
11
|
-
from typing_extensions import TypeVar
|
12
12
|
|
13
13
|
import pangea.exceptions as pe
|
14
14
|
from pangea.request import MultipartResponse, PangeaRequestBase
|
15
15
|
from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
|
16
16
|
from pangea.utils import default_encoder
|
17
17
|
|
18
|
-
TResult = TypeVar("TResult", bound=PangeaResponseResult, default=PangeaResponseResult)
|
19
|
-
|
20
18
|
|
21
19
|
class PangeaRequestAsync(PangeaRequestBase):
|
22
20
|
"""An object that makes direct calls to Pangea Service APIs.
|
@@ -30,12 +28,12 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
30
28
|
async def post(
|
31
29
|
self,
|
32
30
|
endpoint: str,
|
33
|
-
result_class: Type[
|
31
|
+
result_class: Type[PangeaResponseResult],
|
34
32
|
data: Union[str, Dict] = {},
|
35
33
|
files: List[Tuple] = [],
|
36
34
|
poll_result: bool = True,
|
37
35
|
url: Optional[str] = None,
|
38
|
-
) -> PangeaResponse
|
36
|
+
) -> PangeaResponse:
|
39
37
|
"""Makes the POST call to a Pangea Service endpoint.
|
40
38
|
|
41
39
|
Args:
|
@@ -93,7 +91,9 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
93
91
|
|
94
92
|
return self._check_response(pangea_response)
|
95
93
|
|
96
|
-
async def get(
|
94
|
+
async def get(
|
95
|
+
self, path: str, result_class: Type[PangeaResponseResult], check_response: bool = True
|
96
|
+
) -> PangeaResponse[Type[PangeaResponseResult]]:
|
97
97
|
"""Makes the GET call to a Pangea Service endpoint.
|
98
98
|
|
99
99
|
Args:
|
@@ -110,7 +110,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
110
110
|
|
111
111
|
async with self.session.get(url, headers=self._headers()) as requests_response:
|
112
112
|
await self._check_http_errors(requests_response)
|
113
|
-
pangea_response = PangeaResponse(
|
113
|
+
pangea_response = PangeaResponse( # type: ignore[var-annotated]
|
114
114
|
requests_response, result_class=result_class, json=await requests_response.json()
|
115
115
|
)
|
116
116
|
|
@@ -131,11 +131,11 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
131
131
|
raise pe.ServiceTemporarilyUnavailable(await resp.json())
|
132
132
|
|
133
133
|
async def poll_result_by_id(
|
134
|
-
self, request_id: str, result_class: Type[
|
135
|
-
)
|
134
|
+
self, request_id: str, result_class: Union[Type[PangeaResponseResult], Type[dict]], check_response: bool = True
|
135
|
+
):
|
136
136
|
path = self._get_poll_path(request_id)
|
137
137
|
self.logger.debug(json.dumps({"service": self.service, "action": "poll_result_once", "url": path}))
|
138
|
-
return await self.get(path, result_class, check_response=check_response)
|
138
|
+
return await self.get(path, result_class, check_response=check_response) # type: ignore[arg-type]
|
139
139
|
|
140
140
|
async def poll_result_once(self, response: PangeaResponse, check_response: bool = True):
|
141
141
|
request_id = response.request_id
|
@@ -180,6 +180,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
180
180
|
"service": self.service,
|
181
181
|
"action": "download_file",
|
182
182
|
"url": url,
|
183
|
+
"filename": filename,
|
183
184
|
"status": "start",
|
184
185
|
}
|
185
186
|
)
|
@@ -295,6 +296,9 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
295
296
|
raise AttributeError("files attribute should have at least 1 file")
|
296
297
|
|
297
298
|
response = await self.request_presigned_url(endpoint=endpoint, result_class=result_class, data=data)
|
299
|
+
if response.success: # This should only happen when uploading a zero bytes file
|
300
|
+
return response.raw_response
|
301
|
+
|
298
302
|
if response.accepted_result is None:
|
299
303
|
raise pe.PangeaException("No accepted_result field when requesting presigned url")
|
300
304
|
if response.accepted_result.post_url is None:
|
@@ -314,9 +318,8 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
314
318
|
) -> PangeaResponse:
|
315
319
|
# Send request
|
316
320
|
try:
|
317
|
-
# This should return 202 (AcceptedRequestException)
|
318
|
-
|
319
|
-
raise pe.PresignedURLException("Should return 202", resp)
|
321
|
+
# This should return 202 (AcceptedRequestException) at least zero size file is sent
|
322
|
+
return await self.post(endpoint=endpoint, result_class=result_class, data=data, poll_result=False)
|
320
323
|
except pe.AcceptedRequestException as e:
|
321
324
|
accepted_exception = e
|
322
325
|
except Exception as e:
|
@@ -325,7 +328,9 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
325
328
|
# Receive 202
|
326
329
|
return await self._poll_presigned_url(accepted_exception.response)
|
327
330
|
|
328
|
-
async def _poll_presigned_url(
|
331
|
+
async def _poll_presigned_url(
|
332
|
+
self, response: PangeaResponse[Type[PangeaResponseResult]]
|
333
|
+
) -> PangeaResponse[Type[PangeaResponseResult]]:
|
329
334
|
if response.http_status != 202:
|
330
335
|
raise AttributeError("Response should be 202")
|
331
336
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
from .audit import AuditAsync
|
2
2
|
from .authn import AuthNAsync
|
3
|
-
from .authz import AuthZAsync
|
4
3
|
from .embargo import EmbargoAsync
|
5
4
|
from .file_scan import FileScanAsync
|
6
5
|
from .intel import DomainIntelAsync, FileIntelAsync, IpIntelAsync, UrlIntelAsync, UserIntelAsync
|
7
6
|
from .redact import RedactAsync
|
7
|
+
from .share import ShareAsync
|
8
|
+
from .sanitize import SanitizeAsync
|
8
9
|
from .vault import VaultAsync
|
pangea/asyncio/services/audit.py
CHANGED
@@ -1,14 +1,11 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
-
from __future__ import annotations
|
4
|
-
|
5
3
|
import datetime
|
6
|
-
from typing import Any, Dict, List, Optional,
|
4
|
+
from typing import Any, Dict, List, Optional, Union
|
7
5
|
|
8
6
|
import pangea.exceptions as pexc
|
9
7
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
10
|
-
from pangea.
|
11
|
-
from pangea.response import PangeaResponse, PangeaResponseResult
|
8
|
+
from pangea.response import PangeaResponse
|
12
9
|
from pangea.services.audit.audit import AuditBase
|
13
10
|
from pangea.services.audit.exceptions import AuditException
|
14
11
|
from pangea.services.audit.models import (
|
@@ -16,7 +13,6 @@ from pangea.services.audit.models import (
|
|
16
13
|
DownloadRequest,
|
17
14
|
DownloadResult,
|
18
15
|
Event,
|
19
|
-
ExportRequest,
|
20
16
|
LogBulkResult,
|
21
17
|
LogResult,
|
22
18
|
PublishedRoot,
|
@@ -60,33 +56,14 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
60
56
|
|
61
57
|
def __init__(
|
62
58
|
self,
|
63
|
-
token
|
64
|
-
config
|
59
|
+
token,
|
60
|
+
config=None,
|
65
61
|
private_key_file: str = "",
|
66
|
-
public_key_info:
|
67
|
-
tenant_id: str
|
68
|
-
logger_name
|
69
|
-
config_id: str
|
70
|
-
)
|
71
|
-
"""
|
72
|
-
Audit client
|
73
|
-
|
74
|
-
Initializes a new Audit client.
|
75
|
-
|
76
|
-
Args:
|
77
|
-
token: Pangea API token.
|
78
|
-
config: Configuration.
|
79
|
-
private_key_file: Private key filepath.
|
80
|
-
public_key_info: Public key information.
|
81
|
-
tenant_id: Tenant ID.
|
82
|
-
logger_name: Logger name.
|
83
|
-
config_id: Configuration ID.
|
84
|
-
|
85
|
-
Examples:
|
86
|
-
config = PangeaConfig(domain="pangea_domain")
|
87
|
-
audit = AuditAsync(token="pangea_token", config=config)
|
88
|
-
"""
|
89
|
-
|
62
|
+
public_key_info: Dict[str, str] = {},
|
63
|
+
tenant_id: Optional[str] = None,
|
64
|
+
logger_name="pangea",
|
65
|
+
config_id: Optional[str] = None,
|
66
|
+
):
|
90
67
|
# FIXME: Temporary check to deprecate config_id from PangeaConfig.
|
91
68
|
# Delete it when deprecate PangeaConfig.config_id
|
92
69
|
if config_id and config is not None and config.config_id is not None:
|
@@ -295,7 +272,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
295
272
|
end: Optional[Union[datetime.datetime, str]] = None,
|
296
273
|
limit: Optional[int] = None,
|
297
274
|
max_results: Optional[int] = None,
|
298
|
-
search_restriction: Optional[
|
275
|
+
search_restriction: Optional[dict] = None,
|
299
276
|
verbose: Optional[bool] = None,
|
300
277
|
verify_consistency: bool = False,
|
301
278
|
verify_events: bool = True,
|
@@ -324,7 +301,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
324
301
|
end (datetime, optional): An RFC-3339 formatted timestamp, or relative time adjustment from the current time.
|
325
302
|
limit (int, optional): Optional[int] = None,
|
326
303
|
max_results (int, optional): Maximum number of results to return.
|
327
|
-
search_restriction (
|
304
|
+
search_restriction (dict, optional): A list of keys to restrict the search results to. Useful for partitioning data available to the query string.
|
328
305
|
verbose (bool, optional): If true, response include root and membership and consistency proofs.
|
329
306
|
verify_consistency (bool): True to verify logs consistency
|
330
307
|
verify_events (bool): True to verify hash events and signatures
|
@@ -370,7 +347,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
370
347
|
id: str,
|
371
348
|
limit: Optional[int] = 20,
|
372
349
|
offset: Optional[int] = 0,
|
373
|
-
assert_search_restriction: Optional[Dict[str, Sequence[str]]] = None,
|
374
350
|
verify_consistency: bool = False,
|
375
351
|
verify_events: bool = True,
|
376
352
|
) -> PangeaResponse[SearchResultOutput]:
|
@@ -385,7 +361,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
385
361
|
id (string): the id of a search action, found in `response.result.id`
|
386
362
|
limit (integer, optional): the maximum number of results to return, default is 20
|
387
363
|
offset (integer, optional): the position of the first result to return, default is 0
|
388
|
-
assert_search_restriction (Dict[str, Sequence[str]], optional): Assert the requested search results were queried with the exact same search restrictions, to ensure the results comply to the expected restrictions.
|
389
364
|
verify_consistency (bool): True to verify logs consistency
|
390
365
|
verify_events (bool): True to verify hash events and signatures
|
391
366
|
Raises:
|
@@ -403,8 +378,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
403
378
|
result_res: PangeaResponse[SearchResultsOutput] = audit.results(
|
404
379
|
id=search_res.result.id,
|
405
380
|
limit=10,
|
406
|
-
offset=0
|
407
|
-
assert_search_restriction={'source': ["monitor"]})
|
381
|
+
offset=0)
|
408
382
|
"""
|
409
383
|
|
410
384
|
if limit <= 0: # type: ignore[operator]
|
@@ -417,7 +391,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
417
391
|
id=id,
|
418
392
|
limit=limit,
|
419
393
|
offset=offset,
|
420
|
-
assert_search_restriction=assert_search_restriction,
|
421
394
|
)
|
422
395
|
response = await self.request.post("v1/results", SearchResultOutput, data=input.dict(exclude_none=True))
|
423
396
|
if verify_consistency and response.result is not None:
|
@@ -425,107 +398,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
425
398
|
|
426
399
|
return self.handle_results_response(response, verify_consistency, verify_events)
|
427
400
|
|
428
|
-
async def export(
|
429
|
-
self,
|
430
|
-
*,
|
431
|
-
format: DownloadFormat = DownloadFormat.CSV,
|
432
|
-
start: Optional[datetime.datetime] = None,
|
433
|
-
end: Optional[datetime.datetime] = None,
|
434
|
-
order: Optional[SearchOrder] = None,
|
435
|
-
order_by: Optional[str] = None,
|
436
|
-
verbose: bool = True,
|
437
|
-
) -> PangeaResponse[PangeaResponseResult]:
|
438
|
-
"""
|
439
|
-
Export from the audit log
|
440
|
-
|
441
|
-
Bulk export of data from the Secure Audit Log, with optional filtering.
|
442
|
-
|
443
|
-
OperationId: audit_post_v1_export
|
444
|
-
|
445
|
-
Args:
|
446
|
-
format: Format for the records.
|
447
|
-
start: The start of the time range to perform the search on.
|
448
|
-
end: The end of the time range to perform the search on. If omitted,
|
449
|
-
then all records up to the latest will be searched.
|
450
|
-
order: Specify the sort order of the response.
|
451
|
-
order_by: Name of column to sort the results by.
|
452
|
-
verbose: Whether or not to include the root hash of the tree and the
|
453
|
-
membership proof for each record.
|
454
|
-
|
455
|
-
Raises:
|
456
|
-
AuditException: If an audit based api exception happens
|
457
|
-
PangeaAPIException: If an API Error happens
|
458
|
-
|
459
|
-
Examples:
|
460
|
-
export_res = await audit.export(verbose=False)
|
461
|
-
|
462
|
-
# Export may take several dozens of minutes, so polling for the result
|
463
|
-
# should be done in a loop. That is omitted here for brevity's sake.
|
464
|
-
try:
|
465
|
-
await audit.poll_result(request_id=export_res.request_id)
|
466
|
-
except AcceptedRequestException:
|
467
|
-
# Retry later.
|
468
|
-
|
469
|
-
# Download the result when it's ready.
|
470
|
-
download_res = await audit.download_results(request_id=export_res.request_id)
|
471
|
-
download_res.result.dest_url
|
472
|
-
# => https://pangea-runtime.s3.amazonaws.com/audit/xxxxx/search_results_[...]
|
473
|
-
"""
|
474
|
-
input = ExportRequest(
|
475
|
-
format=format,
|
476
|
-
start=start,
|
477
|
-
end=end,
|
478
|
-
order=order,
|
479
|
-
order_by=order_by,
|
480
|
-
verbose=verbose,
|
481
|
-
)
|
482
|
-
try:
|
483
|
-
return await self.request.post(
|
484
|
-
"v1/export", PangeaResponseResult, data=input.dict(exclude_none=True), poll_result=False
|
485
|
-
)
|
486
|
-
except pexc.AcceptedRequestException as e:
|
487
|
-
return e.response
|
488
|
-
|
489
|
-
async def log_stream(self, data: dict) -> PangeaResponse[PangeaResponseResult]:
|
490
|
-
"""
|
491
|
-
Log streaming endpoint
|
492
|
-
|
493
|
-
This API allows 3rd party vendors (like Auth0) to stream events to this
|
494
|
-
endpoint where the structure of the payload varies across different
|
495
|
-
vendors.
|
496
|
-
|
497
|
-
OperationId: audit_post_v1_log_stream
|
498
|
-
|
499
|
-
Args:
|
500
|
-
data: Event data. The exact schema of this will vary by vendor.
|
501
|
-
|
502
|
-
Raises:
|
503
|
-
AuditException: If an audit based api exception happens
|
504
|
-
PangeaAPIException: If an API Error happens
|
505
|
-
|
506
|
-
Examples:
|
507
|
-
data = {
|
508
|
-
"logs": [
|
509
|
-
{
|
510
|
-
"log_id": "some log ID",
|
511
|
-
"data": {
|
512
|
-
"date": "2024-03-29T17:26:50.193Z",
|
513
|
-
"type": "sapi",
|
514
|
-
"description": "Create a log stream",
|
515
|
-
"client_id": "some client ID",
|
516
|
-
"ip": "127.0.0.1",
|
517
|
-
"user_agent": "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0",
|
518
|
-
"user_id": "some user ID",
|
519
|
-
},
|
520
|
-
}
|
521
|
-
# ...
|
522
|
-
]
|
523
|
-
}
|
524
|
-
|
525
|
-
response = await audit.log_stream(data)
|
526
|
-
"""
|
527
|
-
return await self.request.post("v1/log_stream", PangeaResponseResult, data=data)
|
528
|
-
|
529
401
|
async def root(self, tree_size: Optional[int] = None) -> PangeaResponse[RootResult]:
|
530
402
|
"""
|
531
403
|
Tamperproof verification
|
@@ -551,10 +423,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
551
423
|
return await self.request.post("v1/root", RootResult, data=input.dict(exclude_none=True))
|
552
424
|
|
553
425
|
async def download_results(
|
554
|
-
self,
|
555
|
-
result_id: Optional[str] = None,
|
556
|
-
format: DownloadFormat = DownloadFormat.CSV,
|
557
|
-
request_id: Optional[str] = None,
|
426
|
+
self, result_id: str, format: Optional[DownloadFormat] = None
|
558
427
|
) -> PangeaResponse[DownloadResult]:
|
559
428
|
"""
|
560
429
|
Download search results
|
@@ -566,7 +435,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
566
435
|
Args:
|
567
436
|
result_id: ID returned by the search API.
|
568
437
|
format: Format for the records.
|
569
|
-
request_id: ID returned by the export API.
|
570
438
|
|
571
439
|
Returns:
|
572
440
|
URL where search results can be downloaded.
|
@@ -582,10 +450,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
582
450
|
)
|
583
451
|
"""
|
584
452
|
|
585
|
-
|
586
|
-
raise ValueError("must pass one of `request_id` or `result_id`")
|
587
|
-
|
588
|
-
input = DownloadRequest(request_id=request_id, result_id=result_id, format=format)
|
453
|
+
input = DownloadRequest(result_id=result_id, format=format)
|
589
454
|
return await self.request.post("v1/download_results", DownloadResult, data=input.dict(exclude_none=True))
|
590
455
|
|
591
456
|
async def update_published_roots(self, result: SearchResultOutput):
|
pangea/asyncio/services/authn.py
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
-
from __future__ import annotations
|
4
3
|
|
5
4
|
from typing import Dict, List, Optional, Union
|
6
5
|
|
7
6
|
import pangea.services.authn.models as m
|
8
7
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
9
|
-
from pangea.config import PangeaConfig
|
10
8
|
from pangea.response import PangeaResponse
|
11
9
|
|
12
10
|
SERVICE_NAME = "authn"
|
@@ -39,24 +37,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
39
37
|
|
40
38
|
def __init__(
|
41
39
|
self,
|
42
|
-
token
|
43
|
-
config
|
44
|
-
logger_name
|
45
|
-
)
|
46
|
-
"""
|
47
|
-
AuthN client
|
48
|
-
|
49
|
-
Initializes a new AuthN client.
|
50
|
-
|
51
|
-
Args:
|
52
|
-
token: Pangea API token.
|
53
|
-
config: Configuration.
|
54
|
-
logger_name: Logger name.
|
55
|
-
|
56
|
-
Examples:
|
57
|
-
config = PangeaConfig(domain="pangea_domain")
|
58
|
-
authn = AuthNAsync(token="pangea_token", config=config)
|
59
|
-
"""
|
40
|
+
token,
|
41
|
+
config=None,
|
42
|
+
logger_name="pangea",
|
43
|
+
):
|
60
44
|
super().__init__(token, config, logger_name=logger_name)
|
61
45
|
self.user = AuthNAsync.UserAsync(token, config, logger_name=logger_name)
|
62
46
|
self.flow = AuthNAsync.FlowAsync(token, config, logger_name=logger_name)
|
@@ -69,10 +53,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
69
53
|
|
70
54
|
def __init__(
|
71
55
|
self,
|
72
|
-
token
|
73
|
-
config
|
74
|
-
logger_name
|
75
|
-
)
|
56
|
+
token,
|
57
|
+
config=None,
|
58
|
+
logger_name="pangea",
|
59
|
+
):
|
76
60
|
super().__init__(token, config, logger_name=logger_name)
|
77
61
|
|
78
62
|
async def invalidate(self, session_id: str) -> PangeaResponse[m.SessionInvalidateResult]:
|
@@ -164,10 +148,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
164
148
|
|
165
149
|
def __init__(
|
166
150
|
self,
|
167
|
-
token
|
168
|
-
config
|
169
|
-
logger_name
|
170
|
-
)
|
151
|
+
token,
|
152
|
+
config=None,
|
153
|
+
logger_name="pangea",
|
154
|
+
):
|
171
155
|
super().__init__(token, config, logger_name=logger_name)
|
172
156
|
self.session = AuthNAsync.ClientAsync.SessionAsync(token, config, logger_name=logger_name)
|
173
157
|
self.password = AuthNAsync.ClientAsync.PasswordAsync(token, config, logger_name=logger_name)
|
@@ -224,10 +208,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
224
208
|
|
225
209
|
def __init__(
|
226
210
|
self,
|
227
|
-
token
|
228
|
-
config
|
229
|
-
logger_name
|
230
|
-
)
|
211
|
+
token,
|
212
|
+
config=None,
|
213
|
+
logger_name="pangea",
|
214
|
+
):
|
231
215
|
super().__init__(token, config, logger_name=logger_name)
|
232
216
|
|
233
217
|
async def invalidate(self, token: str, session_id: str) -> PangeaResponse[m.ClientSessionInvalidateResult]:
|
@@ -359,10 +343,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
359
343
|
|
360
344
|
def __init__(
|
361
345
|
self,
|
362
|
-
token
|
363
|
-
config
|
364
|
-
logger_name
|
365
|
-
)
|
346
|
+
token,
|
347
|
+
config=None,
|
348
|
+
logger_name="pangea",
|
349
|
+
):
|
366
350
|
super().__init__(token, config, logger_name=logger_name)
|
367
351
|
|
368
352
|
async def change(
|
@@ -400,10 +384,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
400
384
|
|
401
385
|
def __init__(
|
402
386
|
self,
|
403
|
-
token
|
404
|
-
config
|
405
|
-
logger_name
|
406
|
-
)
|
387
|
+
token,
|
388
|
+
config=None,
|
389
|
+
logger_name="pangea",
|
390
|
+
):
|
407
391
|
super().__init__(token, config, logger_name=logger_name)
|
408
392
|
|
409
393
|
async def check(self, token: str) -> PangeaResponse[m.ClientTokenCheckResult]:
|
@@ -437,10 +421,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
437
421
|
|
438
422
|
def __init__(
|
439
423
|
self,
|
440
|
-
token
|
441
|
-
config
|
442
|
-
logger_name
|
443
|
-
)
|
424
|
+
token,
|
425
|
+
config=None,
|
426
|
+
logger_name="pangea",
|
427
|
+
):
|
444
428
|
super().__init__(token, config, logger_name=logger_name)
|
445
429
|
self.profile = AuthNAsync.UserAsync.ProfileAsync(token, config, logger_name=logger_name)
|
446
430
|
self.authenticators = AuthNAsync.UserAsync.AuthenticatorsAsync(token, config, logger_name=logger_name)
|
@@ -631,10 +615,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
631
615
|
|
632
616
|
def __init__(
|
633
617
|
self,
|
634
|
-
token
|
635
|
-
config
|
636
|
-
logger_name
|
637
|
-
)
|
618
|
+
token,
|
619
|
+
config=None,
|
620
|
+
logger_name="pangea",
|
621
|
+
):
|
638
622
|
super().__init__(token, config, logger_name=logger_name)
|
639
623
|
|
640
624
|
async def list(
|
@@ -703,10 +687,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
703
687
|
|
704
688
|
def __init__(
|
705
689
|
self,
|
706
|
-
token
|
707
|
-
config
|
708
|
-
logger_name
|
709
|
-
)
|
690
|
+
token,
|
691
|
+
config=None,
|
692
|
+
logger_name="pangea",
|
693
|
+
):
|
710
694
|
super().__init__(token, config, logger_name=logger_name)
|
711
695
|
|
712
696
|
async def delete(
|
@@ -774,10 +758,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
774
758
|
|
775
759
|
def __init__(
|
776
760
|
self,
|
777
|
-
token
|
778
|
-
config
|
779
|
-
logger_name
|
780
|
-
)
|
761
|
+
token,
|
762
|
+
config=None,
|
763
|
+
logger_name="pangea",
|
764
|
+
):
|
781
765
|
super().__init__(token, config, logger_name=logger_name)
|
782
766
|
|
783
767
|
async def get(
|
@@ -854,10 +838,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
854
838
|
|
855
839
|
def __init__(
|
856
840
|
self,
|
857
|
-
token
|
858
|
-
config
|
859
|
-
logger_name
|
860
|
-
)
|
841
|
+
token,
|
842
|
+
config=None,
|
843
|
+
logger_name="pangea",
|
844
|
+
):
|
861
845
|
super().__init__(token, config, logger_name=logger_name)
|
862
846
|
|
863
847
|
async def complete(self, flow_id: str) -> PangeaResponse[m.FlowCompleteResult]:
|
@@ -994,10 +978,10 @@ class AuthNAsync(ServiceBaseAsync):
|
|
994
978
|
|
995
979
|
def __init__(
|
996
980
|
self,
|
997
|
-
token
|
998
|
-
config
|
999
|
-
logger_name
|
1000
|
-
)
|
981
|
+
token,
|
982
|
+
config=None,
|
983
|
+
logger_name="pangea",
|
984
|
+
):
|
1001
985
|
super().__init__(token, config, logger_name=logger_name)
|
1002
986
|
|
1003
987
|
async def create(
|
pangea/asyncio/services/intel.py
CHANGED
@@ -76,7 +76,7 @@ class FileIntelAsync(ServiceBaseAsync):
|
|
76
76
|
provider: Optional[str] = None,
|
77
77
|
verbose: Optional[bool] = None,
|
78
78
|
raw: Optional[bool] = None,
|
79
|
-
) -> PangeaResponse[m.
|
79
|
+
) -> PangeaResponse[m.FileReputationResult]:
|
80
80
|
"""
|
81
81
|
Reputation check
|
82
82
|
|
@@ -182,7 +182,7 @@ class FileIntelAsync(ServiceBaseAsync):
|
|
182
182
|
hash = hash_256_filepath(filepath)
|
183
183
|
hashes.append(hash)
|
184
184
|
|
185
|
-
return await self.hash_reputation_bulk(
|
185
|
+
return await self.hash_reputation_bulk( # type: ignore[return-value]
|
186
186
|
hashes=hashes, hash_type="sha256", verbose=verbose, raw=raw, provider=provider
|
187
187
|
)
|
188
188
|
|
@@ -251,7 +251,7 @@ class DomainIntelAsync(ServiceBaseAsync):
|
|
251
251
|
verbose: Optional[bool] = None,
|
252
252
|
raw: Optional[bool] = None,
|
253
253
|
provider: Optional[str] = None,
|
254
|
-
) -> PangeaResponse[m.
|
254
|
+
) -> PangeaResponse[m.DomainReputationResult]:
|
255
255
|
"""
|
256
256
|
Reputation
|
257
257
|
|
@@ -373,7 +373,7 @@ class IpIntelAsync(ServiceBaseAsync):
|
|
373
373
|
|
374
374
|
async def reputation_bulk(
|
375
375
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
376
|
-
) -> PangeaResponse[m.
|
376
|
+
) -> PangeaResponse[m.IPReputationResult]:
|
377
377
|
"""
|
378
378
|
Reputation
|
379
379
|
|