pangea-sdk 4.3.0__py3-none-any.whl → 4.4.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/request.py +9 -8
- pangea/asyncio/services/authz.py +2 -2
- pangea/asyncio/services/intel.py +3 -0
- pangea/services/authz.py +2 -2
- pangea/services/intel.py +5 -0
- pangea/services/sanitize.py +33 -2
- {pangea_sdk-4.3.0.dist-info → pangea_sdk-4.4.0.dist-info}/METADATA +3 -2
- {pangea_sdk-4.3.0.dist-info → pangea_sdk-4.4.0.dist-info}/RECORD +10 -10
- {pangea_sdk-4.3.0.dist-info → pangea_sdk-4.4.0.dist-info}/WHEEL +1 -1
pangea/__init__.py
CHANGED
pangea/asyncio/request.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
3
4
|
|
4
5
|
import asyncio
|
5
6
|
import json
|
6
7
|
import time
|
7
|
-
from typing import Dict, List, Optional, Sequence, Tuple, Type, Union
|
8
|
+
from typing import Any, Dict, List, Optional, Sequence, Tuple, Type, Union
|
8
9
|
|
9
10
|
import aiohttp
|
10
11
|
from aiohttp import FormData
|
@@ -211,13 +212,14 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
211
212
|
else:
|
212
213
|
raise pe.DownloadFileError(f"Failed to download file. Status: {response.status}", await response.text())
|
213
214
|
|
214
|
-
async def _get_pangea_json(self, reader: aiohttp.
|
215
|
+
async def _get_pangea_json(self, reader: aiohttp.multipart.MultipartResponseWrapper) -> Optional[Dict[str, Any]]:
|
215
216
|
# Iterate through parts
|
216
217
|
async for part in reader:
|
217
|
-
|
218
|
+
if isinstance(part, aiohttp.BodyPartReader):
|
219
|
+
return await part.json()
|
218
220
|
return None
|
219
221
|
|
220
|
-
async def _get_attached_files(self, reader: aiohttp.
|
222
|
+
async def _get_attached_files(self, reader: aiohttp.multipart.MultipartResponseWrapper) -> List[AttachedFile]:
|
221
223
|
files = []
|
222
224
|
i = 0
|
223
225
|
|
@@ -228,7 +230,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
228
230
|
if name is None:
|
229
231
|
name = f"default_file_name_{i}"
|
230
232
|
i += 1
|
231
|
-
files.append(AttachedFile(name, await part.read(), content_type))
|
233
|
+
files.append(AttachedFile(name, await part.read(), content_type)) # type: ignore[union-attr]
|
232
234
|
|
233
235
|
return files
|
234
236
|
|
@@ -236,13 +238,12 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
236
238
|
# Parse the multipart response
|
237
239
|
multipart_reader = aiohttp.MultipartReader.from_response(resp)
|
238
240
|
|
239
|
-
pangea_json = await self._get_pangea_json(multipart_reader)
|
241
|
+
pangea_json = await self._get_pangea_json(multipart_reader)
|
240
242
|
self.logger.debug(
|
241
243
|
json.dumps({"service": self.service, "action": "multipart response", "response": pangea_json})
|
242
244
|
)
|
243
245
|
|
244
|
-
|
245
|
-
attached_files = await self._get_attached_files(multipart_reader) # type: ignore[arg-type]
|
246
|
+
attached_files = await self._get_attached_files(multipart_reader)
|
246
247
|
return MultipartResponse(pangea_json, attached_files) # type: ignore[arg-type]
|
247
248
|
|
248
249
|
async def _http_post(
|
pangea/asyncio/services/authz.py
CHANGED
@@ -198,7 +198,7 @@ class AuthZAsync(ServiceBaseAsync):
|
|
198
198
|
async def list_resources(
|
199
199
|
self, type: str, action: str, subject: Subject, attributes: Optional[Dict[str, Any]] = None
|
200
200
|
) -> PangeaResponse[ListResourcesResult]:
|
201
|
-
"""List resources.
|
201
|
+
"""List resources.
|
202
202
|
|
203
203
|
Given a type, action, and subject, list all the resources in the
|
204
204
|
type that the subject has access to the action with.
|
@@ -233,7 +233,7 @@ class AuthZAsync(ServiceBaseAsync):
|
|
233
233
|
async def list_subjects(
|
234
234
|
self, resource: Resource, action: str, attributes: Optional[Dict[str, Any]] = None
|
235
235
|
) -> PangeaResponse[ListSubjectsResult]:
|
236
|
-
"""List subjects.
|
236
|
+
"""List subjects.
|
237
237
|
|
238
238
|
Given a resource and an action, return the list of subjects who have
|
239
239
|
access to the action for the given resource.
|
pangea/asyncio/services/intel.py
CHANGED
@@ -846,6 +846,7 @@ class UserIntelAsync(ServiceBaseAsync):
|
|
846
846
|
usernames: Optional[List[str]] = None,
|
847
847
|
ips: Optional[List[str]] = None,
|
848
848
|
phone_numbers: Optional[List[str]] = None,
|
849
|
+
domains: Optional[List[str]] = None,
|
849
850
|
start: Optional[str] = None,
|
850
851
|
end: Optional[str] = None,
|
851
852
|
verbose: Optional[bool] = None,
|
@@ -864,6 +865,7 @@ class UserIntelAsync(ServiceBaseAsync):
|
|
864
865
|
usernames (List[str]): An username's list to search for
|
865
866
|
ips (List[str]): An ip's list to search for
|
866
867
|
phone_numbers (List[str]): A phone number's list to search for. minLength: 7, maxLength: 15.
|
868
|
+
domains (List[str]): Search for user under these domains.
|
867
869
|
start (str): Earliest date for search
|
868
870
|
end (str): Latest date for search
|
869
871
|
verbose (bool, optional): Echo the API parameters in the response
|
@@ -886,6 +888,7 @@ class UserIntelAsync(ServiceBaseAsync):
|
|
886
888
|
phone_numbers=phone_numbers,
|
887
889
|
usernames=usernames,
|
888
890
|
ips=ips,
|
891
|
+
domains=domains,
|
889
892
|
provider=provider,
|
890
893
|
start=start,
|
891
894
|
end=end,
|
pangea/services/authz.py
CHANGED
@@ -316,7 +316,7 @@ class AuthZ(ServiceBase):
|
|
316
316
|
def list_resources(
|
317
317
|
self, type: str, action: str, subject: Subject, attributes: Optional[Dict[str, Any]] = None
|
318
318
|
) -> PangeaResponse[ListResourcesResult]:
|
319
|
-
"""List resources.
|
319
|
+
"""List resources.
|
320
320
|
|
321
321
|
Given a type, action, and subject, list all the resources in the
|
322
322
|
type that the subject has access to the action with.
|
@@ -351,7 +351,7 @@ class AuthZ(ServiceBase):
|
|
351
351
|
def list_subjects(
|
352
352
|
self, resource: Resource, action: str, attributes: Optional[Dict[str, Any]] = None
|
353
353
|
) -> PangeaResponse[ListSubjectsResult]:
|
354
|
-
"""List subjects.
|
354
|
+
"""List subjects.
|
355
355
|
|
356
356
|
Given a resource and an action, return the list of subjects who have
|
357
357
|
access to the action for the given resource.
|
pangea/services/intel.py
CHANGED
@@ -1255,6 +1255,7 @@ class UserBreachedBulkRequest(IntelCommonRequest):
|
|
1255
1255
|
usernames (List[str]): An username' list to search for
|
1256
1256
|
ips (List[str]): An ip's list to search for
|
1257
1257
|
phone_numbers (List[str]): A phone number's list to search for. minLength: 7, maxLength: 15.
|
1258
|
+
domains (List[str]): Search for user under these domains.
|
1258
1259
|
start (str): Earliest date for search
|
1259
1260
|
end (str): Latest date for search
|
1260
1261
|
"""
|
@@ -1263,6 +1264,7 @@ class UserBreachedBulkRequest(IntelCommonRequest):
|
|
1263
1264
|
usernames: Optional[List[str]] = None
|
1264
1265
|
ips: Optional[List[str]] = None
|
1265
1266
|
phone_numbers: Optional[List[str]] = None
|
1267
|
+
domains: Optional[List[str]] = None
|
1266
1268
|
start: Optional[str] = None
|
1267
1269
|
end: Optional[str] = None
|
1268
1270
|
|
@@ -1439,6 +1441,7 @@ class UserIntel(ServiceBase):
|
|
1439
1441
|
usernames: Optional[List[str]] = None,
|
1440
1442
|
ips: Optional[List[str]] = None,
|
1441
1443
|
phone_numbers: Optional[List[str]] = None,
|
1444
|
+
domains: Optional[List[str]] = None,
|
1442
1445
|
start: Optional[str] = None,
|
1443
1446
|
end: Optional[str] = None,
|
1444
1447
|
verbose: Optional[bool] = None,
|
@@ -1457,6 +1460,7 @@ class UserIntel(ServiceBase):
|
|
1457
1460
|
usernames (List[str]): A list of usernames to search for
|
1458
1461
|
ips (List[str]): A list of ips to search for
|
1459
1462
|
phone_numbers (List[str]): A list of phone numbers to search for. minLength: 7, maxLength: 15.
|
1463
|
+
domains (List[str]): Search for user under these domains.
|
1460
1464
|
start (str): Earliest date for search
|
1461
1465
|
end (str): Latest date for search
|
1462
1466
|
verbose (bool, optional): Echo the API parameters in the response
|
@@ -1484,6 +1488,7 @@ class UserIntel(ServiceBase):
|
|
1484
1488
|
phone_numbers=phone_numbers,
|
1485
1489
|
usernames=usernames,
|
1486
1490
|
ips=ips,
|
1491
|
+
domains=domains,
|
1487
1492
|
provider=provider,
|
1488
1493
|
start=start,
|
1489
1494
|
end=end,
|
pangea/services/sanitize.py
CHANGED
@@ -5,6 +5,8 @@ from __future__ import annotations
|
|
5
5
|
import io
|
6
6
|
from typing import Dict, List, Optional, Tuple
|
7
7
|
|
8
|
+
from pydantic import Field
|
9
|
+
|
8
10
|
from pangea.response import APIRequestModel, PangeaResponse, PangeaResponseResult, TransferMethod
|
9
11
|
from pangea.services.base import ServiceBase
|
10
12
|
from pangea.utils import FileUploadParams, get_file_upload_params
|
@@ -37,6 +39,12 @@ class SanitizeContent(APIRequestModel):
|
|
37
39
|
redact: Optional[bool] = None
|
38
40
|
"""Redact sensitive content."""
|
39
41
|
|
42
|
+
redact_detect_only: Optional[bool] = None
|
43
|
+
"""
|
44
|
+
If redact is enabled, avoids redacting the file and instead returns the PII
|
45
|
+
analysis engine results. Only works if redact is enabled.
|
46
|
+
"""
|
47
|
+
|
40
48
|
remove_attachments: Optional[bool] = None
|
41
49
|
"""Remove file attachments (PDF only)."""
|
42
50
|
|
@@ -104,13 +112,36 @@ class DefangData(PangeaResponseResult):
|
|
104
112
|
"""Processed N Domains: X are malicious, Y are suspicious, Z are unknown."""
|
105
113
|
|
106
114
|
|
115
|
+
class RedactRecognizerResult(PangeaResponseResult):
|
116
|
+
field_type: str
|
117
|
+
"""The entity name."""
|
118
|
+
|
119
|
+
score: float
|
120
|
+
"""The certainty score that the entity matches this specific snippet."""
|
121
|
+
|
122
|
+
text: str
|
123
|
+
"""The text snippet that matched."""
|
124
|
+
|
125
|
+
start: int
|
126
|
+
"""The starting index of a snippet."""
|
127
|
+
|
128
|
+
end: int
|
129
|
+
"""The ending index of a snippet."""
|
130
|
+
|
131
|
+
redacted: bool
|
132
|
+
"""Indicates if this rule was used to anonymize a text snippet."""
|
133
|
+
|
134
|
+
|
107
135
|
class RedactData(PangeaResponseResult):
|
108
|
-
redaction_count:
|
136
|
+
redaction_count: int
|
109
137
|
"""Number of items redacted"""
|
110
138
|
|
111
|
-
summary_counts: Dict =
|
139
|
+
summary_counts: Dict[str, int] = Field(default_factory=dict)
|
112
140
|
"""Summary counts."""
|
113
141
|
|
142
|
+
recognizer_results: Optional[List[RedactRecognizerResult]] = None
|
143
|
+
"""The scoring result of a set of rules."""
|
144
|
+
|
114
145
|
|
115
146
|
class CDR(PangeaResponseResult):
|
116
147
|
file_attachments_removed: Optional[int] = None
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pangea-sdk
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.4.0
|
4
4
|
Summary: Pangea API SDK
|
5
5
|
Home-page: https://pangea.cloud/docs/sdk/python/
|
6
6
|
License: MIT
|
@@ -15,9 +15,10 @@ Classifier: Programming Language :: Python :: 3.9
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
18
19
|
Classifier: Topic :: Software Development
|
19
20
|
Classifier: Topic :: Software Development :: Libraries
|
20
|
-
Requires-Dist: aiohttp (>=3.10.
|
21
|
+
Requires-Dist: aiohttp (>=3.10.10,<4.0.0)
|
21
22
|
Requires-Dist: cryptography (>=43.0.1,<44.0.0)
|
22
23
|
Requires-Dist: deprecated (>=1.2.14,<2.0.0)
|
23
24
|
Requires-Dist: google-crc32c (>=1.5.0,<2.0.0)
|
@@ -1,15 +1,15 @@
|
|
1
|
-
pangea/__init__.py,sha256=
|
1
|
+
pangea/__init__.py,sha256=v6ZDmf842vyF60xDR-QFmFgqOrACNjTFpxIBQcx3gFc,246
|
2
2
|
pangea/asyncio/__init__.py,sha256=kjEMkqMQ521LlMSu5jn3_WgweyArwVZ2C-s3x7mR6Pk,45
|
3
3
|
pangea/asyncio/file_uploader.py,sha256=wI7epib7Rc5jtZw4eJ1L1SlmutDG6CPv59C8N2UPhtY,1436
|
4
|
-
pangea/asyncio/request.py,sha256=
|
4
|
+
pangea/asyncio/request.py,sha256=KMfQYC027EBeyYyMlvnDtjxbpaRj9xubeqAdpot3F3U,17168
|
5
5
|
pangea/asyncio/services/__init__.py,sha256=hMeTMnksGimg-fS_XMpRgh02a7BNcLYCt56tnChYeC4,356
|
6
6
|
pangea/asyncio/services/audit.py,sha256=bZ7gdkVWkzqLqUVc1Wnf3oDAaCLg97-zTWhY8UdX0_Y,26549
|
7
7
|
pangea/asyncio/services/authn.py,sha256=rPeLJweL8mYH_t4ebcQn4n_Wglr3kClKNnCXNCimZU4,46622
|
8
|
-
pangea/asyncio/services/authz.py,sha256=
|
8
|
+
pangea/asyncio/services/authz.py,sha256=HgW9R8DeW19wS7fpgq0NWOx41wZWcn6NYS4NMbi8p1A,9482
|
9
9
|
pangea/asyncio/services/base.py,sha256=4FtKtlq74NmE9myrgIt9HMA6JDnP4mPZ6krafWr286o,2663
|
10
10
|
pangea/asyncio/services/embargo.py,sha256=ctzj3kip6xos-Eu3JuOskrCGYC8T3JlsgAopZHiPSXM,3068
|
11
11
|
pangea/asyncio/services/file_scan.py,sha256=PLG1O-PL4Yk9uY9D6NbMrZ5LHg70Z311s7bFe46UMZA,7108
|
12
|
-
pangea/asyncio/services/intel.py,sha256=
|
12
|
+
pangea/asyncio/services/intel.py,sha256=cCm3VwWxUzEUCNhuPCeejJvr4uOeLXuYDbDwTzNG6Aw,38121
|
13
13
|
pangea/asyncio/services/redact.py,sha256=jRNtXr_DZ_cY7guhut-eZmOEhy2uN_VCXrjGH6bkh74,7265
|
14
14
|
pangea/asyncio/services/sanitize.py,sha256=bf98J-s-P51oSKqNBgR0wj5mlHOCBwpjWz7k0NdXCKQ,7899
|
15
15
|
pangea/asyncio/services/vault.py,sha256=gFch7dVFZzjcTryn68AR4Xbj37U4A_LxfCMrX2mhtSk,53271
|
@@ -32,13 +32,13 @@ pangea/services/audit/signing.py,sha256=EYuZN6pcFOjDJBG6S65jesE_8xOz5SNms6qHZ1qa
|
|
32
32
|
pangea/services/audit/util.py,sha256=Zq1qvfeplYfhCP_ud5YMvntSB0UvnCdsuYbOzZkHbjg,7620
|
33
33
|
pangea/services/authn/authn.py,sha256=cZKl2Ixc6HwHnkRecpSaAGTQUgaZUtxfLa0T3S03HMs,45478
|
34
34
|
pangea/services/authn/models.py,sha256=HH5su6jx3O9AwVGzASXZ99-eIWjgXEP5LhIVdewM13s,22394
|
35
|
-
pangea/services/authz.py,sha256=
|
35
|
+
pangea/services/authz.py,sha256=HfDnovAokzAHvnjYdOCwceM-1sCmzODnjNEbQBUSfo8,12222
|
36
36
|
pangea/services/base.py,sha256=lwhHoe5Juy28Ir3Mfj2lHdM58gxZRaxa2SRFi4_DBRw,3453
|
37
37
|
pangea/services/embargo.py,sha256=9Wfku4td5ORaIENKmnGmS5jxJJIRfWp6Q51L36Jsy0I,3897
|
38
38
|
pangea/services/file_scan.py,sha256=QiO80uKqB_BnAOiYQKznXfxpa5j40qqETE3-zBRT_QE,7813
|
39
|
-
pangea/services/intel.py,sha256=
|
39
|
+
pangea/services/intel.py,sha256=CziBhC5K6O_kBXpD8zgJLpDtLHzBRgATGW4gHHFJT48,52039
|
40
40
|
pangea/services/redact.py,sha256=ZYXkzEoriLJyCqaj5dqmgsC56mIz4T3pPToZ7TcNfhg,11465
|
41
|
-
pangea/services/sanitize.py,sha256=
|
41
|
+
pangea/services/sanitize.py,sha256=XP5D4CcbCZfzgU567X6H5eFBWwZuYSsHdvsdrQAZekY,12767
|
42
42
|
pangea/services/vault/models/asymmetric.py,sha256=xr8oZnjzExMYcbzPJRG3xPXSmhumKDKn7RO90RvdrwU,1526
|
43
43
|
pangea/services/vault/models/common.py,sha256=FOmi2UN5cEgSsrM-aDT1KWLK4TTgrtMukqNczrnWH6w,15491
|
44
44
|
pangea/services/vault/models/secret.py,sha256=cLgEj-_BeGkB4-pmSeTkWVyasFbaJwcEltIEcOyf1U8,481
|
@@ -47,6 +47,6 @@ pangea/services/vault/vault.py,sha256=pv52dpZM0yicdtNra0Yd4AdkWUZC91Yk4rATthu1bs
|
|
47
47
|
pangea/tools.py,sha256=sa2pSz-L8tB6GcZg6lghsmm8w0qMQAIkzqcv7dilU6Q,6429
|
48
48
|
pangea/utils.py,sha256=pMSwL8B-owtrjeWYRjxuyaTQN4V-HsCT669KtOLU3Sw,3195
|
49
49
|
pangea/verify_audit.py,sha256=rvni5akz_P2kYLAGAeA1A5gY6XGpXpAQpbIa7V1PoRY,17458
|
50
|
-
pangea_sdk-4.
|
51
|
-
pangea_sdk-4.
|
52
|
-
pangea_sdk-4.
|
50
|
+
pangea_sdk-4.4.0.dist-info/METADATA,sha256=Pdac62iEWB9wChXMZrR2saCrBMXnsLuWJlhIx6ovA44,7545
|
51
|
+
pangea_sdk-4.4.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
52
|
+
pangea_sdk-4.4.0.dist-info/RECORD,,
|