pangea-sdk 3.8.0b1__py3-none-any.whl → 5.3.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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/intel.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
import enum
|
4
6
|
import hashlib
|
5
7
|
from typing import Dict, List, Optional
|
@@ -524,7 +526,7 @@ class FileIntel(ServiceBase):
|
|
524
526
|
)
|
525
527
|
"""
|
526
528
|
input = FileReputationRequest(hash=hash, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider)
|
527
|
-
return self.request.post("v1/reputation", FileReputationResult, data=input.
|
529
|
+
return self.request.post("v1/reputation", FileReputationResult, data=input.model_dump(exclude_none=True))
|
528
530
|
|
529
531
|
def hash_reputation_bulk(
|
530
532
|
self,
|
@@ -563,7 +565,7 @@ class FileIntel(ServiceBase):
|
|
563
565
|
input = FileReputationBulkRequest( # type: ignore[call-arg]
|
564
566
|
hashes=hashes, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider
|
565
567
|
)
|
566
|
-
return self.request.post("v2/reputation", FileReputationBulkResult, data=input.
|
568
|
+
return self.request.post("v2/reputation", FileReputationBulkResult, data=input.model_dump(exclude_none=True))
|
567
569
|
|
568
570
|
def filepath_reputation(
|
569
571
|
self,
|
@@ -708,7 +710,7 @@ class DomainIntel(ServiceBase):
|
|
708
710
|
)
|
709
711
|
"""
|
710
712
|
input = DomainReputationRequest(domain=domain, verbose=verbose, provider=provider, raw=raw)
|
711
|
-
return self.request.post("v1/reputation", DomainReputationResult, data=input.
|
713
|
+
return self.request.post("v1/reputation", DomainReputationResult, data=input.model_dump(exclude_none=True))
|
712
714
|
|
713
715
|
def reputation_bulk(
|
714
716
|
self,
|
@@ -744,7 +746,7 @@ class DomainIntel(ServiceBase):
|
|
744
746
|
)
|
745
747
|
"""
|
746
748
|
input = DomainReputationBulkRequest(domains=domains, verbose=verbose, provider=provider, raw=raw)
|
747
|
-
return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.
|
749
|
+
return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.model_dump(exclude_none=True))
|
748
750
|
|
749
751
|
def who_is(
|
750
752
|
self, domain: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -776,7 +778,7 @@ class DomainIntel(ServiceBase):
|
|
776
778
|
)
|
777
779
|
"""
|
778
780
|
input = DomainWhoIsRequest(domain=domain, verbose=verbose, provider=provider, raw=raw) # type: ignore[call-arg]
|
779
|
-
return self.request.post("v1/whois", DomainWhoIsResult, data=input.
|
781
|
+
return self.request.post("v1/whois", DomainWhoIsResult, data=input.model_dump(exclude_none=True))
|
780
782
|
|
781
783
|
|
782
784
|
class IpIntel(ServiceBase):
|
@@ -819,7 +821,7 @@ class IpIntel(ServiceBase):
|
|
819
821
|
ip (str): The IP to be looked up
|
820
822
|
verbose (bool, optional): Echo the API parameters in the response
|
821
823
|
raw (bool, optional): Include raw data from this provider
|
822
|
-
provider (str, optional): Use reputation data from this provider
|
824
|
+
provider (str, optional): Use reputation data from this provider
|
823
825
|
|
824
826
|
Raises:
|
825
827
|
PangeaAPIException: If an API Error happens
|
@@ -835,11 +837,11 @@ class IpIntel(ServiceBase):
|
|
835
837
|
)
|
836
838
|
"""
|
837
839
|
input = IPReputationRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
838
|
-
return self.request.post("v1/reputation", IPReputationResult, data=input.
|
840
|
+
return self.request.post("v1/reputation", IPReputationResult, data=input.model_dump(exclude_none=True))
|
839
841
|
|
840
842
|
def reputation_bulk(
|
841
843
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
842
|
-
) -> PangeaResponse[
|
844
|
+
) -> PangeaResponse[IPReputationBulkResult]:
|
843
845
|
"""
|
844
846
|
Reputation V2
|
845
847
|
|
@@ -851,7 +853,7 @@ class IpIntel(ServiceBase):
|
|
851
853
|
ips (List[str]): The IP list to be looked up
|
852
854
|
verbose (bool, optional): Echo the API parameters in the response
|
853
855
|
raw (bool, optional): Include raw data from this provider
|
854
|
-
provider (str, optional): Use reputation data from this provider
|
856
|
+
provider (str, optional): Use reputation data from this provider
|
855
857
|
|
856
858
|
Raises:
|
857
859
|
PangeaAPIException: If an API Error happens
|
@@ -867,7 +869,7 @@ class IpIntel(ServiceBase):
|
|
867
869
|
)
|
868
870
|
"""
|
869
871
|
input = IPReputationBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
870
|
-
return self.request.post("v2/reputation", IPReputationBulkResult, data=input.
|
872
|
+
return self.request.post("v2/reputation", IPReputationBulkResult, data=input.model_dump(exclude_none=True))
|
871
873
|
|
872
874
|
def geolocate(
|
873
875
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -899,7 +901,7 @@ class IpIntel(ServiceBase):
|
|
899
901
|
)
|
900
902
|
"""
|
901
903
|
input = IPGeolocateRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
902
|
-
return self.request.post("v1/geolocate", IPGeolocateResult, data=input.
|
904
|
+
return self.request.post("v1/geolocate", IPGeolocateResult, data=input.model_dump(exclude_none=True))
|
903
905
|
|
904
906
|
def geolocate_bulk(
|
905
907
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -931,7 +933,7 @@ class IpIntel(ServiceBase):
|
|
931
933
|
)
|
932
934
|
"""
|
933
935
|
input = IPGeolocateBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
934
|
-
return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.
|
936
|
+
return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.model_dump(exclude_none=True))
|
935
937
|
|
936
938
|
def get_domain(
|
937
939
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -963,7 +965,7 @@ class IpIntel(ServiceBase):
|
|
963
965
|
)
|
964
966
|
"""
|
965
967
|
input = IPDomainRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
966
|
-
return self.request.post("v1/domain", IPDomainResult, data=input.
|
968
|
+
return self.request.post("v1/domain", IPDomainResult, data=input.model_dump(exclude_none=True))
|
967
969
|
|
968
970
|
def get_domain_bulk(
|
969
971
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -995,7 +997,7 @@ class IpIntel(ServiceBase):
|
|
995
997
|
)
|
996
998
|
"""
|
997
999
|
input = IPDomainBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
998
|
-
return self.request.post("v2/domain", IPDomainBulkResult, data=input.
|
1000
|
+
return self.request.post("v2/domain", IPDomainBulkResult, data=input.model_dump(exclude_none=True))
|
999
1001
|
|
1000
1002
|
def is_vpn(
|
1001
1003
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1027,7 +1029,7 @@ class IpIntel(ServiceBase):
|
|
1027
1029
|
)
|
1028
1030
|
"""
|
1029
1031
|
input = IPVPNRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
1030
|
-
return self.request.post("v1/vpn", IPVPNResult, data=input.
|
1032
|
+
return self.request.post("v1/vpn", IPVPNResult, data=input.model_dump(exclude_none=True))
|
1031
1033
|
|
1032
1034
|
def is_vpn_bulk(
|
1033
1035
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1059,7 +1061,7 @@ class IpIntel(ServiceBase):
|
|
1059
1061
|
)
|
1060
1062
|
"""
|
1061
1063
|
input = IPVPNBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
1062
|
-
return self.request.post("v2/vpn", IPVPNBulkResult, data=input.
|
1064
|
+
return self.request.post("v2/vpn", IPVPNBulkResult, data=input.model_dump(exclude_none=True))
|
1063
1065
|
|
1064
1066
|
def is_proxy(
|
1065
1067
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1091,7 +1093,7 @@ class IpIntel(ServiceBase):
|
|
1091
1093
|
)
|
1092
1094
|
"""
|
1093
1095
|
input = IPProxyRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
1094
|
-
return self.request.post("v1/proxy", IPProxyResult, data=input.
|
1096
|
+
return self.request.post("v1/proxy", IPProxyResult, data=input.model_dump(exclude_none=True))
|
1095
1097
|
|
1096
1098
|
def is_proxy_bulk(
|
1097
1099
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1123,7 +1125,7 @@ class IpIntel(ServiceBase):
|
|
1123
1125
|
)
|
1124
1126
|
"""
|
1125
1127
|
input = IPProxyBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
1126
|
-
return self.request.post("v2/proxy", IPProxyBulkResult, data=input.
|
1128
|
+
return self.request.post("v2/proxy", IPProxyBulkResult, data=input.model_dump(exclude_none=True))
|
1127
1129
|
|
1128
1130
|
|
1129
1131
|
class UrlIntel(ServiceBase):
|
@@ -1170,7 +1172,7 @@ class UrlIntel(ServiceBase):
|
|
1170
1172
|
url (str): The URL to be looked up
|
1171
1173
|
verbose (bool, optional): Echo the API parameters in the response
|
1172
1174
|
raw (bool, optional): Include raw data from this provider
|
1173
|
-
provider (str, optional): Use reputation data from this provider
|
1175
|
+
provider (str, optional): Use reputation data from this provider
|
1174
1176
|
|
1175
1177
|
Raises:
|
1176
1178
|
PangeaAPIException: If an API Error happens
|
@@ -1187,7 +1189,7 @@ class UrlIntel(ServiceBase):
|
|
1187
1189
|
"""
|
1188
1190
|
|
1189
1191
|
input = URLReputationRequest(url=url, provider=provider, verbose=verbose, raw=raw)
|
1190
|
-
return self.request.post("v1/reputation", URLReputationResult, data=input.
|
1192
|
+
return self.request.post("v1/reputation", URLReputationResult, data=input.model_dump(exclude_none=True))
|
1191
1193
|
|
1192
1194
|
def reputation_bulk(
|
1193
1195
|
self,
|
@@ -1195,7 +1197,7 @@ class UrlIntel(ServiceBase):
|
|
1195
1197
|
verbose: Optional[bool] = None,
|
1196
1198
|
raw: Optional[bool] = None,
|
1197
1199
|
provider: Optional[str] = None,
|
1198
|
-
) -> PangeaResponse[
|
1200
|
+
) -> PangeaResponse[URLReputationBulkResult]:
|
1199
1201
|
"""
|
1200
1202
|
Reputation V2
|
1201
1203
|
|
@@ -1207,7 +1209,7 @@ class UrlIntel(ServiceBase):
|
|
1207
1209
|
urls (List[str]): The URL list to be looked up
|
1208
1210
|
verbose (bool, optional): Echo the API parameters in the response
|
1209
1211
|
raw (bool, optional): Include raw data from this provider
|
1210
|
-
provider (str, optional): Use reputation data from this provider
|
1212
|
+
provider (str, optional): Use reputation data from this provider
|
1211
1213
|
|
1212
1214
|
Raises:
|
1213
1215
|
PangeaAPIException: If an API Error happens
|
@@ -1224,7 +1226,7 @@ class UrlIntel(ServiceBase):
|
|
1224
1226
|
"""
|
1225
1227
|
|
1226
1228
|
input = URLReputationBulkRequest(urls=urls, provider=provider, verbose=verbose, raw=raw)
|
1227
|
-
return self.request.post("v2/reputation", URLReputationBulkResult, data=input.
|
1229
|
+
return self.request.post("v2/reputation", URLReputationBulkResult, data=input.model_dump(exclude_none=True))
|
1228
1230
|
|
1229
1231
|
|
1230
1232
|
class UserBreachedRequest(IntelCommonRequest):
|
@@ -1237,6 +1239,7 @@ class UserBreachedRequest(IntelCommonRequest):
|
|
1237
1239
|
phone_number (str): A phone number to search for. minLength: 7, maxLength: 15.
|
1238
1240
|
start (str): Earliest date for search
|
1239
1241
|
end (str): Latest date for search
|
1242
|
+
cursor (str, optional): A token given in the raw response from SpyCloud. Post this back to paginate results
|
1240
1243
|
"""
|
1241
1244
|
|
1242
1245
|
email: Optional[str] = None
|
@@ -1245,6 +1248,10 @@ class UserBreachedRequest(IntelCommonRequest):
|
|
1245
1248
|
phone_number: Optional[str] = None
|
1246
1249
|
start: Optional[str] = None
|
1247
1250
|
end: Optional[str] = None
|
1251
|
+
cursor: Optional[str] = None
|
1252
|
+
|
1253
|
+
severity: Optional[List[int]] = None
|
1254
|
+
"""Filter for records that match one of the given severities"""
|
1248
1255
|
|
1249
1256
|
|
1250
1257
|
class UserBreachedBulkRequest(IntelCommonRequest):
|
@@ -1255,6 +1262,7 @@ class UserBreachedBulkRequest(IntelCommonRequest):
|
|
1255
1262
|
usernames (List[str]): An username' list to search for
|
1256
1263
|
ips (List[str]): An ip's list to search for
|
1257
1264
|
phone_numbers (List[str]): A phone number's list to search for. minLength: 7, maxLength: 15.
|
1265
|
+
domains (List[str]): Search for user under these domains.
|
1258
1266
|
start (str): Earliest date for search
|
1259
1267
|
end (str): Latest date for search
|
1260
1268
|
"""
|
@@ -1263,9 +1271,13 @@ class UserBreachedBulkRequest(IntelCommonRequest):
|
|
1263
1271
|
usernames: Optional[List[str]] = None
|
1264
1272
|
ips: Optional[List[str]] = None
|
1265
1273
|
phone_numbers: Optional[List[str]] = None
|
1274
|
+
domains: Optional[List[str]] = None
|
1266
1275
|
start: Optional[str] = None
|
1267
1276
|
end: Optional[str] = None
|
1268
1277
|
|
1278
|
+
severity: Optional[List[int]] = None
|
1279
|
+
"""Filter for records that match one of the given severities"""
|
1280
|
+
|
1269
1281
|
|
1270
1282
|
class UserBreachedCommonData(PangeaResponseResult):
|
1271
1283
|
"""
|
@@ -1314,7 +1326,7 @@ class UserPasswordBreachedRequest(IntelCommonRequest):
|
|
1314
1326
|
|
1315
1327
|
class UserPasswordBreachedBulkRequest(IntelCommonRequest):
|
1316
1328
|
"""
|
1317
|
-
User password breached
|
1329
|
+
User password breached bulk request data
|
1318
1330
|
|
1319
1331
|
hash_type (str): Hash type to be looked up
|
1320
1332
|
hash_prefixes (List[str]): The list of prefixes of the hashes to be looked up.
|
@@ -1348,6 +1360,44 @@ class UserPasswordBreachedBulkResult(IntelCommonResult):
|
|
1348
1360
|
data: Dict[str, UserPasswordBreachedData]
|
1349
1361
|
|
1350
1362
|
|
1363
|
+
class BreachRequest(APIRequestModel):
|
1364
|
+
"""Breach request data"""
|
1365
|
+
|
1366
|
+
breach_id: Optional[str] = None
|
1367
|
+
"""The ID of a breach returned by a provider."""
|
1368
|
+
|
1369
|
+
verbose: Optional[bool] = None
|
1370
|
+
"""Echo back the parameters of the API in the response."""
|
1371
|
+
|
1372
|
+
provider: Optional[str] = None
|
1373
|
+
"""Provider of the information. Default provider defined by the configuration."""
|
1374
|
+
|
1375
|
+
severity: Optional[List[int]] = None
|
1376
|
+
"""Filter for records that match one of the given severities"""
|
1377
|
+
|
1378
|
+
start: Optional[str] = None
|
1379
|
+
"""This parameter allows you to define the starting point for a date range query on the spycloud_publish_date field."""
|
1380
|
+
|
1381
|
+
end: Optional[str] = None
|
1382
|
+
"""This parameter allows you to define the ending point for a date range query on the spycloud_publish_date field."""
|
1383
|
+
|
1384
|
+
cursor: Optional[str] = None
|
1385
|
+
"""A token given in the raw response from SpyCloud. Post this back to paginate results"""
|
1386
|
+
|
1387
|
+
|
1388
|
+
class BreachResult(PangeaResponseResult):
|
1389
|
+
"""Breach result"""
|
1390
|
+
|
1391
|
+
found: bool
|
1392
|
+
"""A flag indicating if the lookup was successful."""
|
1393
|
+
|
1394
|
+
data: Optional[Dict] = None
|
1395
|
+
"""Breach details given by the provider."""
|
1396
|
+
|
1397
|
+
parameters: Optional[Dict] = None
|
1398
|
+
"""The parameters, which were passed in the request, echoed back."""
|
1399
|
+
|
1400
|
+
|
1351
1401
|
class UserIntel(ServiceBase):
|
1352
1402
|
"""User Intel service client.
|
1353
1403
|
|
@@ -1385,6 +1435,8 @@ class UserIntel(ServiceBase):
|
|
1385
1435
|
verbose: Optional[bool] = None,
|
1386
1436
|
raw: Optional[bool] = None,
|
1387
1437
|
provider: Optional[str] = None,
|
1438
|
+
cursor: Optional[str] = None,
|
1439
|
+
severity: Optional[List[int]] = None,
|
1388
1440
|
) -> PangeaResponse[UserBreachedResult]:
|
1389
1441
|
"""
|
1390
1442
|
Look up breached users
|
@@ -1402,7 +1454,9 @@ class UserIntel(ServiceBase):
|
|
1402
1454
|
end (str): Latest date for search
|
1403
1455
|
verbose (bool, optional): Echo the API parameters in the response
|
1404
1456
|
raw (bool, optional): Include raw data from this provider
|
1405
|
-
provider (str, optional): Use reputation data from this provider
|
1457
|
+
provider (str, optional): Use reputation data from this provider
|
1458
|
+
cursor (str, optional): A token given in the raw response from SpyCloud. Post this back to paginate results
|
1459
|
+
severity (List[int], optional): Filter for records that match one of the given severities
|
1406
1460
|
|
1407
1461
|
Raises:
|
1408
1462
|
PangeaAPIException: If an API Error happens
|
@@ -1430,8 +1484,10 @@ class UserIntel(ServiceBase):
|
|
1430
1484
|
end=end,
|
1431
1485
|
verbose=verbose,
|
1432
1486
|
raw=raw,
|
1487
|
+
cursor=cursor,
|
1488
|
+
severity=severity,
|
1433
1489
|
)
|
1434
|
-
return self.request.post("v1/user/breached", UserBreachedResult, data=input.
|
1490
|
+
return self.request.post("v1/user/breached", UserBreachedResult, data=input.model_dump(exclude_none=True))
|
1435
1491
|
|
1436
1492
|
def user_breached_bulk(
|
1437
1493
|
self,
|
@@ -1439,11 +1495,13 @@ class UserIntel(ServiceBase):
|
|
1439
1495
|
usernames: Optional[List[str]] = None,
|
1440
1496
|
ips: Optional[List[str]] = None,
|
1441
1497
|
phone_numbers: Optional[List[str]] = None,
|
1498
|
+
domains: Optional[List[str]] = None,
|
1442
1499
|
start: Optional[str] = None,
|
1443
1500
|
end: Optional[str] = None,
|
1444
1501
|
verbose: Optional[bool] = None,
|
1445
1502
|
raw: Optional[bool] = None,
|
1446
1503
|
provider: Optional[str] = None,
|
1504
|
+
severity: Optional[List[int]] = None,
|
1447
1505
|
) -> PangeaResponse[UserBreachedBulkResult]:
|
1448
1506
|
"""
|
1449
1507
|
Look up breached users V2
|
@@ -1457,11 +1515,13 @@ class UserIntel(ServiceBase):
|
|
1457
1515
|
usernames (List[str]): A list of usernames to search for
|
1458
1516
|
ips (List[str]): A list of ips to search for
|
1459
1517
|
phone_numbers (List[str]): A list of phone numbers to search for. minLength: 7, maxLength: 15.
|
1518
|
+
domains (List[str]): Search for user under these domains.
|
1460
1519
|
start (str): Earliest date for search
|
1461
1520
|
end (str): Latest date for search
|
1462
1521
|
verbose (bool, optional): Echo the API parameters in the response
|
1463
1522
|
raw (bool, optional): Include raw data from this provider
|
1464
|
-
provider (str, optional): Use reputation data from this provider
|
1523
|
+
provider (str, optional): Use reputation data from this provider
|
1524
|
+
severity (List[int], optional): Filter for records that match one of the given severities
|
1465
1525
|
|
1466
1526
|
Raises:
|
1467
1527
|
PangeaAPIException: If an API Error happens
|
@@ -1484,13 +1544,15 @@ class UserIntel(ServiceBase):
|
|
1484
1544
|
phone_numbers=phone_numbers,
|
1485
1545
|
usernames=usernames,
|
1486
1546
|
ips=ips,
|
1547
|
+
domains=domains,
|
1487
1548
|
provider=provider,
|
1488
1549
|
start=start,
|
1489
1550
|
end=end,
|
1490
1551
|
verbose=verbose,
|
1491
1552
|
raw=raw,
|
1553
|
+
severity=severity,
|
1492
1554
|
)
|
1493
|
-
return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.
|
1555
|
+
return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.model_dump(exclude_none=True))
|
1494
1556
|
|
1495
1557
|
def password_breached(
|
1496
1558
|
self,
|
@@ -1512,7 +1574,7 @@ class UserIntel(ServiceBase):
|
|
1512
1574
|
hash_prefix (str): The prefix of the hash to be looked up.
|
1513
1575
|
verbose (bool, optional): Echo the API parameters in the response
|
1514
1576
|
raw (bool, optional): Include raw data from this provider
|
1515
|
-
provider (str, optional): Use reputation data from this provider
|
1577
|
+
provider (str, optional): Use reputation data from this provider
|
1516
1578
|
|
1517
1579
|
Raises:
|
1518
1580
|
PangeaAPIException: If an API Error happens
|
@@ -1532,7 +1594,9 @@ class UserIntel(ServiceBase):
|
|
1532
1594
|
input = UserPasswordBreachedRequest(
|
1533
1595
|
hash_type=hash_type, hash_prefix=hash_prefix, provider=provider, verbose=verbose, raw=raw
|
1534
1596
|
)
|
1535
|
-
return self.request.post(
|
1597
|
+
return self.request.post(
|
1598
|
+
"v1/password/breached", UserPasswordBreachedResult, data=input.model_dump(exclude_none=True)
|
1599
|
+
)
|
1536
1600
|
|
1537
1601
|
def password_breached_bulk(
|
1538
1602
|
self,
|
@@ -1554,7 +1618,7 @@ class UserIntel(ServiceBase):
|
|
1554
1618
|
hash_prefixes (List[str]): The list of prefixes of the hashes to be looked up.
|
1555
1619
|
verbose (bool, optional): Echo the API parameters in the response
|
1556
1620
|
raw (bool, optional): Include raw data from this provider
|
1557
|
-
provider (str, optional): Use reputation data from this provider
|
1621
|
+
provider (str, optional): Use reputation data from this provider
|
1558
1622
|
|
1559
1623
|
Raises:
|
1560
1624
|
PangeaAPIException: If an API Error happens
|
@@ -1575,9 +1639,59 @@ class UserIntel(ServiceBase):
|
|
1575
1639
|
hash_type=hash_type, hash_prefixes=hash_prefixes, provider=provider, verbose=verbose, raw=raw
|
1576
1640
|
)
|
1577
1641
|
return self.request.post(
|
1578
|
-
"v2/password/breached", UserPasswordBreachedBulkResult, data=input.
|
1642
|
+
"v2/password/breached", UserPasswordBreachedBulkResult, data=input.model_dump(exclude_none=True)
|
1579
1643
|
)
|
1580
1644
|
|
1645
|
+
def breach(
|
1646
|
+
self,
|
1647
|
+
breach_id: Optional[str] = None,
|
1648
|
+
verbose: Optional[bool] = None,
|
1649
|
+
provider: Optional[str] = None,
|
1650
|
+
cursor: Optional[str] = None,
|
1651
|
+
start: Optional[str] = None,
|
1652
|
+
end: Optional[str] = None,
|
1653
|
+
severity: Optional[List[int]] = None,
|
1654
|
+
) -> PangeaResponse[BreachResult]:
|
1655
|
+
"""
|
1656
|
+
Look up information about a specific breach
|
1657
|
+
|
1658
|
+
Given a provider specific breach ID, find details about the breach.
|
1659
|
+
|
1660
|
+
OperationId: user_intel_post_v1_breach
|
1661
|
+
|
1662
|
+
Args:
|
1663
|
+
breach_id (str, optional): The ID of a breach returned by a provider
|
1664
|
+
verbose (bool, optional): Echo the API parameters in the response
|
1665
|
+
provider (str, optional): Use reputation data from this provider
|
1666
|
+
cursor (str, optional): A token given in the raw response from SpyCloud. Post this back to paginate results
|
1667
|
+
start (str, optional): This parameter allows you to define the starting point for a date range query on the spycloud_publish_date field
|
1668
|
+
end (str, optional): This parameter allows you to define the ending point for a date range query on the spycloud_publish_date field
|
1669
|
+
severity (List[int], optional): Filter for records that match one of the given severities
|
1670
|
+
|
1671
|
+
Raises:
|
1672
|
+
PangeaAPIException: If an API Error happens
|
1673
|
+
|
1674
|
+
Returns:
|
1675
|
+
A PangeaResponse where the breach details are in the
|
1676
|
+
response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/user-intel)
|
1677
|
+
|
1678
|
+
Examples:
|
1679
|
+
response = user_intel.breach(
|
1680
|
+
breach_id="66111",
|
1681
|
+
)
|
1682
|
+
"""
|
1683
|
+
|
1684
|
+
input = BreachRequest(
|
1685
|
+
breach_id=breach_id,
|
1686
|
+
provider=provider,
|
1687
|
+
verbose=verbose,
|
1688
|
+
cursor=cursor,
|
1689
|
+
start=start,
|
1690
|
+
end=end,
|
1691
|
+
severity=severity,
|
1692
|
+
)
|
1693
|
+
return self.request.post("v1/breach", BreachResult, data=input.model_dump(exclude_none=True))
|
1694
|
+
|
1581
1695
|
class PasswordStatus(enum.Enum):
|
1582
1696
|
BREACHED = 0
|
1583
1697
|
UNBREACHED = 1
|
@@ -1585,6 +1699,17 @@ class UserIntel(ServiceBase):
|
|
1585
1699
|
|
1586
1700
|
@staticmethod
|
1587
1701
|
def is_password_breached(response: PangeaResponse[UserBreachedResult], hash: str) -> PasswordStatus:
|
1702
|
+
"""
|
1703
|
+
Check if a password was breached
|
1704
|
+
|
1705
|
+
Helper function that simplifies searching the response's raw data for
|
1706
|
+
the full hash.
|
1707
|
+
|
1708
|
+
Args:
|
1709
|
+
response: API response from an earlier request
|
1710
|
+
hash: Password hash
|
1711
|
+
"""
|
1712
|
+
|
1588
1713
|
if response.result.raw_data is None: # type: ignore[union-attr]
|
1589
1714
|
raise PangeaException("Need raw data to check if hash is breached. Send request with raw=true")
|
1590
1715
|
|