pangea-sdk 3.8.0b1__py3-none-any.whl → 5.3.0__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 +1 -1
- pangea/asyncio/file_uploader.py +1 -1
- pangea/asyncio/request.py +49 -31
- pangea/asyncio/services/__init__.py +2 -0
- pangea/asyncio/services/audit.py +192 -31
- pangea/asyncio/services/authn.py +187 -109
- pangea/asyncio/services/authz.py +285 -0
- pangea/asyncio/services/base.py +21 -2
- pangea/asyncio/services/embargo.py +2 -2
- pangea/asyncio/services/file_scan.py +24 -9
- pangea/asyncio/services/intel.py +108 -34
- pangea/asyncio/services/redact.py +72 -4
- pangea/asyncio/services/sanitize.py +217 -0
- pangea/asyncio/services/share.py +246 -73
- pangea/asyncio/services/vault.py +1710 -750
- pangea/crypto/rsa.py +135 -0
- pangea/deep_verify.py +7 -1
- pangea/dump_audit.py +9 -8
- pangea/request.py +83 -59
- pangea/response.py +49 -31
- pangea/services/__init__.py +2 -0
- pangea/services/audit/audit.py +205 -42
- pangea/services/audit/models.py +56 -8
- pangea/services/audit/signing.py +6 -5
- pangea/services/audit/util.py +3 -3
- pangea/services/authn/authn.py +140 -70
- pangea/services/authn/models.py +167 -11
- pangea/services/authz.py +400 -0
- pangea/services/base.py +39 -8
- pangea/services/embargo.py +2 -2
- pangea/services/file_scan.py +32 -15
- pangea/services/intel.py +157 -32
- pangea/services/redact.py +152 -4
- pangea/services/sanitize.py +388 -0
- pangea/services/share/share.py +683 -107
- pangea/services/vault/models/asymmetric.py +120 -18
- pangea/services/vault/models/common.py +439 -141
- pangea/services/vault/models/keys.py +94 -0
- pangea/services/vault/models/secret.py +27 -3
- pangea/services/vault/models/symmetric.py +68 -22
- pangea/services/vault/vault.py +1690 -749
- pangea/tools.py +6 -7
- pangea/utils.py +16 -27
- pangea/verify_audit.py +270 -83
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/METADATA +43 -35
- pangea_sdk-5.3.0.dist-info/RECORD +56 -0
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/WHEEL +1 -1
- pangea_sdk-3.8.0b1.dist-info/RECORD +0 -50
pangea/services/base.py
CHANGED
@@ -1,23 +1,40 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
3
4
|
|
4
5
|
import copy
|
5
6
|
import logging
|
6
7
|
from typing import Dict, Optional, Type, Union
|
7
8
|
|
9
|
+
from typing_extensions import TypeVar
|
10
|
+
|
8
11
|
from pangea.asyncio.request import PangeaRequestAsync
|
9
12
|
from pangea.config import PangeaConfig
|
10
13
|
from pangea.exceptions import AcceptedRequestException
|
11
14
|
from pangea.request import PangeaRequest
|
12
15
|
from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult
|
13
16
|
|
17
|
+
TResult = TypeVar("TResult", bound=PangeaResponseResult, default=PangeaResponseResult)
|
18
|
+
|
14
19
|
|
15
20
|
class ServiceBase(object):
|
16
21
|
service_name: str = "base"
|
17
22
|
|
18
23
|
def __init__(
|
19
|
-
self,
|
20
|
-
|
24
|
+
self,
|
25
|
+
token: str,
|
26
|
+
config: PangeaConfig | None = None,
|
27
|
+
logger_name: str = "pangea",
|
28
|
+
config_id: str | None = None,
|
29
|
+
) -> None:
|
30
|
+
"""
|
31
|
+
Initializes a new Pangea service client.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
token: Pangea API token.
|
35
|
+
config: Configuration.
|
36
|
+
logger_name: Logger name.
|
37
|
+
"""
|
21
38
|
if not token:
|
22
39
|
raise Exception("No token provided")
|
23
40
|
|
@@ -30,11 +47,11 @@ class ServiceBase(object):
|
|
30
47
|
self.request.set_extra_headers(extra_headers)
|
31
48
|
|
32
49
|
@property
|
33
|
-
def token(self):
|
50
|
+
def token(self) -> str:
|
34
51
|
return self._token
|
35
52
|
|
36
53
|
@token.setter
|
37
|
-
def token(self, value):
|
54
|
+
def token(self, value: str) -> None:
|
38
55
|
self._token = value
|
39
56
|
|
40
57
|
@property
|
@@ -55,15 +72,16 @@ class ServiceBase(object):
|
|
55
72
|
exception: Optional[AcceptedRequestException] = None,
|
56
73
|
response: Optional[PangeaResponse] = None,
|
57
74
|
request_id: Optional[str] = None,
|
58
|
-
result_class:
|
59
|
-
) -> PangeaResponse:
|
75
|
+
result_class: Type[TResult] = PangeaResponseResult, # type: ignore[assignment]
|
76
|
+
) -> PangeaResponse[TResult]:
|
60
77
|
"""
|
61
78
|
Poll result
|
62
79
|
|
63
80
|
Returns request's result that has been accepted by the server
|
64
81
|
|
65
82
|
Args:
|
66
|
-
exception
|
83
|
+
exception: Exception that was previously raised by the SDK on a call
|
84
|
+
that is being processed.
|
67
85
|
|
68
86
|
Returns:
|
69
87
|
PangeaResponse
|
@@ -83,5 +101,18 @@ class ServiceBase(object):
|
|
83
101
|
else:
|
84
102
|
raise AttributeError("Need to set exception, response or request_id")
|
85
103
|
|
86
|
-
def download_file(self, url: str, filename:
|
104
|
+
def download_file(self, url: str, filename: str | None = None) -> AttachedFile:
|
105
|
+
"""
|
106
|
+
Download file
|
107
|
+
|
108
|
+
Download a file from the specified URL and save it with the given
|
109
|
+
filename.
|
110
|
+
|
111
|
+
Args:
|
112
|
+
url: URL of the file to download
|
113
|
+
filename: Name to save the downloaded file as. If not provided, the
|
114
|
+
filename will be determined from the Content-Disposition header or
|
115
|
+
the URL.
|
116
|
+
"""
|
117
|
+
|
87
118
|
return self.request.download_file(url=url, filename=filename)
|
pangea/services/embargo.py
CHANGED
@@ -103,7 +103,7 @@ class Embargo(ServiceBase):
|
|
103
103
|
response = embargo.ip_check("190.6.64.94")
|
104
104
|
"""
|
105
105
|
input = IPCheckRequest(ip=ip)
|
106
|
-
return self.request.post("v1/ip/check", EmbargoResult, data=input.
|
106
|
+
return self.request.post("v1/ip/check", EmbargoResult, data=input.model_dump())
|
107
107
|
|
108
108
|
def iso_check(self, iso_code: str) -> PangeaResponse[EmbargoResult]:
|
109
109
|
"""
|
@@ -130,4 +130,4 @@ class Embargo(ServiceBase):
|
|
130
130
|
response = embargo.iso_check("CU")
|
131
131
|
"""
|
132
132
|
input = ISOCheckRequest(iso_code=iso_code)
|
133
|
-
return self.request.post("v1/iso/check", result_class=EmbargoResult, data=input.
|
133
|
+
return self.request.post("v1/iso/check", result_class=EmbargoResult, data=input.model_dump())
|
pangea/services/file_scan.py
CHANGED
@@ -11,22 +11,25 @@ from pangea.utils import FileUploadParams, get_file_upload_params
|
|
11
11
|
|
12
12
|
|
13
13
|
class FileScanRequest(APIRequestModel):
|
14
|
-
"""
|
15
|
-
File Scan request data
|
16
|
-
|
17
|
-
provider (str, optional): Provider of the information. Default provider defined by the configuration.
|
18
|
-
verbose (bool, optional): Echo back the parameters of the API in the response
|
19
|
-
raw (bool, optional): Return additional details from the provider.
|
20
|
-
"""
|
14
|
+
"""File Scan request data."""
|
21
15
|
|
22
16
|
verbose: Optional[bool] = None
|
17
|
+
"""Echo back the parameters of the API in the response."""
|
18
|
+
|
23
19
|
raw: Optional[bool] = None
|
20
|
+
"""Return additional details from the provider."""
|
21
|
+
|
24
22
|
provider: Optional[str] = None
|
23
|
+
"""Provider of the information. Default provider defined by the configuration."""
|
24
|
+
|
25
25
|
size: Optional[int] = None
|
26
26
|
crc32c: Optional[str] = None
|
27
27
|
sha256: Optional[str] = None
|
28
28
|
source_url: Optional[str] = None
|
29
|
+
"""A URL where the file to be scanned can be downloaded."""
|
30
|
+
|
29
31
|
transfer_method: TransferMethod = TransferMethod.POST_URL
|
32
|
+
"""The transfer method used to upload the file data."""
|
30
33
|
|
31
34
|
|
32
35
|
class FileScanData(PangeaResponseResult):
|
@@ -71,7 +74,6 @@ class FileScan(ServiceBase):
|
|
71
74
|
"""
|
72
75
|
|
73
76
|
service_name = "file-scan"
|
74
|
-
version = "v1"
|
75
77
|
|
76
78
|
def file_scan(
|
77
79
|
self,
|
@@ -92,12 +94,14 @@ class FileScan(ServiceBase):
|
|
92
94
|
OperationId: file_scan_post_v1_scan
|
93
95
|
|
94
96
|
Args:
|
95
|
-
file (io.BufferedReader, optional): file to be scanned (should be opened with read permissions and in binary format)
|
96
97
|
file_path (str, optional): filepath to be opened and scanned
|
98
|
+
file (io.BufferedReader, optional): file to be scanned (should be opened with read permissions and in binary format)
|
97
99
|
verbose (bool, optional): Echo the API parameters in the response
|
98
100
|
raw (bool, optional): Include raw data from this provider
|
99
101
|
provider (str, optional): Scan file using this provider
|
100
102
|
sync_call (bool, optional): True to wait until server returns a result, False to return immediately and retrieve result asynchronously
|
103
|
+
transfer_method (TransferMethod, optional): Transfer method used to upload the file data.
|
104
|
+
source_url (str, optional): A URL where the Pangea APIs can fetch the contents of the input file.
|
101
105
|
|
102
106
|
Raises:
|
103
107
|
PangeaAPIException: If an API Error happens
|
@@ -118,6 +122,15 @@ class FileScan(ServiceBase):
|
|
118
122
|
print(f"\\t{err.detail} \\n")
|
119
123
|
"""
|
120
124
|
|
125
|
+
if transfer_method == TransferMethod.SOURCE_URL and source_url is None:
|
126
|
+
raise ValueError("`source_url` argument is required when using `TransferMethod.SOURCE_URL`.")
|
127
|
+
|
128
|
+
if source_url is not None and transfer_method != TransferMethod.SOURCE_URL:
|
129
|
+
raise ValueError(
|
130
|
+
"`transfer_method` should be `TransferMethod.SOURCE_URL` when using the `source_url` argument."
|
131
|
+
)
|
132
|
+
|
133
|
+
files: Optional[List[Tuple]] = None
|
121
134
|
if file or file_path:
|
122
135
|
if file_path:
|
123
136
|
file = open(file_path, "rb")
|
@@ -128,9 +141,9 @@ class FileScan(ServiceBase):
|
|
128
141
|
size = params.size
|
129
142
|
else:
|
130
143
|
crc, sha, size = None, None, None
|
131
|
-
files
|
132
|
-
|
133
|
-
raise ValueError("Need to set file_path or
|
144
|
+
files = [("upload", ("filename", file, "application/octet-stream"))]
|
145
|
+
elif source_url is None:
|
146
|
+
raise ValueError("Need to set one of `file_path`, `file`, or `source_url` arguments.")
|
134
147
|
|
135
148
|
input = FileScanRequest(
|
136
149
|
verbose=verbose,
|
@@ -142,8 +155,12 @@ class FileScan(ServiceBase):
|
|
142
155
|
transfer_method=transfer_method,
|
143
156
|
source_url=source_url,
|
144
157
|
)
|
145
|
-
data = input.
|
146
|
-
|
158
|
+
data = input.model_dump(exclude_none=True)
|
159
|
+
try:
|
160
|
+
return self.request.post("v1/scan", FileScanResult, data=data, files=files, poll_result=sync_call)
|
161
|
+
finally:
|
162
|
+
if file_path and file:
|
163
|
+
file.close()
|
147
164
|
|
148
165
|
def request_upload_url(
|
149
166
|
self,
|
@@ -164,7 +181,7 @@ class FileScan(ServiceBase):
|
|
164
181
|
input.sha256 = params.sha256_hex
|
165
182
|
input.size = params.size
|
166
183
|
|
167
|
-
data = input.
|
184
|
+
data = input.model_dump(exclude_none=True)
|
168
185
|
return self.request.request_presigned_url("v1/scan", FileScanResult, data=data)
|
169
186
|
|
170
187
|
|