pangea-sdk 3.9.0__py3-none-any.whl → 4.0.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 +4 -4
- pangea/asyncio/services/audit.py +30 -11
- pangea/asyncio/services/authn.py +49 -29
- pangea/asyncio/services/authz.py +13 -7
- pangea/asyncio/services/embargo.py +2 -2
- pangea/asyncio/services/file_scan.py +3 -3
- pangea/asyncio/services/intel.py +40 -22
- pangea/asyncio/services/redact.py +5 -3
- pangea/asyncio/services/vault.py +32 -28
- pangea/dump_audit.py +1 -1
- pangea/request.py +8 -5
- pangea/response.py +9 -16
- pangea/services/audit/audit.py +43 -20
- pangea/services/audit/models.py +3 -3
- pangea/services/audit/util.py +3 -3
- pangea/services/authn/authn.py +39 -29
- pangea/services/authn/models.py +9 -4
- pangea/services/authz.py +10 -8
- pangea/services/embargo.py +2 -2
- pangea/services/file_scan.py +2 -2
- pangea/services/intel.py +23 -21
- pangea/services/redact.py +3 -3
- pangea/services/vault/models/common.py +6 -6
- pangea/services/vault/models/symmetric.py +2 -2
- pangea/services/vault/vault.py +28 -28
- pangea/utils.py +1 -18
- pangea/verify_audit.py +267 -83
- {pangea_sdk-3.9.0.dist-info → pangea_sdk-4.0.0.dist-info}/METADATA +10 -9
- pangea_sdk-4.0.0.dist-info/RECORD +46 -0
- {pangea_sdk-3.9.0.dist-info → pangea_sdk-4.0.0.dist-info}/WHEEL +1 -1
- pangea_sdk-3.9.0.dist-info/RECORD +0 -46
pangea/services/intel.py
CHANGED
@@ -524,7 +524,7 @@ class FileIntel(ServiceBase):
|
|
524
524
|
)
|
525
525
|
"""
|
526
526
|
input = FileReputationRequest(hash=hash, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider)
|
527
|
-
return self.request.post("v1/reputation", FileReputationResult, data=input.
|
527
|
+
return self.request.post("v1/reputation", FileReputationResult, data=input.model_dump(exclude_none=True))
|
528
528
|
|
529
529
|
def hash_reputation_bulk(
|
530
530
|
self,
|
@@ -563,7 +563,7 @@ class FileIntel(ServiceBase):
|
|
563
563
|
input = FileReputationBulkRequest( # type: ignore[call-arg]
|
564
564
|
hashes=hashes, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider
|
565
565
|
)
|
566
|
-
return self.request.post("v2/reputation", FileReputationBulkResult, data=input.
|
566
|
+
return self.request.post("v2/reputation", FileReputationBulkResult, data=input.model_dump(exclude_none=True))
|
567
567
|
|
568
568
|
def filepath_reputation(
|
569
569
|
self,
|
@@ -708,7 +708,7 @@ class DomainIntel(ServiceBase):
|
|
708
708
|
)
|
709
709
|
"""
|
710
710
|
input = DomainReputationRequest(domain=domain, verbose=verbose, provider=provider, raw=raw)
|
711
|
-
return self.request.post("v1/reputation", DomainReputationResult, data=input.
|
711
|
+
return self.request.post("v1/reputation", DomainReputationResult, data=input.model_dump(exclude_none=True))
|
712
712
|
|
713
713
|
def reputation_bulk(
|
714
714
|
self,
|
@@ -744,7 +744,7 @@ class DomainIntel(ServiceBase):
|
|
744
744
|
)
|
745
745
|
"""
|
746
746
|
input = DomainReputationBulkRequest(domains=domains, verbose=verbose, provider=provider, raw=raw)
|
747
|
-
return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.
|
747
|
+
return self.request.post("v2/reputation", DomainReputationBulkResult, data=input.model_dump(exclude_none=True))
|
748
748
|
|
749
749
|
def who_is(
|
750
750
|
self, domain: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -776,7 +776,7 @@ class DomainIntel(ServiceBase):
|
|
776
776
|
)
|
777
777
|
"""
|
778
778
|
input = DomainWhoIsRequest(domain=domain, verbose=verbose, provider=provider, raw=raw) # type: ignore[call-arg]
|
779
|
-
return self.request.post("v1/whois", DomainWhoIsResult, data=input.
|
779
|
+
return self.request.post("v1/whois", DomainWhoIsResult, data=input.model_dump(exclude_none=True))
|
780
780
|
|
781
781
|
|
782
782
|
class IpIntel(ServiceBase):
|
@@ -835,7 +835,7 @@ class IpIntel(ServiceBase):
|
|
835
835
|
)
|
836
836
|
"""
|
837
837
|
input = IPReputationRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
838
|
-
return self.request.post("v1/reputation", IPReputationResult, data=input.
|
838
|
+
return self.request.post("v1/reputation", IPReputationResult, data=input.model_dump(exclude_none=True))
|
839
839
|
|
840
840
|
def reputation_bulk(
|
841
841
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -867,7 +867,7 @@ class IpIntel(ServiceBase):
|
|
867
867
|
)
|
868
868
|
"""
|
869
869
|
input = IPReputationBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
870
|
-
return self.request.post("v2/reputation", IPReputationBulkResult, data=input.
|
870
|
+
return self.request.post("v2/reputation", IPReputationBulkResult, data=input.model_dump(exclude_none=True))
|
871
871
|
|
872
872
|
def geolocate(
|
873
873
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -899,7 +899,7 @@ class IpIntel(ServiceBase):
|
|
899
899
|
)
|
900
900
|
"""
|
901
901
|
input = IPGeolocateRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
902
|
-
return self.request.post("v1/geolocate", IPGeolocateResult, data=input.
|
902
|
+
return self.request.post("v1/geolocate", IPGeolocateResult, data=input.model_dump(exclude_none=True))
|
903
903
|
|
904
904
|
def geolocate_bulk(
|
905
905
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -931,7 +931,7 @@ class IpIntel(ServiceBase):
|
|
931
931
|
)
|
932
932
|
"""
|
933
933
|
input = IPGeolocateBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
934
|
-
return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.
|
934
|
+
return self.request.post("v2/geolocate", IPGeolocateBulkResult, data=input.model_dump(exclude_none=True))
|
935
935
|
|
936
936
|
def get_domain(
|
937
937
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -963,7 +963,7 @@ class IpIntel(ServiceBase):
|
|
963
963
|
)
|
964
964
|
"""
|
965
965
|
input = IPDomainRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
966
|
-
return self.request.post("v1/domain", IPDomainResult, data=input.
|
966
|
+
return self.request.post("v1/domain", IPDomainResult, data=input.model_dump(exclude_none=True))
|
967
967
|
|
968
968
|
def get_domain_bulk(
|
969
969
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -995,7 +995,7 @@ class IpIntel(ServiceBase):
|
|
995
995
|
)
|
996
996
|
"""
|
997
997
|
input = IPDomainBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
998
|
-
return self.request.post("v2/domain", IPDomainBulkResult, data=input.
|
998
|
+
return self.request.post("v2/domain", IPDomainBulkResult, data=input.model_dump(exclude_none=True))
|
999
999
|
|
1000
1000
|
def is_vpn(
|
1001
1001
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1027,7 +1027,7 @@ class IpIntel(ServiceBase):
|
|
1027
1027
|
)
|
1028
1028
|
"""
|
1029
1029
|
input = IPVPNRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
1030
|
-
return self.request.post("v1/vpn", IPVPNResult, data=input.
|
1030
|
+
return self.request.post("v1/vpn", IPVPNResult, data=input.model_dump(exclude_none=True))
|
1031
1031
|
|
1032
1032
|
def is_vpn_bulk(
|
1033
1033
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1059,7 +1059,7 @@ class IpIntel(ServiceBase):
|
|
1059
1059
|
)
|
1060
1060
|
"""
|
1061
1061
|
input = IPVPNBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
1062
|
-
return self.request.post("v2/vpn", IPVPNBulkResult, data=input.
|
1062
|
+
return self.request.post("v2/vpn", IPVPNBulkResult, data=input.model_dump(exclude_none=True))
|
1063
1063
|
|
1064
1064
|
def is_proxy(
|
1065
1065
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1091,7 +1091,7 @@ class IpIntel(ServiceBase):
|
|
1091
1091
|
)
|
1092
1092
|
"""
|
1093
1093
|
input = IPProxyRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
1094
|
-
return self.request.post("v1/proxy", IPProxyResult, data=input.
|
1094
|
+
return self.request.post("v1/proxy", IPProxyResult, data=input.model_dump(exclude_none=True))
|
1095
1095
|
|
1096
1096
|
def is_proxy_bulk(
|
1097
1097
|
self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
@@ -1123,7 +1123,7 @@ class IpIntel(ServiceBase):
|
|
1123
1123
|
)
|
1124
1124
|
"""
|
1125
1125
|
input = IPProxyBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
|
1126
|
-
return self.request.post("v2/proxy", IPProxyBulkResult, data=input.
|
1126
|
+
return self.request.post("v2/proxy", IPProxyBulkResult, data=input.model_dump(exclude_none=True))
|
1127
1127
|
|
1128
1128
|
|
1129
1129
|
class UrlIntel(ServiceBase):
|
@@ -1187,7 +1187,7 @@ class UrlIntel(ServiceBase):
|
|
1187
1187
|
"""
|
1188
1188
|
|
1189
1189
|
input = URLReputationRequest(url=url, provider=provider, verbose=verbose, raw=raw)
|
1190
|
-
return self.request.post("v1/reputation", URLReputationResult, data=input.
|
1190
|
+
return self.request.post("v1/reputation", URLReputationResult, data=input.model_dump(exclude_none=True))
|
1191
1191
|
|
1192
1192
|
def reputation_bulk(
|
1193
1193
|
self,
|
@@ -1224,7 +1224,7 @@ class UrlIntel(ServiceBase):
|
|
1224
1224
|
"""
|
1225
1225
|
|
1226
1226
|
input = URLReputationBulkRequest(urls=urls, provider=provider, verbose=verbose, raw=raw)
|
1227
|
-
return self.request.post("v2/reputation", URLReputationBulkResult, data=input.
|
1227
|
+
return self.request.post("v2/reputation", URLReputationBulkResult, data=input.model_dump(exclude_none=True))
|
1228
1228
|
|
1229
1229
|
|
1230
1230
|
class UserBreachedRequest(IntelCommonRequest):
|
@@ -1431,7 +1431,7 @@ class UserIntel(ServiceBase):
|
|
1431
1431
|
verbose=verbose,
|
1432
1432
|
raw=raw,
|
1433
1433
|
)
|
1434
|
-
return self.request.post("v1/user/breached", UserBreachedResult, data=input.
|
1434
|
+
return self.request.post("v1/user/breached", UserBreachedResult, data=input.model_dump(exclude_none=True))
|
1435
1435
|
|
1436
1436
|
def user_breached_bulk(
|
1437
1437
|
self,
|
@@ -1490,7 +1490,7 @@ class UserIntel(ServiceBase):
|
|
1490
1490
|
verbose=verbose,
|
1491
1491
|
raw=raw,
|
1492
1492
|
)
|
1493
|
-
return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.
|
1493
|
+
return self.request.post("v2/user/breached", UserBreachedBulkResult, data=input.model_dump(exclude_none=True))
|
1494
1494
|
|
1495
1495
|
def password_breached(
|
1496
1496
|
self,
|
@@ -1532,7 +1532,9 @@ class UserIntel(ServiceBase):
|
|
1532
1532
|
input = UserPasswordBreachedRequest(
|
1533
1533
|
hash_type=hash_type, hash_prefix=hash_prefix, provider=provider, verbose=verbose, raw=raw
|
1534
1534
|
)
|
1535
|
-
return self.request.post(
|
1535
|
+
return self.request.post(
|
1536
|
+
"v1/password/breached", UserPasswordBreachedResult, data=input.model_dump(exclude_none=True)
|
1537
|
+
)
|
1536
1538
|
|
1537
1539
|
def password_breached_bulk(
|
1538
1540
|
self,
|
@@ -1575,7 +1577,7 @@ class UserIntel(ServiceBase):
|
|
1575
1577
|
hash_type=hash_type, hash_prefixes=hash_prefixes, provider=provider, verbose=verbose, raw=raw
|
1576
1578
|
)
|
1577
1579
|
return self.request.post(
|
1578
|
-
"v2/password/breached", UserPasswordBreachedBulkResult, data=input.
|
1580
|
+
"v2/password/breached", UserPasswordBreachedBulkResult, data=input.model_dump(exclude_none=True)
|
1579
1581
|
)
|
1580
1582
|
|
1581
1583
|
class PasswordStatus(enum.Enum):
|
pangea/services/redact.py
CHANGED
@@ -265,7 +265,7 @@ class Redact(ServiceBase):
|
|
265
265
|
return_result=return_result,
|
266
266
|
redaction_method_overrides=redaction_method_overrides,
|
267
267
|
)
|
268
|
-
return self.request.post("v1/redact", RedactResult, data=input.
|
268
|
+
return self.request.post("v1/redact", RedactResult, data=input.model_dump(exclude_none=True))
|
269
269
|
|
270
270
|
def redact_structured(
|
271
271
|
self,
|
@@ -325,7 +325,7 @@ class Redact(ServiceBase):
|
|
325
325
|
return_result=return_result,
|
326
326
|
redaction_method_overrides=redaction_method_overrides,
|
327
327
|
)
|
328
|
-
return self.request.post("v1/redact_structured", StructuredResult, data=input.
|
328
|
+
return self.request.post("v1/redact_structured", StructuredResult, data=input.model_dump(exclude_none=True))
|
329
329
|
|
330
330
|
def unredact(self, redacted_data: RedactedData, fpe_context: str) -> PangeaResponse[UnredactResult]:
|
331
331
|
"""
|
@@ -348,4 +348,4 @@ class Redact(ServiceBase):
|
|
348
348
|
[API Documentation](https://pangea.cloud/docs/api/redact#unredact)
|
349
349
|
"""
|
350
350
|
input = UnredactRequest(redacted_data=redacted_data, fpe_context=fpe_context)
|
351
|
-
return self.request.post("v1/unredact", UnredactResult, data=input.
|
351
|
+
return self.request.post("v1/unredact", UnredactResult, data=input.model_dump(exclude_none=True))
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
-
|
3
|
+
|
4
4
|
import enum
|
5
5
|
from typing import Dict, Generic, List, NewType, Optional, TypeVar, Union
|
6
6
|
|
7
|
-
from pangea.response import APIRequestModel, PangeaResponseResult
|
7
|
+
from pangea.response import APIRequestModel, PangeaDateTime, PangeaResponseResult
|
8
8
|
|
9
9
|
# EncodedPublicKey is a PEM public key, with no further encoding (i.e. no base64)
|
10
10
|
# It may be used for example in openssh with no further processing
|
@@ -181,7 +181,7 @@ class CommonStoreRequest(APIRequestModel):
|
|
181
181
|
tags: Optional[Tags] = None
|
182
182
|
rotation_frequency: Optional[str] = None
|
183
183
|
rotation_state: Optional[ItemVersionState] = None
|
184
|
-
expiration: Optional[
|
184
|
+
expiration: Optional[PangeaDateTime] = None
|
185
185
|
|
186
186
|
|
187
187
|
class CommonStoreResult(PangeaResponseResult):
|
@@ -198,7 +198,7 @@ class CommonGenerateRequest(APIRequestModel):
|
|
198
198
|
tags: Optional[Tags] = None
|
199
199
|
rotation_frequency: Optional[str] = None
|
200
200
|
rotation_state: Optional[ItemVersionState] = None
|
201
|
-
expiration: Optional[
|
201
|
+
expiration: Optional[PangeaDateTime] = None
|
202
202
|
|
203
203
|
|
204
204
|
class CommonGenerateResult(PangeaResponseResult):
|
@@ -261,7 +261,7 @@ class ListItemData(ItemData):
|
|
261
261
|
class ListResult(PangeaResponseResult):
|
262
262
|
items: List[ListItemData] = []
|
263
263
|
count: int
|
264
|
-
last: Optional[str]
|
264
|
+
last: Optional[str] = None
|
265
265
|
|
266
266
|
|
267
267
|
class ListRequest(APIRequestModel):
|
@@ -312,7 +312,7 @@ class UpdateRequest(APIRequestModel):
|
|
312
312
|
rotation_frequency: Optional[str] = None
|
313
313
|
rotation_state: Optional[ItemVersionState] = None
|
314
314
|
rotation_grace_period: Optional[str] = None
|
315
|
-
expiration: Optional[
|
315
|
+
expiration: Optional[PangeaDateTime] = None
|
316
316
|
item_state: Optional[ItemState] = None
|
317
317
|
|
318
318
|
|
@@ -39,7 +39,7 @@ class EncryptRequest(APIRequestModel):
|
|
39
39
|
id: str
|
40
40
|
plain_text: str
|
41
41
|
version: Optional[int] = None
|
42
|
-
additional_data: Optional[str]
|
42
|
+
additional_data: Optional[str] = None
|
43
43
|
|
44
44
|
|
45
45
|
class EncryptResult(PangeaResponseResult):
|
@@ -53,7 +53,7 @@ class DecryptRequest(APIRequestModel):
|
|
53
53
|
id: str
|
54
54
|
cipher_text: str
|
55
55
|
version: Optional[int] = None
|
56
|
-
additional_data: Optional[str]
|
56
|
+
additional_data: Optional[str] = None
|
57
57
|
|
58
58
|
|
59
59
|
class DecryptResult(PangeaResponseResult):
|
pangea/services/vault/vault.py
CHANGED
@@ -151,7 +151,7 @@ class Vault(ServiceBase):
|
|
151
151
|
input = DeleteRequest(
|
152
152
|
id=id,
|
153
153
|
)
|
154
|
-
return self.request.post("v1/delete", DeleteResult, data=input.
|
154
|
+
return self.request.post("v1/delete", DeleteResult, data=input.model_dump(exclude_none=True))
|
155
155
|
|
156
156
|
# Get endpoint
|
157
157
|
def get(
|
@@ -198,7 +198,7 @@ class Vault(ServiceBase):
|
|
198
198
|
verbose=verbose,
|
199
199
|
version_state=version_state,
|
200
200
|
)
|
201
|
-
return self.request.post("v1/get", GetResult, data=input.
|
201
|
+
return self.request.post("v1/get", GetResult, data=input.model_dump(exclude_none=True))
|
202
202
|
|
203
203
|
# List endpoint
|
204
204
|
def list(
|
@@ -254,7 +254,7 @@ class Vault(ServiceBase):
|
|
254
254
|
)
|
255
255
|
"""
|
256
256
|
input = ListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
|
257
|
-
return self.request.post("v1/list", ListResult, data=input.
|
257
|
+
return self.request.post("v1/list", ListResult, data=input.model_dump(exclude_none=True))
|
258
258
|
|
259
259
|
# Update endpoint
|
260
260
|
def update(
|
@@ -335,7 +335,7 @@ class Vault(ServiceBase):
|
|
335
335
|
expiration=expiration,
|
336
336
|
item_state=item_state,
|
337
337
|
)
|
338
|
-
return self.request.post("v1/update", UpdateResult, data=input.
|
338
|
+
return self.request.post("v1/update", UpdateResult, data=input.model_dump(exclude_none=True))
|
339
339
|
|
340
340
|
def secret_store(
|
341
341
|
self,
|
@@ -405,7 +405,7 @@ class Vault(ServiceBase):
|
|
405
405
|
rotation_state=rotation_state,
|
406
406
|
expiration=expiration,
|
407
407
|
)
|
408
|
-
return self.request.post("v1/secret/store", SecretStoreResult, data=input.
|
408
|
+
return self.request.post("v1/secret/store", SecretStoreResult, data=input.model_dump(exclude_none=True))
|
409
409
|
|
410
410
|
def pangea_token_store(
|
411
411
|
self,
|
@@ -475,7 +475,7 @@ class Vault(ServiceBase):
|
|
475
475
|
rotation_state=rotation_state,
|
476
476
|
expiration=expiration,
|
477
477
|
)
|
478
|
-
return self.request.post("v1/secret/store", SecretStoreResult, data=input.
|
478
|
+
return self.request.post("v1/secret/store", SecretStoreResult, data=input.model_dump(exclude_none=True))
|
479
479
|
|
480
480
|
# Rotate endpoint
|
481
481
|
def secret_rotate(
|
@@ -515,7 +515,7 @@ class Vault(ServiceBase):
|
|
515
515
|
)
|
516
516
|
"""
|
517
517
|
input = SecretRotateRequest(id=id, secret=secret, rotation_state=rotation_state)
|
518
|
-
return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.
|
518
|
+
return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.model_dump(exclude_none=True))
|
519
519
|
|
520
520
|
# Rotate endpoint
|
521
521
|
def pangea_token_rotate(self, id: str) -> PangeaResponse[SecretRotateResult]:
|
@@ -543,7 +543,7 @@ class Vault(ServiceBase):
|
|
543
543
|
)
|
544
544
|
"""
|
545
545
|
input = SecretRotateRequest(id=id) # type: ignore[call-arg]
|
546
|
-
return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.
|
546
|
+
return self.request.post("v1/secret/rotate", SecretRotateResult, data=input.model_dump(exclude_none=True))
|
547
547
|
|
548
548
|
def symmetric_generate(
|
549
549
|
self,
|
@@ -620,7 +620,7 @@ class Vault(ServiceBase):
|
|
620
620
|
return self.request.post(
|
621
621
|
"v1/key/generate",
|
622
622
|
SymmetricGenerateResult,
|
623
|
-
data=input.
|
623
|
+
data=input.model_dump(exclude_none=True),
|
624
624
|
)
|
625
625
|
|
626
626
|
def asymmetric_generate(
|
@@ -698,7 +698,7 @@ class Vault(ServiceBase):
|
|
698
698
|
return self.request.post(
|
699
699
|
"v1/key/generate",
|
700
700
|
AsymmetricGenerateResult,
|
701
|
-
data=input.
|
701
|
+
data=input.model_dump(exclude_none=True),
|
702
702
|
)
|
703
703
|
|
704
704
|
# Store endpoints
|
@@ -782,7 +782,7 @@ class Vault(ServiceBase):
|
|
782
782
|
rotation_state=rotation_state,
|
783
783
|
expiration=expiration,
|
784
784
|
)
|
785
|
-
return self.request.post("v1/key/store", AsymmetricStoreResult, data=input.
|
785
|
+
return self.request.post("v1/key/store", AsymmetricStoreResult, data=input.model_dump(exclude_none=True))
|
786
786
|
|
787
787
|
def symmetric_store(
|
788
788
|
self,
|
@@ -860,7 +860,7 @@ class Vault(ServiceBase):
|
|
860
860
|
rotation_state=rotation_state,
|
861
861
|
expiration=expiration,
|
862
862
|
)
|
863
|
-
return self.request.post("v1/key/store", SymmetricStoreResult, data=input.
|
863
|
+
return self.request.post("v1/key/store", SymmetricStoreResult, data=input.model_dump(exclude_none=True))
|
864
864
|
|
865
865
|
# Rotate endpoint
|
866
866
|
def key_rotate(
|
@@ -913,7 +913,7 @@ class Vault(ServiceBase):
|
|
913
913
|
key=key,
|
914
914
|
rotation_state=rotation_state,
|
915
915
|
)
|
916
|
-
return self.request.post("v1/key/rotate", KeyRotateResult, data=input.
|
916
|
+
return self.request.post("v1/key/rotate", KeyRotateResult, data=input.model_dump(exclude_none=True))
|
917
917
|
|
918
918
|
# Encrypt
|
919
919
|
def encrypt(self, id: str, plain_text: str, version: Optional[int] = None) -> PangeaResponse[EncryptResult]:
|
@@ -944,8 +944,8 @@ class Vault(ServiceBase):
|
|
944
944
|
version=1,
|
945
945
|
)
|
946
946
|
"""
|
947
|
-
input = EncryptRequest(id=id, plain_text=plain_text, version=version)
|
948
|
-
return self.request.post("v1/key/encrypt", EncryptResult, data=input.
|
947
|
+
input = EncryptRequest(id=id, plain_text=plain_text, version=version)
|
948
|
+
return self.request.post("v1/key/encrypt", EncryptResult, data=input.model_dump(exclude_none=True))
|
949
949
|
|
950
950
|
# Decrypt
|
951
951
|
def decrypt(self, id: str, cipher_text: str, version: Optional[int] = None) -> PangeaResponse[DecryptResult]:
|
@@ -976,8 +976,8 @@ class Vault(ServiceBase):
|
|
976
976
|
version=1,
|
977
977
|
)
|
978
978
|
"""
|
979
|
-
input = DecryptRequest(id=id, cipher_text=cipher_text, version=version)
|
980
|
-
return self.request.post("v1/key/decrypt", DecryptResult, data=input.
|
979
|
+
input = DecryptRequest(id=id, cipher_text=cipher_text, version=version)
|
980
|
+
return self.request.post("v1/key/decrypt", DecryptResult, data=input.model_dump(exclude_none=True))
|
981
981
|
|
982
982
|
# Sign
|
983
983
|
def sign(self, id: str, message: str, version: Optional[int] = None) -> PangeaResponse[SignResult]:
|
@@ -1009,7 +1009,7 @@ class Vault(ServiceBase):
|
|
1009
1009
|
)
|
1010
1010
|
"""
|
1011
1011
|
input = SignRequest(id=id, message=message, version=version)
|
1012
|
-
return self.request.post("v1/key/sign", SignResult, data=input.
|
1012
|
+
return self.request.post("v1/key/sign", SignResult, data=input.model_dump(exclude_none=True))
|
1013
1013
|
|
1014
1014
|
# Verify
|
1015
1015
|
def verify(
|
@@ -1050,7 +1050,7 @@ class Vault(ServiceBase):
|
|
1050
1050
|
signature=signature,
|
1051
1051
|
version=version,
|
1052
1052
|
)
|
1053
|
-
return self.request.post("v1/key/verify", VerifyResult, data=input.
|
1053
|
+
return self.request.post("v1/key/verify", VerifyResult, data=input.model_dump(exclude_none=True))
|
1054
1054
|
|
1055
1055
|
def jwt_verify(self, jws: str) -> PangeaResponse[JWTVerifyResult]:
|
1056
1056
|
"""
|
@@ -1077,7 +1077,7 @@ class Vault(ServiceBase):
|
|
1077
1077
|
)
|
1078
1078
|
"""
|
1079
1079
|
input = JWTVerifyRequest(jws=jws)
|
1080
|
-
return self.request.post("v1/key/verify/jwt", JWTVerifyResult, data=input.
|
1080
|
+
return self.request.post("v1/key/verify/jwt", JWTVerifyResult, data=input.model_dump(exclude_none=True))
|
1081
1081
|
|
1082
1082
|
def jwt_sign(self, id: str, payload: str) -> PangeaResponse[JWTSignResult]:
|
1083
1083
|
"""
|
@@ -1106,7 +1106,7 @@ class Vault(ServiceBase):
|
|
1106
1106
|
)
|
1107
1107
|
"""
|
1108
1108
|
input = JWTSignRequest(id=id, payload=payload)
|
1109
|
-
return self.request.post("v1/key/sign/jwt", JWTSignResult, data=input.
|
1109
|
+
return self.request.post("v1/key/sign/jwt", JWTSignResult, data=input.model_dump(exclude_none=True))
|
1110
1110
|
|
1111
1111
|
# Get endpoint
|
1112
1112
|
def jwk_get(self, id: str, version: Optional[str] = None) -> PangeaResponse[JWKGetResult]:
|
@@ -1137,7 +1137,7 @@ class Vault(ServiceBase):
|
|
1137
1137
|
)
|
1138
1138
|
"""
|
1139
1139
|
input = JWKGetRequest(id=id, version=version)
|
1140
|
-
return self.request.post("v1/get/jwk", JWKGetResult, data=input.
|
1140
|
+
return self.request.post("v1/get/jwk", JWKGetResult, data=input.model_dump(exclude_none=True))
|
1141
1141
|
|
1142
1142
|
# State change
|
1143
1143
|
def state_change(
|
@@ -1180,7 +1180,7 @@ class Vault(ServiceBase):
|
|
1180
1180
|
)
|
1181
1181
|
"""
|
1182
1182
|
input = StateChangeRequest(id=id, state=state, version=version, destroy_period=destroy_period)
|
1183
|
-
return self.request.post("v1/state/change", StateChangeResult, data=input.
|
1183
|
+
return self.request.post("v1/state/change", StateChangeResult, data=input.model_dump(exclude_none=True))
|
1184
1184
|
|
1185
1185
|
# Folder create
|
1186
1186
|
def folder_create(
|
@@ -1217,7 +1217,7 @@ class Vault(ServiceBase):
|
|
1217
1217
|
)
|
1218
1218
|
"""
|
1219
1219
|
input = FolderCreateRequest(name=name, folder=folder, metadata=metadata, tags=tags)
|
1220
|
-
return self.request.post("v1/folder/create", FolderCreateResult, data=input.
|
1220
|
+
return self.request.post("v1/folder/create", FolderCreateResult, data=input.model_dump(exclude_none=True))
|
1221
1221
|
|
1222
1222
|
# Encrypt structured
|
1223
1223
|
def encrypt_structured(
|
@@ -1265,7 +1265,7 @@ class Vault(ServiceBase):
|
|
1265
1265
|
return self.request.post(
|
1266
1266
|
"v1/key/encrypt/structured",
|
1267
1267
|
EncryptStructuredResult,
|
1268
|
-
data=input.
|
1268
|
+
data=input.model_dump(exclude_none=True),
|
1269
1269
|
)
|
1270
1270
|
|
1271
1271
|
# Decrypt structured
|
@@ -1314,7 +1314,7 @@ class Vault(ServiceBase):
|
|
1314
1314
|
return self.request.post(
|
1315
1315
|
"v1/key/decrypt/structured",
|
1316
1316
|
EncryptStructuredResult,
|
1317
|
-
data=input.
|
1317
|
+
data=input.model_dump(exclude_none=True),
|
1318
1318
|
)
|
1319
1319
|
|
1320
1320
|
def encrypt_transform(
|
@@ -1364,7 +1364,7 @@ class Vault(ServiceBase):
|
|
1364
1364
|
return self.request.post(
|
1365
1365
|
"v1/key/encrypt/transform",
|
1366
1366
|
EncryptTransformResult,
|
1367
|
-
data=input.
|
1367
|
+
data=input.model_dump(exclude_none=True),
|
1368
1368
|
)
|
1369
1369
|
|
1370
1370
|
def decrypt_transform(
|
@@ -1403,5 +1403,5 @@ class Vault(ServiceBase):
|
|
1403
1403
|
return self.request.post(
|
1404
1404
|
"v1/key/decrypt/transform",
|
1405
1405
|
DecryptTransformResult,
|
1406
|
-
data=input.
|
1406
|
+
data=input.model_dump(exclude_none=True),
|
1407
1407
|
)
|
pangea/utils.py
CHANGED
@@ -3,10 +3,9 @@ import copy
|
|
3
3
|
import datetime
|
4
4
|
import io
|
5
5
|
import json
|
6
|
-
from collections import OrderedDict
|
7
6
|
from hashlib import new, sha1, sha256, sha512
|
8
7
|
|
9
|
-
from google_crc32c import Checksum as CRC32C # type: ignore[import]
|
8
|
+
from google_crc32c import Checksum as CRC32C # type: ignore[import-untyped]
|
10
9
|
from pydantic import BaseModel
|
11
10
|
|
12
11
|
|
@@ -34,22 +33,6 @@ def str2str_b64(data: str, encoding: str = "utf-8") -> str:
|
|
34
33
|
return base64.b64encode(data.encode(encoding)).decode("ascii")
|
35
34
|
|
36
35
|
|
37
|
-
def dict_order_keys(data: dict) -> OrderedDict:
|
38
|
-
if isinstance(data, dict):
|
39
|
-
return OrderedDict(sorted(data.items()))
|
40
|
-
else:
|
41
|
-
return data
|
42
|
-
|
43
|
-
|
44
|
-
def dict_order_keys_recursive(data: dict) -> OrderedDict:
|
45
|
-
if isinstance(data, dict):
|
46
|
-
for k, v in data.items():
|
47
|
-
if type(v) is dict:
|
48
|
-
data[k] = dict_order_keys_recursive(v)
|
49
|
-
|
50
|
-
return data # type: ignore[return-value]
|
51
|
-
|
52
|
-
|
53
36
|
def canonicalize_nested_json(data: dict) -> dict:
|
54
37
|
"""Canonicalize nested JSON"""
|
55
38
|
if not isinstance(data, dict):
|