pangea-sdk 3.8.0b1__py3-none-any.whl → 3.8.0b3__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/services/__init__.py +2 -0
- pangea/asyncio/services/authz.py +267 -0
- pangea/asyncio/services/sanitize.py +185 -0
- pangea/asyncio/services/share.py +39 -26
- pangea/services/__init__.py +2 -0
- pangea/services/authz.py +377 -0
- pangea/services/file_scan.py +0 -1
- pangea/services/sanitize.py +275 -0
- pangea/services/share/share.py +39 -26
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-3.8.0b3.dist-info}/METADATA +28 -3
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-3.8.0b3.dist-info}/RECORD +13 -9
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-3.8.0b3.dist-info}/WHEEL +0 -0
pangea/services/authz.py
ADDED
@@ -0,0 +1,377 @@
|
|
1
|
+
# Copyright 2022 Pangea Cyber Corporation
|
2
|
+
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
import enum
|
5
|
+
from typing import Any, Dict, List, Optional, Union
|
6
|
+
|
7
|
+
from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
|
8
|
+
from pangea.services.base import ServiceBase
|
9
|
+
|
10
|
+
|
11
|
+
class ItemOrder(str, enum.Enum):
|
12
|
+
ASC = "asc"
|
13
|
+
DESC = "desc"
|
14
|
+
|
15
|
+
def __str__(self):
|
16
|
+
return str(self.value)
|
17
|
+
|
18
|
+
def __repr__(self):
|
19
|
+
return str(self.value)
|
20
|
+
|
21
|
+
|
22
|
+
class TupleOrderBy(str, enum.Enum):
|
23
|
+
RESOURCE_NAMESPACE = "resource_namespace"
|
24
|
+
RESOURCE_ID = "resource_id"
|
25
|
+
RELATION = "relation"
|
26
|
+
SUBJECT_NAMESPACE = "subject_namespace"
|
27
|
+
SUBJECT_ID = "subject_id"
|
28
|
+
SUBJECT_ACTION = "subject_action"
|
29
|
+
|
30
|
+
def __str__(self):
|
31
|
+
return str(self.value)
|
32
|
+
|
33
|
+
def __repr__(self):
|
34
|
+
return str(self.value)
|
35
|
+
|
36
|
+
|
37
|
+
class Resource(PangeaResponseResult):
|
38
|
+
namespace: str
|
39
|
+
id: Optional[str] = None
|
40
|
+
|
41
|
+
|
42
|
+
class Subject(PangeaResponseResult):
|
43
|
+
namespace: str
|
44
|
+
id: Optional[str] = None
|
45
|
+
action: Optional[str] = None
|
46
|
+
|
47
|
+
|
48
|
+
class Tuple(PangeaResponseResult):
|
49
|
+
resource: Resource
|
50
|
+
relation: str
|
51
|
+
subject: Subject
|
52
|
+
|
53
|
+
|
54
|
+
class TupleCreateRequest(APIRequestModel):
|
55
|
+
tuples: List[Tuple]
|
56
|
+
|
57
|
+
|
58
|
+
class TupleCreateResult(PangeaResponseResult):
|
59
|
+
pass
|
60
|
+
|
61
|
+
|
62
|
+
class TupleListFilter(APIRequestModel):
|
63
|
+
resource_namespace: Optional[str] = None
|
64
|
+
resource_namespace__contains: Optional[List[str]] = None
|
65
|
+
resource_namespace__in: Optional[List[str]] = None
|
66
|
+
resource_id: Optional[str] = None
|
67
|
+
resource_id__contains: Optional[List[str]] = None
|
68
|
+
resource_id__in: Optional[List[str]] = None
|
69
|
+
relation: Optional[str] = None
|
70
|
+
relation__contains: Optional[List[str]] = None
|
71
|
+
relation__in: Optional[List[str]] = None
|
72
|
+
subject_namespace: Optional[str] = None
|
73
|
+
subject_namespace__contains: Optional[List[str]] = None
|
74
|
+
subject_namespace__in: Optional[List[str]] = None
|
75
|
+
subject_id: Optional[str] = None
|
76
|
+
subject_id__contains: Optional[List[str]] = None
|
77
|
+
subject_id__in: Optional[List[str]] = None
|
78
|
+
subject_action: Optional[str] = None
|
79
|
+
subject_action__contains: Optional[List[str]] = None
|
80
|
+
subject_action__in: Optional[List[str]] = None
|
81
|
+
|
82
|
+
|
83
|
+
class TupleListRequest(APIRequestModel):
|
84
|
+
filter: Optional[Union[Dict, TupleListFilter]] = None
|
85
|
+
size: Optional[int] = None
|
86
|
+
last: Optional[str] = None
|
87
|
+
order: Optional[ItemOrder] = None
|
88
|
+
order_by: Optional[TupleOrderBy] = None
|
89
|
+
|
90
|
+
|
91
|
+
class TupleListResult(PangeaResponseResult):
|
92
|
+
tuples: List[Tuple]
|
93
|
+
last: str
|
94
|
+
count: int
|
95
|
+
|
96
|
+
|
97
|
+
class TupleDeleteRequest(APIRequestModel):
|
98
|
+
tuples: List[Tuple]
|
99
|
+
|
100
|
+
|
101
|
+
class TupleDeleteResult(PangeaResponseResult):
|
102
|
+
pass
|
103
|
+
|
104
|
+
|
105
|
+
class CheckRequest(APIRequestModel):
|
106
|
+
resource: Resource
|
107
|
+
action: str
|
108
|
+
subject: Subject
|
109
|
+
debug: Optional[bool] = None
|
110
|
+
attributes: Optional[Dict[str, Any]] = None
|
111
|
+
|
112
|
+
|
113
|
+
class DebugPath(APIResponseModel):
|
114
|
+
namespace: str
|
115
|
+
id: str
|
116
|
+
action: Optional[str]
|
117
|
+
|
118
|
+
|
119
|
+
class Debug(APIResponseModel):
|
120
|
+
path: List[DebugPath]
|
121
|
+
|
122
|
+
|
123
|
+
class CheckResult(PangeaResponseResult):
|
124
|
+
schema_id: str
|
125
|
+
schema_version: int
|
126
|
+
depth: int
|
127
|
+
allowed: bool
|
128
|
+
debug: Optional[Debug] = None
|
129
|
+
|
130
|
+
|
131
|
+
class ListResourcesRequest(APIRequestModel):
|
132
|
+
namespace: str
|
133
|
+
action: str
|
134
|
+
subject: Subject
|
135
|
+
|
136
|
+
|
137
|
+
class ListResourcesResult(PangeaResponseResult):
|
138
|
+
ids: List[str]
|
139
|
+
|
140
|
+
|
141
|
+
class ListSubjectsRequest(APIRequestModel):
|
142
|
+
resource: Resource
|
143
|
+
action: str
|
144
|
+
|
145
|
+
|
146
|
+
class ListSubjectsResult(PangeaResponseResult):
|
147
|
+
subjects: List[Subject]
|
148
|
+
|
149
|
+
|
150
|
+
class AuthZ(ServiceBase):
|
151
|
+
"""AuthZ service client. (Beta)
|
152
|
+
|
153
|
+
Provides methods to interact with the Pangea AuthZ Service.
|
154
|
+
Documentation for the AuthZ Service API can be found at
|
155
|
+
<https://pangea.cloud/docs/api/authz>. Note that this service is in Beta and
|
156
|
+
is subject to change.
|
157
|
+
|
158
|
+
Examples:
|
159
|
+
import os
|
160
|
+
from pangea.config import PangeaConfig
|
161
|
+
from pangea.services import AuthZ
|
162
|
+
|
163
|
+
PANGEA_TOKEN = os.getenv("PANGEA_AUTHZ_TOKEN")
|
164
|
+
|
165
|
+
authz_config = PangeaConfig(domain="aws.us.pangea.cloud")
|
166
|
+
|
167
|
+
# Setup Pangea AuthZ service client
|
168
|
+
authz = AuthZ(token=PANGEA_TOKEN, config=authz_config)
|
169
|
+
"""
|
170
|
+
|
171
|
+
service_name = "authz"
|
172
|
+
|
173
|
+
def __init__(self, token: str, config=None, logger_name="pangea", config_id: Optional[str] = None):
|
174
|
+
super().__init__(token, config, logger_name, config_id=config_id)
|
175
|
+
|
176
|
+
def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateResult]:
|
177
|
+
"""Create tuples. (Beta)
|
178
|
+
|
179
|
+
Create tuples in the AuthZ Service. The request will fail if there is no schema
|
180
|
+
or the tuples do not validate against the schema.
|
181
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
182
|
+
|
183
|
+
Args:
|
184
|
+
tuples (List[Tuple]): List of tuples to be created.
|
185
|
+
|
186
|
+
Raises:
|
187
|
+
PangeaAPIException: If an API Error happens.
|
188
|
+
|
189
|
+
Returns:
|
190
|
+
Pangea Response with empty result.
|
191
|
+
Available response fields can be found in our
|
192
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1beta/tuple/create).
|
193
|
+
|
194
|
+
Examples:
|
195
|
+
response = authz.tuple_create(
|
196
|
+
tuples=[
|
197
|
+
Tuple(
|
198
|
+
resource=Resource(namespace="file", id="file_1"),
|
199
|
+
relation="owner",
|
200
|
+
subject=Subject(namespace="user", id="user_1"),
|
201
|
+
)
|
202
|
+
]
|
203
|
+
)
|
204
|
+
"""
|
205
|
+
|
206
|
+
input_data = TupleCreateRequest(tuples=tuples)
|
207
|
+
return self.request.post("v1beta/tuple/create", TupleCreateResult, data=input_data.dict(exclude_none=True))
|
208
|
+
|
209
|
+
def tuple_list(
|
210
|
+
self,
|
211
|
+
filter: TupleListFilter,
|
212
|
+
size: Optional[int] = None,
|
213
|
+
last: Optional[str] = None,
|
214
|
+
order: Optional[ItemOrder] = None,
|
215
|
+
order_by: Optional[TupleOrderBy] = None,
|
216
|
+
) -> PangeaResponse[TupleListResult]:
|
217
|
+
"""List tuples. (Beta)
|
218
|
+
|
219
|
+
Return a paginated list of filtered tuples. The filter is given in terms
|
220
|
+
of a tuple. Fill out the fields that you want to filter. If the filter
|
221
|
+
is empty it will return all the tuples.
|
222
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
223
|
+
|
224
|
+
Args:
|
225
|
+
filter (TupleListFilter): The filter for listing tuples.
|
226
|
+
size (Optional[int]): The size of the result set. Default is None.
|
227
|
+
last (Optional[str]): The last token from a previous response. Default is None.
|
228
|
+
order (Optional[ItemOrder]): Order results asc(ending) or desc(ending).
|
229
|
+
order_by (Optional[TupleOrderBy]): Which field to order results by.
|
230
|
+
|
231
|
+
Raises:
|
232
|
+
PangeaAPIException: If an API Error happens.
|
233
|
+
|
234
|
+
Returns:
|
235
|
+
Pangea Response with a list of tuples and the last token.
|
236
|
+
Available response fields can be found in our
|
237
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1beta/tuple/list).
|
238
|
+
|
239
|
+
Examples:
|
240
|
+
authz.tuple_list(TupleListFilter(subject_namespace="user", subject_id="user_1"))
|
241
|
+
"""
|
242
|
+
input_data = TupleListRequest(
|
243
|
+
filter=filter.dict(exclude_none=True), size=size, last=last, order=order, order_by=order_by
|
244
|
+
)
|
245
|
+
return self.request.post("v1beta/tuple/list", TupleListResult, data=input_data.dict(exclude_none=True))
|
246
|
+
|
247
|
+
def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
|
248
|
+
"""Delete tuples. (Beta)
|
249
|
+
|
250
|
+
Delete tuples in the AuthZ Service.
|
251
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
252
|
+
|
253
|
+
Args:
|
254
|
+
tuples (List[Tuple]): List of tuples to be deleted.
|
255
|
+
|
256
|
+
Raises:
|
257
|
+
PangeaAPIException: If an API Error happens.
|
258
|
+
|
259
|
+
Returns:
|
260
|
+
Pangea Response with empty result.
|
261
|
+
Available response fields can be found in our
|
262
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1beta/tuple/delete).
|
263
|
+
|
264
|
+
Examples:
|
265
|
+
response = authz.tuple_delete(
|
266
|
+
tuples=[
|
267
|
+
Tuple(
|
268
|
+
resource=Resource(namespace="file", id="file_1"),
|
269
|
+
relation="owner",
|
270
|
+
subject=Subject(namespace="user", id="user_1"),
|
271
|
+
)
|
272
|
+
]
|
273
|
+
)
|
274
|
+
"""
|
275
|
+
|
276
|
+
input_data = TupleDeleteRequest(tuples=tuples)
|
277
|
+
return self.request.post("v1beta/tuple/delete", TupleDeleteResult, data=input_data.dict(exclude_none=True))
|
278
|
+
|
279
|
+
def check(
|
280
|
+
self,
|
281
|
+
resource: Resource,
|
282
|
+
action: str,
|
283
|
+
subject: Subject,
|
284
|
+
debug: Optional[bool] = None,
|
285
|
+
attributes: Optional[Dict[str, Union[int, str]]] = None,
|
286
|
+
) -> PangeaResponse[CheckResult]:
|
287
|
+
"""Perform a check request. (Beta)
|
288
|
+
|
289
|
+
Check if a subject has permission to perform an action on the resource.
|
290
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
291
|
+
|
292
|
+
Args:
|
293
|
+
resource (Resource): The resource to check.
|
294
|
+
action (str): The action to check.
|
295
|
+
subject (Subject): The subject to check.
|
296
|
+
debug (Optional[bool]): Setting this value to True will provide a detailed analysis of the check.
|
297
|
+
attributes (Optional[Dict[str, Union[int, str]]]): Additional attributes for the check.
|
298
|
+
|
299
|
+
Raises:
|
300
|
+
PangeaAPIException: If an API Error happens.
|
301
|
+
|
302
|
+
Returns:
|
303
|
+
Pangea Response with the result of the check.
|
304
|
+
Available response fields can be found in our
|
305
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1beta/check).
|
306
|
+
|
307
|
+
Examples:
|
308
|
+
response = authz.check(
|
309
|
+
resource=Resource(namespace="file", id="file_1"),
|
310
|
+
action="update",
|
311
|
+
subject=Subject(namespace="user", id="user_1"),
|
312
|
+
debug=True,
|
313
|
+
)
|
314
|
+
"""
|
315
|
+
|
316
|
+
input_data = CheckRequest(resource=resource, action=action, subject=subject, debug=debug, attributes=attributes)
|
317
|
+
return self.request.post("v1beta/check", CheckResult, data=input_data.dict(exclude_none=True))
|
318
|
+
|
319
|
+
def list_resources(self, namespace: str, action: str, subject: Subject) -> PangeaResponse[ListResourcesResult]:
|
320
|
+
"""List resources. (Beta)
|
321
|
+
|
322
|
+
Given a namespace, action, and subject, list all the resources in the
|
323
|
+
namespace that the subject has access to the action with.
|
324
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
325
|
+
|
326
|
+
Args:
|
327
|
+
namespace (str): The namespace to filter resources.
|
328
|
+
action (str): The action to filter resources.
|
329
|
+
subject (Subject): The subject to filter resources.
|
330
|
+
|
331
|
+
Raises:
|
332
|
+
PangeaAPIException: If an API Error happens.
|
333
|
+
|
334
|
+
Returns:
|
335
|
+
Pangea Response with a list of resource IDs.
|
336
|
+
Available response fields can be found in our
|
337
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1beta/list-resources).
|
338
|
+
|
339
|
+
Examples:
|
340
|
+
authz.list_resources(
|
341
|
+
namespace="file",
|
342
|
+
action="update",
|
343
|
+
subject=Subject(namespace="user", id="user_1"),
|
344
|
+
)
|
345
|
+
"""
|
346
|
+
|
347
|
+
input_data = ListResourcesRequest(namespace=namespace, action=action, subject=subject)
|
348
|
+
return self.request.post("v1beta/list-resources", ListResourcesResult, data=input_data.dict(exclude_none=True))
|
349
|
+
|
350
|
+
def list_subjects(self, resource: Resource, action: str) -> PangeaResponse[ListSubjectsResult]:
|
351
|
+
"""List subjects. (Beta)
|
352
|
+
|
353
|
+
Given a resource and an action, return the list of subjects who have
|
354
|
+
access to the action for the given resource.
|
355
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
356
|
+
|
357
|
+
Args:
|
358
|
+
resource (Resource): The resource to filter subjects.
|
359
|
+
action (str): The action to filter subjects.
|
360
|
+
|
361
|
+
Raises:
|
362
|
+
PangeaAPIException: If an API Error happens.
|
363
|
+
|
364
|
+
Returns:
|
365
|
+
Pangea Response with a list of subjects.
|
366
|
+
Available response fields can be found in our
|
367
|
+
[API Documentation](https://pangea.cloud/docs/api/authz#/v1beta/list-subjects).
|
368
|
+
|
369
|
+
Examples:
|
370
|
+
response = authz.list_subjects(
|
371
|
+
resource=Resource(namespace="file", id="file_1"),
|
372
|
+
action="update",
|
373
|
+
)
|
374
|
+
"""
|
375
|
+
|
376
|
+
input_data = ListSubjectsRequest(resource=resource, action=action)
|
377
|
+
return self.request.post("v1beta/list-subjects", ListSubjectsResult, data=input_data.dict(exclude_none=True))
|
pangea/services/file_scan.py
CHANGED
@@ -0,0 +1,275 @@
|
|
1
|
+
# Copyright 2022 Pangea Cyber Corporation
|
2
|
+
# Author: Pangea Cyber Corporation
|
3
|
+
import io
|
4
|
+
from typing import Dict, List, Optional, Tuple
|
5
|
+
|
6
|
+
from pangea.response import APIRequestModel, PangeaResponse, PangeaResponseResult, TransferMethod
|
7
|
+
from pangea.services.base import ServiceBase
|
8
|
+
from pangea.utils import FileUploadParams, get_file_upload_params
|
9
|
+
|
10
|
+
|
11
|
+
class SanitizeFile(APIRequestModel):
|
12
|
+
scan_provider: Optional[str] = None
|
13
|
+
"""Provider to use for File Scan."""
|
14
|
+
|
15
|
+
cdr_provider: Optional[str] = None
|
16
|
+
"""Provider to use for CDR."""
|
17
|
+
|
18
|
+
|
19
|
+
class SanitizeContent(APIRequestModel):
|
20
|
+
url_intel: Optional[bool] = None
|
21
|
+
"""Perform URL Intel lookup."""
|
22
|
+
|
23
|
+
url_intel_provider: Optional[str] = None
|
24
|
+
"""Provider to use for URL Intel."""
|
25
|
+
|
26
|
+
domain_intel: Optional[bool] = None
|
27
|
+
"""Perform Domain Intel lookup."""
|
28
|
+
|
29
|
+
domain_intel_provider: Optional[str] = None
|
30
|
+
"""Provider to use for Domain Intel lookup."""
|
31
|
+
|
32
|
+
defang: Optional[bool] = None
|
33
|
+
"""Defang external links."""
|
34
|
+
|
35
|
+
defang_threshold: Optional[int] = None
|
36
|
+
"""Defang risk threshold."""
|
37
|
+
|
38
|
+
redact: Optional[bool] = None
|
39
|
+
"""Redact sensitive content."""
|
40
|
+
|
41
|
+
remove_attachments: Optional[bool] = None
|
42
|
+
"""Remove file attachments (PDF only)."""
|
43
|
+
|
44
|
+
remove_interactive: Optional[bool] = None
|
45
|
+
"""Remove interactive content (PDF only)."""
|
46
|
+
|
47
|
+
|
48
|
+
class SanitizeShareOutput(APIRequestModel):
|
49
|
+
enabled: Optional[bool] = None
|
50
|
+
"""Store Sanitized files to Pangea Secure Share."""
|
51
|
+
|
52
|
+
output_folder: Optional[str] = None
|
53
|
+
"""
|
54
|
+
Store Sanitized files to this Secure Share folder (will be auto-created if
|
55
|
+
it does not exist)
|
56
|
+
"""
|
57
|
+
|
58
|
+
|
59
|
+
class SanitizeRequest(APIRequestModel):
|
60
|
+
transfer_method: TransferMethod = TransferMethod.POST_URL
|
61
|
+
source_url: Optional[str] = None
|
62
|
+
share_id: Optional[str] = None
|
63
|
+
file: Optional[SanitizeFile] = None
|
64
|
+
content: Optional[SanitizeContent] = None
|
65
|
+
share_output: Optional[SanitizeShareOutput] = None
|
66
|
+
size: Optional[int] = None
|
67
|
+
crc32c: Optional[str] = None
|
68
|
+
sha256: Optional[str] = None
|
69
|
+
uploaded_file_name: Optional[str] = None
|
70
|
+
|
71
|
+
|
72
|
+
class DefangData(PangeaResponseResult):
|
73
|
+
external_urls_count: Optional[int] = None
|
74
|
+
external_domains_count: Optional[int] = None
|
75
|
+
defanged_count: Optional[int] = None
|
76
|
+
url_intel_summary: Optional[str] = None
|
77
|
+
domain_intel_summary: Optional[str] = None
|
78
|
+
|
79
|
+
|
80
|
+
class RedactData(PangeaResponseResult):
|
81
|
+
redaction_count: Optional[int] = None
|
82
|
+
summary_counts: Dict = {}
|
83
|
+
|
84
|
+
|
85
|
+
class CDR(PangeaResponseResult):
|
86
|
+
file_attachments_removed: Optional[int] = None
|
87
|
+
interactive_contents_removed: Optional[int] = None
|
88
|
+
|
89
|
+
|
90
|
+
class SanitizeData(PangeaResponseResult):
|
91
|
+
defang: Optional[DefangData] = None
|
92
|
+
redact: Optional[RedactData] = None
|
93
|
+
malicious_file: Optional[bool] = None
|
94
|
+
cdr: Optional[CDR] = None
|
95
|
+
|
96
|
+
|
97
|
+
class SanitizeResult(PangeaResponseResult):
|
98
|
+
dest_url: Optional[str] = None
|
99
|
+
dest_share_id: Optional[str] = None
|
100
|
+
data: SanitizeData
|
101
|
+
parameters: Dict = {}
|
102
|
+
|
103
|
+
|
104
|
+
class Sanitize(ServiceBase):
|
105
|
+
"""Sanitize service client.
|
106
|
+
|
107
|
+
Examples:
|
108
|
+
import os
|
109
|
+
|
110
|
+
# Pangea SDK
|
111
|
+
from pangea.config import PangeaConfig
|
112
|
+
from pangea.services import Sanitize
|
113
|
+
|
114
|
+
PANGEA_SANITIZE_TOKEN = os.getenv("PANGEA_SANITIZE_TOKEN")
|
115
|
+
config = PangeaConfig(domain="pangea.cloud")
|
116
|
+
|
117
|
+
sanitize = Sanitize(token=PANGEA_SANITIZE_TOKEN, config=config)
|
118
|
+
"""
|
119
|
+
|
120
|
+
service_name = "sanitize"
|
121
|
+
|
122
|
+
def sanitize(
|
123
|
+
self,
|
124
|
+
transfer_method: TransferMethod = TransferMethod.POST_URL,
|
125
|
+
file_path: Optional[str] = None,
|
126
|
+
file: Optional[io.BufferedReader] = None,
|
127
|
+
source_url: Optional[str] = None,
|
128
|
+
share_id: Optional[str] = None,
|
129
|
+
file_scan: Optional[SanitizeFile] = None,
|
130
|
+
content: Optional[SanitizeContent] = None,
|
131
|
+
share_output: Optional[SanitizeShareOutput] = None,
|
132
|
+
size: Optional[int] = None,
|
133
|
+
crc32c: Optional[str] = None,
|
134
|
+
sha256: Optional[str] = None,
|
135
|
+
uploaded_file_name: Optional[str] = None,
|
136
|
+
sync_call: bool = True,
|
137
|
+
) -> PangeaResponse[SanitizeResult]:
|
138
|
+
"""
|
139
|
+
Sanitize (Beta)
|
140
|
+
|
141
|
+
Apply file sanitization actions according to specified rules.
|
142
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
143
|
+
|
144
|
+
OperationId: sanitize_post_v1beta_sanitize
|
145
|
+
|
146
|
+
Args:
|
147
|
+
transfer_method: The transfer method used to upload the file data.
|
148
|
+
file_path: Path to file to sanitize.
|
149
|
+
file: File to sanitize.
|
150
|
+
source_url: A URL where the file to be sanitized can be downloaded.
|
151
|
+
share_id: A Pangea Secure Share ID where the file to be sanitized is stored.
|
152
|
+
file_scan: Options for File Scan.
|
153
|
+
content: Options for how the file should be sanitized.
|
154
|
+
share_output: Integration with Secure Share.
|
155
|
+
size: The size (in bytes) of the file. If the upload doesn't match, the call will fail.
|
156
|
+
crc32c: The CRC32C hash of the file data, which will be verified by the server if provided.
|
157
|
+
sha256: The hexadecimal-encoded SHA256 hash of the file data, which will be verified by the server if provided.
|
158
|
+
uploaded_file_name: Name of the user-uploaded file, required for `TransferMethod.PUT_URL` and `TransferMethod.POST_URL`.
|
159
|
+
sync_call: Whether or not to poll on HTTP/202.
|
160
|
+
|
161
|
+
Raises:
|
162
|
+
PangeaAPIException: If an API error happens.
|
163
|
+
|
164
|
+
Returns:
|
165
|
+
The sanitized file and information on the sanitization that was
|
166
|
+
performed.
|
167
|
+
|
168
|
+
Examples:
|
169
|
+
with open("/path/to/file.pdf", "rb") as f:
|
170
|
+
response = sanitize.sanitize(
|
171
|
+
file=f,
|
172
|
+
transfer_method=TransferMethod.POST_URL,
|
173
|
+
uploaded_file_name="uploaded_file",
|
174
|
+
)
|
175
|
+
"""
|
176
|
+
|
177
|
+
if file or file_path:
|
178
|
+
if file_path:
|
179
|
+
file = open(file_path, "rb")
|
180
|
+
if transfer_method == TransferMethod.POST_URL and (sha256 is None or crc32c is None or size is None):
|
181
|
+
params = get_file_upload_params(file) # type: ignore[arg-type]
|
182
|
+
crc32c = params.crc_hex if crc32c is None else crc32c
|
183
|
+
sha256 = params.sha256_hex if sha256 is None else sha256
|
184
|
+
size = params.size if size is None else size
|
185
|
+
else:
|
186
|
+
crc32c, sha256, size = None, None, None
|
187
|
+
files: List[Tuple] = [("upload", ("filename", file, "application/octet-stream"))]
|
188
|
+
else:
|
189
|
+
raise ValueError("Need to set file_path or file arguments")
|
190
|
+
|
191
|
+
input = SanitizeRequest(
|
192
|
+
transfer_method=transfer_method,
|
193
|
+
source_url=source_url,
|
194
|
+
share_id=share_id,
|
195
|
+
file=file_scan,
|
196
|
+
content=content,
|
197
|
+
share_output=share_output,
|
198
|
+
crc32c=crc32c,
|
199
|
+
sha256=sha256,
|
200
|
+
size=size,
|
201
|
+
uploaded_file_name=uploaded_file_name,
|
202
|
+
)
|
203
|
+
data = input.dict(exclude_none=True)
|
204
|
+
response = self.request.post("v1beta/sanitize", SanitizeResult, data=data, files=files, poll_result=sync_call)
|
205
|
+
if file_path and file is not None:
|
206
|
+
file.close()
|
207
|
+
return response
|
208
|
+
|
209
|
+
def request_upload_url(
|
210
|
+
self,
|
211
|
+
transfer_method: TransferMethod = TransferMethod.PUT_URL,
|
212
|
+
params: Optional[FileUploadParams] = None,
|
213
|
+
file_scan: Optional[SanitizeFile] = None,
|
214
|
+
content: Optional[SanitizeContent] = None,
|
215
|
+
share_output: Optional[SanitizeShareOutput] = None,
|
216
|
+
size: Optional[int] = None,
|
217
|
+
crc32c: Optional[str] = None,
|
218
|
+
sha256: Optional[str] = None,
|
219
|
+
uploaded_file_name: Optional[str] = None,
|
220
|
+
) -> PangeaResponse[SanitizeResult]:
|
221
|
+
"""
|
222
|
+
Sanitize via presigned URL (Beta)
|
223
|
+
|
224
|
+
Apply file sanitization actions according to specified rules via a
|
225
|
+
[presigned URL](https://pangea.cloud/docs/api/presigned-urls).
|
226
|
+
How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
|
227
|
+
|
228
|
+
OperationId: sanitize_post_v1beta_sanitize 2
|
229
|
+
|
230
|
+
Args:
|
231
|
+
transfer_method: The transfer method used to upload the file data.
|
232
|
+
params: File upload parameters.
|
233
|
+
file_scan: Options for File Scan.
|
234
|
+
content: Options for how the file should be sanitized.
|
235
|
+
share_output: Integration with Secure Share.
|
236
|
+
size: The size (in bytes) of the file. If the upload doesn't match, the call will fail.
|
237
|
+
crc32c: The CRC32C hash of the file data, which will be verified by the server if provided.
|
238
|
+
sha256: The hexadecimal-encoded SHA256 hash of the file data, which will be verified by the server if provided.
|
239
|
+
uploaded_file_name: Name of the user-uploaded file, required for `TransferMethod.PUT_URL` and `TransferMethod.POST_URL`.
|
240
|
+
|
241
|
+
Raises:
|
242
|
+
PangeaAPIException: If an API error happens.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
A presigned URL.
|
246
|
+
|
247
|
+
Examples:
|
248
|
+
presignedUrl = sanitize.request_upload_url(
|
249
|
+
transfer_method=TransferMethod.PUT_URL,
|
250
|
+
uploaded_file_name="uploaded_file",
|
251
|
+
)
|
252
|
+
|
253
|
+
# Upload file to `presignedUrl.accepted_result.put_url`.
|
254
|
+
|
255
|
+
# Poll for Sanitize's result.
|
256
|
+
response: PangeaResponse[SanitizeResult] = sanitize.poll_result(response=presignedUrl)
|
257
|
+
"""
|
258
|
+
|
259
|
+
input = SanitizeRequest(
|
260
|
+
transfer_method=transfer_method,
|
261
|
+
file=file_scan,
|
262
|
+
content=content,
|
263
|
+
share_output=share_output,
|
264
|
+
crc32c=crc32c,
|
265
|
+
sha256=sha256,
|
266
|
+
size=size,
|
267
|
+
uploaded_file_name=uploaded_file_name,
|
268
|
+
)
|
269
|
+
if params is not None and (transfer_method == TransferMethod.POST_URL):
|
270
|
+
input.crc32c = params.crc_hex
|
271
|
+
input.sha256 = params.sha256_hex
|
272
|
+
input.size = params.size
|
273
|
+
|
274
|
+
data = input.dict(exclude_none=True)
|
275
|
+
return self.request.request_presigned_url("v1beta/sanitize", SanitizeResult, data=data)
|