pangea-sdk 6.1.0__py3-none-any.whl → 6.2.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 +9 -1
- pangea/asyncio/__init__.py +1 -0
- pangea/asyncio/file_uploader.py +4 -2
- pangea/asyncio/request.py +53 -18
- pangea/asyncio/services/__init__.py +2 -0
- pangea/asyncio/services/ai_guard.py +9 -12
- pangea/asyncio/services/audit.py +12 -7
- pangea/asyncio/services/authn.py +36 -25
- pangea/asyncio/services/authz.py +6 -6
- pangea/asyncio/services/base.py +4 -0
- pangea/asyncio/services/file_scan.py +8 -2
- pangea/asyncio/services/intel.py +26 -28
- pangea/asyncio/services/redact.py +7 -3
- pangea/asyncio/services/sanitize.py +5 -1
- pangea/asyncio/services/share.py +5 -1
- pangea/asyncio/services/vault.py +19 -15
- pangea/audit_logger.py +3 -1
- pangea/deep_verify.py +13 -13
- pangea/deprecated.py +1 -1
- pangea/dump_audit.py +2 -3
- pangea/exceptions.py +8 -5
- pangea/file_uploader.py +4 -0
- pangea/request.py +64 -48
- pangea/response.py +21 -18
- pangea/services/__init__.py +2 -0
- pangea/services/ai_guard.py +35 -24
- pangea/services/audit/audit.py +16 -13
- pangea/services/audit/models.py +71 -34
- pangea/services/audit/signing.py +1 -1
- pangea/services/audit/util.py +10 -10
- pangea/services/authn/authn.py +36 -25
- pangea/services/authn/models.py +10 -56
- pangea/services/authz.py +10 -6
- pangea/services/base.py +7 -4
- pangea/services/embargo.py +6 -0
- pangea/services/file_scan.py +8 -2
- pangea/services/intel.py +36 -19
- pangea/services/redact.py +7 -3
- pangea/services/sanitize.py +5 -1
- pangea/services/share/share.py +13 -7
- pangea/services/vault/models/asymmetric.py +4 -0
- pangea/services/vault/models/common.py +4 -0
- pangea/services/vault/models/symmetric.py +4 -0
- pangea/services/vault/vault.py +17 -19
- pangea/tools.py +13 -9
- pangea/utils.py +3 -5
- pangea/verify_audit.py +23 -27
- {pangea_sdk-6.1.0.dist-info → pangea_sdk-6.2.0.dist-info}/METADATA +36 -17
- pangea_sdk-6.2.0.dist-info/RECORD +60 -0
- {pangea_sdk-6.1.0.dist-info → pangea_sdk-6.2.0.dist-info}/WHEEL +1 -1
- pangea_sdk-6.1.0.dist-info/RECORD +0 -60
pangea/services/embargo.py
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
7
|
+
from __future__ import annotations
|
8
|
+
|
3
9
|
from typing import Any, Dict, List
|
4
10
|
|
5
11
|
from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
|
pangea/services/file_scan.py
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
7
|
+
from __future__ import annotations
|
8
|
+
|
3
9
|
import io
|
4
10
|
import logging
|
5
11
|
from typing import Dict, List, Optional, Tuple
|
@@ -52,7 +58,7 @@ class FileScan(ServiceBase):
|
|
52
58
|
"""FileScan service client.
|
53
59
|
|
54
60
|
Provides methods to interact with Pangea FileScan Service:
|
55
|
-
https://pangea.cloud/docs/api/
|
61
|
+
https://pangea.cloud/docs/api/file-scan
|
56
62
|
|
57
63
|
The following information is needed:
|
58
64
|
PANGEA_TOKEN - service token which can be found on the Pangea User
|
@@ -133,7 +139,7 @@ class FileScan(ServiceBase):
|
|
133
139
|
files: Optional[List[Tuple]] = None
|
134
140
|
if file or file_path:
|
135
141
|
if file_path:
|
136
|
-
file = open(file_path, "rb")
|
142
|
+
file = open(file_path, "rb") # noqa: SIM115
|
137
143
|
if transfer_method == TransferMethod.POST_URL:
|
138
144
|
params = get_file_upload_params(file) # type: ignore[arg-type]
|
139
145
|
crc = params.crc_hex
|
pangea/services/intel.py
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import enum
|
6
10
|
import hashlib
|
7
|
-
from typing import Dict, List, Optional
|
11
|
+
from typing import Dict, List, Literal, Optional
|
8
12
|
|
9
13
|
from pangea.exceptions import PangeaException
|
10
14
|
from pangea.response import APIRequestModel, PangeaResponse, PangeaResponseResult
|
@@ -61,8 +65,20 @@ class FileReputationBulkRequest(APIRequestModel):
|
|
61
65
|
hash_type (str): Type of hash, can be "sha256", "sha" or "md5"
|
62
66
|
"""
|
63
67
|
|
64
|
-
hashes:
|
65
|
-
|
68
|
+
hashes: list[str]
|
69
|
+
"""The hash of the file to be looked up"""
|
70
|
+
|
71
|
+
hash_type: Literal["sha256", "sha", "md5"]
|
72
|
+
"""One of "sha256", "sha", "md5"."""
|
73
|
+
|
74
|
+
verbose: Optional[bool] = None
|
75
|
+
"""Echo the API parameters in the response"""
|
76
|
+
|
77
|
+
raw: Optional[bool] = None
|
78
|
+
"""Include raw data from this provider"""
|
79
|
+
|
80
|
+
provider: Optional[Literal["reversinglabs", "crowdstrike"]] = None
|
81
|
+
"""Use reputation data from this provider"""
|
66
82
|
|
67
83
|
|
68
84
|
class FileReputationData(IntelReputationData):
|
@@ -356,7 +372,8 @@ class DomainWhoIsRequest(DomainCommonRequest):
|
|
356
372
|
Domain whois request data
|
357
373
|
"""
|
358
374
|
|
359
|
-
|
375
|
+
domain: str
|
376
|
+
"""The domain to query."""
|
360
377
|
|
361
378
|
|
362
379
|
class DomainWhoIsData(PangeaResponseResult):
|
@@ -530,11 +547,11 @@ class FileIntel(ServiceBase):
|
|
530
547
|
|
531
548
|
def hash_reputation_bulk(
|
532
549
|
self,
|
533
|
-
hashes:
|
534
|
-
hash_type:
|
535
|
-
provider:
|
536
|
-
verbose:
|
537
|
-
raw:
|
550
|
+
hashes: list[str],
|
551
|
+
hash_type: Literal["sha256", "sha", "md5"],
|
552
|
+
provider: Literal["reversinglabs", "crowdstrike"] | None = None,
|
553
|
+
verbose: bool | None = None,
|
554
|
+
raw: bool | None = None,
|
538
555
|
) -> PangeaResponse[FileReputationBulkResult]:
|
539
556
|
"""
|
540
557
|
Reputation check V2
|
@@ -562,7 +579,7 @@ class FileIntel(ServiceBase):
|
|
562
579
|
provider="reversinglabs",
|
563
580
|
)
|
564
581
|
"""
|
565
|
-
input = FileReputationBulkRequest(
|
582
|
+
input = FileReputationBulkRequest(
|
566
583
|
hashes=hashes, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider
|
567
584
|
)
|
568
585
|
return self.request.post("v2/reputation", FileReputationBulkResult, data=input.model_dump(exclude_none=True))
|
@@ -610,10 +627,10 @@ class FileIntel(ServiceBase):
|
|
610
627
|
|
611
628
|
def filepath_reputation_bulk(
|
612
629
|
self,
|
613
|
-
filepaths:
|
614
|
-
provider:
|
615
|
-
verbose:
|
616
|
-
raw:
|
630
|
+
filepaths: list[str],
|
631
|
+
provider: Literal["reversinglabs", "crowdstrike"] | None = None,
|
632
|
+
verbose: bool | None = None,
|
633
|
+
raw: bool | None = None,
|
617
634
|
) -> PangeaResponse[FileReputationBulkResult]:
|
618
635
|
"""
|
619
636
|
Reputation, from filepath V2
|
@@ -624,10 +641,10 @@ class FileIntel(ServiceBase):
|
|
624
641
|
OperationId: file_intel_post_v2_reputation
|
625
642
|
|
626
643
|
Args:
|
627
|
-
filepaths
|
628
|
-
provider
|
629
|
-
verbose
|
630
|
-
raw
|
644
|
+
filepaths: The path list to the files to be looked up
|
645
|
+
provider: Use reputation data from these providers: "reversinglabs" or "crowdstrike"
|
646
|
+
verbose: Echo the API parameters in the response
|
647
|
+
raw: Include raw data from this provider
|
631
648
|
|
632
649
|
Raises:
|
633
650
|
PangeaAPIException: If an API Error happens
|
@@ -777,7 +794,7 @@ class DomainIntel(ServiceBase):
|
|
777
794
|
provider="whoisxml",
|
778
795
|
)
|
779
796
|
"""
|
780
|
-
input = DomainWhoIsRequest(domain=domain, verbose=verbose, provider=provider, raw=raw)
|
797
|
+
input = DomainWhoIsRequest(domain=domain, verbose=verbose, provider=provider, raw=raw)
|
781
798
|
return self.request.post("v1/whois", DomainWhoIsResult, data=input.model_dump(exclude_none=True))
|
782
799
|
|
783
800
|
|
pangea/services/redact.py
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import enum
|
@@ -276,7 +280,7 @@ class Redact(ServiceBase):
|
|
276
280
|
Returns:
|
277
281
|
Pangea Response with redacted text in the response.result property,
|
278
282
|
available response fields can be found in our
|
279
|
-
[API Documentation](https://pangea.cloud/docs/api/redact#redact).
|
283
|
+
[API Documentation](https://pangea.cloud/docs/api/redact#redact-post).
|
280
284
|
|
281
285
|
Examples:
|
282
286
|
response = redact.redact(text="Jenny Jenny... 555-867-5309")
|
@@ -335,7 +339,7 @@ class Redact(ServiceBase):
|
|
335
339
|
Returns:
|
336
340
|
Pangea Response with redacted data in the response.result field,
|
337
341
|
available response fields can be found in our
|
338
|
-
[API Documentation](https://pangea.cloud/docs/api/redact#redact-structured)
|
342
|
+
[API Documentation](https://pangea.cloud/docs/api/redact#redact-structured-post)
|
339
343
|
|
340
344
|
Examples:
|
341
345
|
data = {
|
@@ -378,7 +382,7 @@ class Redact(ServiceBase):
|
|
378
382
|
Returns:
|
379
383
|
Pangea Response with redacted data in the response.result field,
|
380
384
|
available response fields can be found in our
|
381
|
-
[API Documentation](https://pangea.cloud/docs/api/redact#unredact)
|
385
|
+
[API Documentation](https://pangea.cloud/docs/api/redact#unredact-post)
|
382
386
|
"""
|
383
387
|
input = UnredactRequest(redacted_data=redacted_data, fpe_context=fpe_context)
|
384
388
|
return self.request.post("v1/unredact", UnredactResult, data=input.model_dump(exclude_none=True))
|
pangea/services/sanitize.py
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import io
|
@@ -267,7 +271,7 @@ class Sanitize(ServiceBase):
|
|
267
271
|
files: Optional[List[Tuple]] = None
|
268
272
|
if file or file_path:
|
269
273
|
if file_path:
|
270
|
-
file = open(file_path, "rb")
|
274
|
+
file = open(file_path, "rb") # noqa: SIM115
|
271
275
|
if (
|
272
276
|
transfer_method == TransferMethod.POST_URL
|
273
277
|
and file
|
pangea/services/share/share.py
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import enum
|
6
10
|
import io
|
7
|
-
from typing import Dict, List,
|
11
|
+
from typing import Dict, List, Optional, Tuple, Union
|
12
|
+
|
13
|
+
from pydantic import RootModel
|
8
14
|
|
9
15
|
from pangea.config import PangeaConfig
|
10
16
|
from pangea.response import APIRequestModel, PangeaResponse, PangeaResponseResult, TransferMethod
|
@@ -12,8 +18,8 @@ from pangea.services.base import ServiceBase
|
|
12
18
|
from pangea.services.share.file_format import FileFormat
|
13
19
|
from pangea.utils import get_file_size, get_file_upload_params
|
14
20
|
|
15
|
-
Metadata =
|
16
|
-
Tags =
|
21
|
+
Metadata = RootModel[dict[str, str]]
|
22
|
+
Tags = RootModel[list[str]]
|
17
23
|
|
18
24
|
|
19
25
|
class ItemOrder(str, enum.Enum):
|
@@ -916,10 +922,10 @@ class Share(ServiceBase):
|
|
916
922
|
|
917
923
|
def get_archive(
|
918
924
|
self,
|
919
|
-
ids:
|
920
|
-
format:
|
921
|
-
transfer_method:
|
922
|
-
bucket_id:
|
925
|
+
ids: list[str],
|
926
|
+
format: ArchiveFormat | None = None,
|
927
|
+
transfer_method: TransferMethod | None = None,
|
928
|
+
bucket_id: str | None = None,
|
923
929
|
) -> PangeaResponse[GetArchiveResult]:
|
924
930
|
"""
|
925
931
|
Get archive
|
pangea/services/vault/vault.py
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from typing import TYPE_CHECKING,
|
5
|
+
from typing import TYPE_CHECKING, Annotated, Any, Literal, Optional, Union, cast, overload
|
6
6
|
|
7
7
|
from pydantic import Field, TypeAdapter
|
8
|
-
from typing_extensions import Annotated
|
9
8
|
|
10
9
|
from pangea.response import PangeaResponse, PangeaResponseResult
|
11
10
|
from pangea.services.base import ServiceBase
|
@@ -34,7 +33,6 @@ from pangea.services.vault.models.common import (
|
|
34
33
|
EncryptTransformRequest,
|
35
34
|
EncryptTransformResult,
|
36
35
|
ExportEncryptionAlgorithm,
|
37
|
-
ExportEncryptionType,
|
38
36
|
ExportRequest,
|
39
37
|
ExportResult,
|
40
38
|
Folder,
|
@@ -98,7 +96,7 @@ vault_item_adapter: TypeAdapter[VaultItem] = TypeAdapter(VaultItem)
|
|
98
96
|
|
99
97
|
|
100
98
|
class GetBulkResponse(PangeaResponseResult):
|
101
|
-
items:
|
99
|
+
items: list[VaultItem]
|
102
100
|
|
103
101
|
|
104
102
|
class Vault(ServiceBase):
|
@@ -164,7 +162,7 @@ class Vault(ServiceBase):
|
|
164
162
|
Returns:
|
165
163
|
A PangeaResponse where the id of the deleted secret or key
|
166
164
|
is returned in the response.result field.
|
167
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
165
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/delete-post).
|
168
166
|
|
169
167
|
Raises:
|
170
168
|
PangeaAPIException: If an API Error happens
|
@@ -197,7 +195,7 @@ class Vault(ServiceBase):
|
|
197
195
|
Returns:
|
198
196
|
A PangeaResponse where the secret or key
|
199
197
|
is returned in the response.result field.
|
200
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
198
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/get-post).
|
201
199
|
|
202
200
|
Raises:
|
203
201
|
PangeaAPIException: If an API Error happens
|
@@ -285,7 +283,7 @@ class Vault(ServiceBase):
|
|
285
283
|
Returns:
|
286
284
|
A PangeaResponse where a list of secrets or keys
|
287
285
|
is returned in the response.result field.
|
288
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
286
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/list-post).
|
289
287
|
|
290
288
|
Examples:
|
291
289
|
response = vault.list(
|
@@ -344,7 +342,7 @@ class Vault(ServiceBase):
|
|
344
342
|
Returns:
|
345
343
|
A PangeaResponse where the item ID is returned in the
|
346
344
|
response.result field. Available response fields can be found in our
|
347
|
-
[API documentation](https://pangea.cloud/docs/api/vault
|
345
|
+
[API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/update-post).
|
348
346
|
|
349
347
|
Raises:
|
350
348
|
PangeaAPIException: If an API Error happens
|
@@ -1679,7 +1677,7 @@ class Vault(ServiceBase):
|
|
1679
1677
|
Returns:
|
1680
1678
|
A PangeaResponse where the encrypted message in base64 is returned
|
1681
1679
|
in the response.result field. Available response fields can be found
|
1682
|
-
in our [API documentation](https://pangea.cloud/docs/api/vault
|
1680
|
+
in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/encrypt-post).
|
1683
1681
|
|
1684
1682
|
Raises:
|
1685
1683
|
PangeaAPIException: If an API Error happens
|
@@ -1715,7 +1713,7 @@ class Vault(ServiceBase):
|
|
1715
1713
|
|
1716
1714
|
Returns:
|
1717
1715
|
A PangeaResponse where the decrypted message in base64 is returned
|
1718
|
-
in the response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1716
|
+
in the response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/decrypt-post).
|
1719
1717
|
|
1720
1718
|
Raises:
|
1721
1719
|
PangeaAPIException: If an API Error happens
|
@@ -1749,7 +1747,7 @@ class Vault(ServiceBase):
|
|
1749
1747
|
Returns:
|
1750
1748
|
A PangeaResponse where the signature of the message in base64 is
|
1751
1749
|
returned in the response.result field. Available response fields can
|
1752
|
-
be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1750
|
+
be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/sign-post).
|
1753
1751
|
|
1754
1752
|
Raises:
|
1755
1753
|
PangeaAPIException: If an API Error happens
|
@@ -1785,7 +1783,7 @@ class Vault(ServiceBase):
|
|
1785
1783
|
Returns:
|
1786
1784
|
A PangeaResponse where the signature is valid
|
1787
1785
|
is returned in the response.result field.
|
1788
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1786
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/verify-post).
|
1789
1787
|
|
1790
1788
|
Examples:
|
1791
1789
|
response = vault.verify(
|
@@ -1823,7 +1821,7 @@ class Vault(ServiceBase):
|
|
1823
1821
|
Returns:
|
1824
1822
|
A PangeaResponse where the signature is valid
|
1825
1823
|
is returned in the response.result field.
|
1826
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1824
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-jwt#/v1/key/verify/jwt-post).
|
1827
1825
|
|
1828
1826
|
Examples:
|
1829
1827
|
response = vault.jwt_verify(jws="ewogICJhbGciO...")
|
@@ -1848,7 +1846,7 @@ class Vault(ServiceBase):
|
|
1848
1846
|
Returns:
|
1849
1847
|
A PangeaResponse where the signed JSON Web Token (JWS) is returned
|
1850
1848
|
in the response.result field. Available response fields can be found
|
1851
|
-
in our [API documentation](https://pangea.cloud/docs/api/vault
|
1849
|
+
in our [API documentation](https://pangea.cloud/docs/api/vault/v1-jwt#/v1/key/sign/jwt-post).
|
1852
1850
|
|
1853
1851
|
Examples:
|
1854
1852
|
response = vault.jwt_sign(
|
@@ -1878,7 +1876,7 @@ class Vault(ServiceBase):
|
|
1878
1876
|
Returns:
|
1879
1877
|
A PangeaResponse where the JSON Web Key Set (JWKS) object is
|
1880
1878
|
returned in the response.result field. Available response fields can
|
1881
|
-
be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1879
|
+
be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-jwt#/v1/get/jwk-post).
|
1882
1880
|
|
1883
1881
|
Examples:
|
1884
1882
|
response = vault.jwk_get("pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5")
|
@@ -1910,7 +1908,7 @@ class Vault(ServiceBase):
|
|
1910
1908
|
Returns:
|
1911
1909
|
A PangeaResponse where the state change object is returned in the
|
1912
1910
|
response.result field. Available response fields can be found in our
|
1913
|
-
[API documentation](https://pangea.cloud/docs/api/vault
|
1911
|
+
[API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/state/change-post).
|
1914
1912
|
|
1915
1913
|
Raises:
|
1916
1914
|
PangeaAPIException: If an API Error happens
|
@@ -2011,7 +2009,7 @@ class Vault(ServiceBase):
|
|
2011
2009
|
Returns:
|
2012
2010
|
A `PangeaResponse` where the encrypted object is returned in the
|
2013
2011
|
`response.result` field. Available response fields can be found in
|
2014
|
-
our [API documentation](https://pangea.cloud/docs/api/vault
|
2012
|
+
our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/encrypt/structured-post).
|
2015
2013
|
|
2016
2014
|
Raises:
|
2017
2015
|
PangeaAPIException: If an API error happens.
|
@@ -2067,7 +2065,7 @@ class Vault(ServiceBase):
|
|
2067
2065
|
Returns:
|
2068
2066
|
A `PangeaResponse` where the decrypted object is returned in the
|
2069
2067
|
`response.result` field. Available response fields can be found in
|
2070
|
-
our [API documentation](https://pangea.cloud/docs/api/vault
|
2068
|
+
our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/decrypt/structured-post).
|
2071
2069
|
|
2072
2070
|
Examples:
|
2073
2071
|
data = {"field1": [1, 2, "kxcbC9E9IlgVaSCChPWUMgUC3ko=", "6FfI/LCzatLRLNAc8SuBK/TDnGxp"], "field2": "data2"}
|
@@ -2211,7 +2209,7 @@ class Vault(ServiceBase):
|
|
2211
2209
|
Returns:
|
2212
2210
|
A `PangeaResponse` where the exported key is returned in the
|
2213
2211
|
`response.result` field. Available response fields can be found in
|
2214
|
-
our [API documentation](https://pangea.cloud/docs/api/vault
|
2212
|
+
our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/export-post).
|
2215
2213
|
|
2216
2214
|
Raises:
|
2217
2215
|
PangeaAPIException: If an API error happens.
|
pangea/tools.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
3
4
|
|
4
5
|
import enum
|
5
6
|
import io
|
@@ -7,9 +8,10 @@ import json
|
|
7
8
|
import logging
|
8
9
|
import os
|
9
10
|
import sys
|
11
|
+
from collections.abc import Iterator
|
10
12
|
from datetime import datetime, timezone
|
11
13
|
from logging.handlers import TimedRotatingFileHandler
|
12
|
-
from typing import
|
14
|
+
from typing import Optional
|
13
15
|
|
14
16
|
from pangea.config import PangeaConfig
|
15
17
|
from pangea.exceptions import PangeaException
|
@@ -17,6 +19,8 @@ from pangea.services import Audit
|
|
17
19
|
|
18
20
|
|
19
21
|
class TestEnvironment(str, enum.Enum):
|
22
|
+
__test__ = False
|
23
|
+
|
20
24
|
DEVELOP = "DEV"
|
21
25
|
LIVE = "LVE"
|
22
26
|
STAGING = "STG"
|
@@ -28,15 +32,15 @@ class TestEnvironment(str, enum.Enum):
|
|
28
32
|
return str(self.value)
|
29
33
|
|
30
34
|
|
31
|
-
class Root(
|
35
|
+
class Root(dict):
|
32
36
|
size: int
|
33
37
|
tree_name: str
|
34
38
|
|
35
39
|
|
36
|
-
class Event(
|
40
|
+
class Event(dict):
|
37
41
|
membership_proof: str
|
38
42
|
leaf_index: Optional[int]
|
39
|
-
event:
|
43
|
+
event: dict
|
40
44
|
hash: str
|
41
45
|
tree_size: Optional[int]
|
42
46
|
|
@@ -68,7 +72,7 @@ def exit_with_error(message: str):
|
|
68
72
|
sys.exit(1)
|
69
73
|
|
70
74
|
|
71
|
-
def file_events(root_hashes:
|
75
|
+
def file_events(root_hashes: dict[int, str], f: io.TextIOWrapper) -> Iterator[Event]:
|
72
76
|
"""
|
73
77
|
Reads a file containing Events in JSON format with the following fields:
|
74
78
|
- membership_proof: str
|
@@ -111,8 +115,8 @@ def make_aware_datetime(d: datetime) -> datetime:
|
|
111
115
|
return d
|
112
116
|
|
113
117
|
|
114
|
-
def filter_deep_none(data:
|
115
|
-
return {k: v if not isinstance(v,
|
118
|
+
def filter_deep_none(data: dict) -> dict:
|
119
|
+
return {k: v if not isinstance(v, dict) else filter_deep_none(v) for k, v in data.items() if v is not None}
|
116
120
|
|
117
121
|
|
118
122
|
def _load_env_var(env_var_name: str) -> str:
|
@@ -183,7 +187,7 @@ class SequenceFollower:
|
|
183
187
|
self.numbers.remove(min_val)
|
184
188
|
min_val += 1
|
185
189
|
|
186
|
-
def holes(self) ->
|
190
|
+
def holes(self) -> list[int]:
|
187
191
|
if not self.numbers:
|
188
192
|
return []
|
189
193
|
|
@@ -192,7 +196,7 @@ class SequenceFollower:
|
|
192
196
|
return [val for val in range(min_val, max_val) if val not in self.numbers]
|
193
197
|
|
194
198
|
|
195
|
-
loggers:
|
199
|
+
loggers: dict[str, bool] = {}
|
196
200
|
|
197
201
|
|
198
202
|
def logger_set_pangea_config(logger_name: str, level=logging.DEBUG):
|
pangea/utils.py
CHANGED
@@ -60,7 +60,7 @@ def canonicalize(data: dict) -> str:
|
|
60
60
|
return json.dumps(
|
61
61
|
data, ensure_ascii=False, allow_nan=False, separators=(",", ":"), sort_keys=True, default=default_encoder
|
62
62
|
)
|
63
|
-
elif isinstance(data, datetime.datetime
|
63
|
+
elif isinstance(data, (datetime.datetime, datetime.date)):
|
64
64
|
return format_datetime(data)
|
65
65
|
else:
|
66
66
|
return str(data)
|
@@ -151,10 +151,8 @@ def get_crc32c(data: str) -> str:
|
|
151
151
|
|
152
152
|
|
153
153
|
def hash_256_filepath(filepath: str) -> str:
|
154
|
-
|
155
|
-
|
156
|
-
data.close()
|
157
|
-
return hash
|
154
|
+
with open(filepath, "rb") as data:
|
155
|
+
return sha256(data.read()).hexdigest()
|
158
156
|
|
159
157
|
|
160
158
|
def get_prefix(hash: str, len: int = 5):
|