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.
Files changed (51) hide show
  1. pangea/__init__.py +9 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +4 -2
  4. pangea/asyncio/request.py +53 -18
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/ai_guard.py +9 -12
  7. pangea/asyncio/services/audit.py +12 -7
  8. pangea/asyncio/services/authn.py +36 -25
  9. pangea/asyncio/services/authz.py +6 -6
  10. pangea/asyncio/services/base.py +4 -0
  11. pangea/asyncio/services/file_scan.py +8 -2
  12. pangea/asyncio/services/intel.py +26 -28
  13. pangea/asyncio/services/redact.py +7 -3
  14. pangea/asyncio/services/sanitize.py +5 -1
  15. pangea/asyncio/services/share.py +5 -1
  16. pangea/asyncio/services/vault.py +19 -15
  17. pangea/audit_logger.py +3 -1
  18. pangea/deep_verify.py +13 -13
  19. pangea/deprecated.py +1 -1
  20. pangea/dump_audit.py +2 -3
  21. pangea/exceptions.py +8 -5
  22. pangea/file_uploader.py +4 -0
  23. pangea/request.py +64 -48
  24. pangea/response.py +21 -18
  25. pangea/services/__init__.py +2 -0
  26. pangea/services/ai_guard.py +35 -24
  27. pangea/services/audit/audit.py +16 -13
  28. pangea/services/audit/models.py +71 -34
  29. pangea/services/audit/signing.py +1 -1
  30. pangea/services/audit/util.py +10 -10
  31. pangea/services/authn/authn.py +36 -25
  32. pangea/services/authn/models.py +10 -56
  33. pangea/services/authz.py +10 -6
  34. pangea/services/base.py +7 -4
  35. pangea/services/embargo.py +6 -0
  36. pangea/services/file_scan.py +8 -2
  37. pangea/services/intel.py +36 -19
  38. pangea/services/redact.py +7 -3
  39. pangea/services/sanitize.py +5 -1
  40. pangea/services/share/share.py +13 -7
  41. pangea/services/vault/models/asymmetric.py +4 -0
  42. pangea/services/vault/models/common.py +4 -0
  43. pangea/services/vault/models/symmetric.py +4 -0
  44. pangea/services/vault/vault.py +17 -19
  45. pangea/tools.py +13 -9
  46. pangea/utils.py +3 -5
  47. pangea/verify_audit.py +23 -27
  48. {pangea_sdk-6.1.0.dist-info → pangea_sdk-6.2.0.dist-info}/METADATA +36 -17
  49. pangea_sdk-6.2.0.dist-info/RECORD +60 -0
  50. {pangea_sdk-6.1.0.dist-info → pangea_sdk-6.2.0.dist-info}/WHEEL +1 -1
  51. pangea_sdk-6.1.0.dist-info/RECORD +0 -60
@@ -1,11 +1,18 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import datetime
6
10
  import enum
7
11
  from typing import Any, Dict, List, Optional, Sequence, Union
8
12
 
13
+ from pydantic import Field
14
+ from typing_extensions import Annotated
15
+
9
16
  from pangea.response import APIRequestModel, APIResponseModel, PangeaDateTime, PangeaResponseResult
10
17
 
11
18
 
@@ -113,20 +120,25 @@ class Event(Dict[str, Any]):
113
120
 
114
121
 
115
122
  class EventEnvelope(APIResponseModel):
116
- """
117
- Contain extra information about an event.
123
+ event: Optional[dict[str, Any]] = None
118
124
 
119
- Arguments:
120
- event -- Event describing auditable activity.
121
- signature -- An optional client-side signature for forgery protection.
122
- public_key -- The base64-encoded ed25519 public key used for the signature, if one is provided
123
- received_at -- A server-supplied timestamp
125
+ signature: Optional[str] = None
126
+ """
127
+ This is the signature of the hash of the canonicalized event that can be
128
+ verified with the public key provided in the public_key field. Signatures
129
+ cannot be used with the redaction feature turned on. If redaction is
130
+ required, the user needs to perform redaction before computing the signature
131
+ that is to be sent with the message. The SDK facilitates this for users.
124
132
  """
125
133
 
126
- event: Dict[str, Any]
127
- signature: Optional[str] = None
128
134
  public_key: Optional[str] = None
129
- received_at: PangeaDateTime
135
+ """
136
+ The base64-encoded ed25519 public key used for the signature, if one is
137
+ provided
138
+ """
139
+
140
+ received_at: Optional[PangeaDateTime] = None
141
+ """A Pangea provided timestamp of when the event was received."""
130
142
 
131
143
 
132
144
  class LogRequest(APIRequestModel):
@@ -177,21 +189,28 @@ class LogBulkRequest(APIRequestModel):
177
189
 
178
190
 
179
191
  class LogResult(PangeaResponseResult):
192
+ envelope: Optional[EventEnvelope] = None
180
193
  """
181
- Result class after an audit log action
182
-
183
- envelope -- Event envelope information.
184
- hash -- Event envelope hash.
185
- unpublished_root -- The current unpublished root.
186
- membership_proof -- A proof for verifying the unpublished root.
187
- consistency_proof -- If prev_root was present in the request, this proof verifies that the new unpublished root is a continuation of the prev_root
194
+ The sealed envelope containing the event that was logged. Includes event
195
+ metadata such as optional client-side signature details and server-added
196
+ timestamps.
188
197
  """
189
198
 
190
- envelope: Optional[EventEnvelope] = None
191
- hash: str
199
+ hash: Annotated[Optional[str], Field(max_length=64, min_length=64)] = None
200
+ """The hash of the event data."""
201
+
192
202
  unpublished_root: Optional[str] = None
203
+ """The current unpublished root."""
204
+
193
205
  membership_proof: Optional[str] = None
206
+ """A proof for verifying that the buffer_root contains the received event"""
207
+
194
208
  consistency_proof: Optional[List[str]] = None
209
+ """
210
+ If prev_buffer_root was present in the request, this proof verifies that the
211
+ new unpublished root is a continuation of prev_unpublished_root
212
+ """
213
+
195
214
  consistency_verification: EventVerification = EventVerification.NONE
196
215
  membership_verification: EventVerification = EventVerification.NONE
197
216
  signature_verification: EventVerification = EventVerification.NONE
@@ -354,29 +373,47 @@ class RootResult(PangeaResponseResult):
354
373
 
355
374
 
356
375
  class SearchEvent(APIResponseModel):
376
+ envelope: EventEnvelope
377
+
378
+ membership_proof: Optional[str] = None
379
+ """A cryptographic proof that the record has been persisted in the log"""
380
+
381
+ hash: Annotated[Optional[str], Field(max_length=64, min_length=64)] = None
382
+ """The record's hash"""
383
+
384
+ published: Optional[bool] = None
385
+ """
386
+ If true, a root has been published after this event. If false, there is no
387
+ published root for this event
357
388
  """
358
- Event information received after a search request
359
389
 
360
- Arguments:
361
- envelope -- Event related information.
362
- hash -- The record's hash.
363
- leaf_index -- The index of the leaf of the Merkle Tree where this record was inserted.
364
- membership_proof -- A cryptographic proof that the record has been persisted in the log.
365
- consistency_verification -- Consistency verification calculated if required.
366
- membership_verification -- Membership verification calculated if required.
367
- signature_verification -- Signature verification calculated if required.
368
- fpe_context -- The context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
390
+ imported: Optional[bool] = None
391
+ """
392
+ If true, the even was imported manually and not logged by the standard
393
+ procedure. Some features such as tamper proofing may not be available
369
394
  """
370
395
 
371
- envelope: EventEnvelope
372
- hash: str
373
- membership_proof: Optional[str] = None
374
- published: Optional[bool] = None
375
396
  leaf_index: Optional[int] = None
397
+ """
398
+ The index of the leaf of the Merkle Tree where this record was inserted or
399
+ null if published=false
400
+ """
401
+
402
+ valid_signature: Optional[bool] = None
403
+ """
404
+ Result of the verification of the Vault signature, if the event was signed
405
+ and the parameter `verify_signature` is `true`
406
+ """
407
+
408
+ fpe_context: Optional[str] = None
409
+ """
410
+ The context data needed to decrypt secure audit events that have been
411
+ redacted with format preserving encryption.
412
+ """
413
+
376
414
  consistency_verification: EventVerification = EventVerification.NONE
377
415
  membership_verification: EventVerification = EventVerification.NONE
378
416
  signature_verification: EventVerification = EventVerification.NONE
379
- fpe_context: Optional[str] = None
380
417
 
381
418
 
382
419
  class SearchResultOutput(PangeaResponseResult):
@@ -81,7 +81,7 @@ class Signer:
81
81
  with open(self.private_key_file, "rb") as file:
82
82
  file_bytes = file.read()
83
83
  except FileNotFoundError:
84
- raise Exception(f"Error: Failed opening private key file {self.private_key_file}")
84
+ raise Exception(f"Error: Failed opening private key file {self.private_key_file}") from None
85
85
 
86
86
  privkey = self._decode_private_key(file_bytes)
87
87
  for cls, signer in signers.items():
@@ -1,5 +1,11 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
7
+ from __future__ import annotations
8
+
3
9
  import base64
4
10
  import json
5
11
  import logging
@@ -155,9 +161,9 @@ def verify_membership_proof(node_hash: Hash, root_hash: Hash, proof: MembershipP
155
161
  def normalize_log(data: dict) -> dict:
156
162
  ans = {}
157
163
  for key in data:
158
- if type(data[key]) == datetime:
164
+ if isinstance(data[key], datetime):
159
165
  ans[key] = format_datetime(data[key])
160
- elif type(data[key]) == dict:
166
+ elif isinstance(data[key], dict):
161
167
  ans[key] = normalize_log(data[key]) # type: ignore[assignment]
162
168
  else:
163
169
  ans[key] = data[key]
@@ -223,9 +229,7 @@ def get_arweave_published_roots(tree_name: str, tree_sizes: Collection[int]) ->
223
229
  }
224
230
  }
225
231
  }
226
- """.replace(
227
- "{tree_sizes}", ", ".join(f'"{tree_size}"' for tree_size in tree_sizes)
228
- ).replace(
232
+ """.replace("{tree_sizes}", ", ".join(f'"{tree_size}"' for tree_size in tree_sizes)).replace(
229
233
  "{tree_name}", tree_name
230
234
  )
231
235
 
@@ -273,8 +277,4 @@ def verify_consistency_proof(new_root: Hash, prev_root: Hash, proof: Consistency
273
277
  return False
274
278
 
275
279
  logger.debug("Verifying the proofs for the new root")
276
- for item in proof:
277
- if not verify_membership_proof(item.node_hash, new_root, item.proof):
278
- return False
279
-
280
- return True
280
+ return all(verify_membership_proof(item.node_hash, new_root, item.proof) for item in proof)
@@ -1,7 +1,12 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
9
+ from collections.abc import Mapping
5
10
  from typing import Dict, List, Literal, Optional, Union
6
11
 
7
12
  import pangea.services.authn.models as m
@@ -128,7 +133,7 @@ class AuthN(ServiceBase):
128
133
  Returns:
129
134
  A PangeaResponse with a list of sessions in the response.result field.
130
135
  Available response fields can be found in our
131
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list).
136
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/session/list-post).
132
137
 
133
138
  Examples:
134
139
  response = authn.session.list()
@@ -192,7 +197,7 @@ class AuthN(ServiceBase):
192
197
  Returns:
193
198
  A PangeaResponse with credentials for a login session in the response.result field.
194
199
  Available response fields can be found in our
195
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo).
200
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/client/userinfo-post).
196
201
 
197
202
  Examples:
198
203
  response = authn.client.userinfo(
@@ -217,7 +222,7 @@ class AuthN(ServiceBase):
217
222
  Returns:
218
223
  A PangeaResponse with jwt verification keys in the response.result field.
219
224
  Available response fields can be found in our
220
- [API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks).
225
+ [API Documentation](https://pangea.cloud/docs/api/authn/jwt#/v2/client/jwks-post).
221
226
 
222
227
  Examples:
223
228
  response = authn.client.jwks()
@@ -290,7 +295,7 @@ class AuthN(ServiceBase):
290
295
  Returns:
291
296
  A PangeaResponse with a list of sessions in the response.result field.
292
297
  Available response fields can be found in our
293
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list).
298
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/list-post).
294
299
 
295
300
  Examples:
296
301
  response = authn.client.session.list(
@@ -349,7 +354,7 @@ class AuthN(ServiceBase):
349
354
  Returns:
350
355
  A PangeaResponse with credentials for a login session in the response.result field.
351
356
  Available response fields can be found in our
352
- [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh).
357
+ [API Documentation](https://pangea.cloud/docs/api/authn/session#/v2/client/session/refresh-post).
353
358
 
354
359
  Examples:
355
360
  response = authn.client.session.refresh(
@@ -447,7 +452,7 @@ class AuthN(ServiceBase):
447
452
  Returns:
448
453
  A PangeaResponse with a token and its information in the response.result field.
449
454
  Available response fields can be found in our
450
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check).
455
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/client/token/check-post).
451
456
 
452
457
  Examples:
453
458
  response = authn.client.token_endpoints.check(
@@ -477,7 +482,7 @@ class AuthN(ServiceBase):
477
482
  def create(
478
483
  self,
479
484
  email: str,
480
- profile: m.Profile,
485
+ profile: Mapping[str, str],
481
486
  *,
482
487
  username: str | None = None,
483
488
  ) -> PangeaResponse[m.UserCreateResult]:
@@ -496,7 +501,7 @@ class AuthN(ServiceBase):
496
501
  Returns:
497
502
  A PangeaResponse with a user and its information in the response.result field.
498
503
  Available response fields can be found in our
499
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create).
504
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/create-post).
500
505
 
501
506
  Examples:
502
507
  response = authn.user.create(
@@ -561,7 +566,7 @@ class AuthN(ServiceBase):
561
566
  Returns:
562
567
  A PangeaResponse with a pending user invitation in the response.result field.
563
568
  Available response fields can be found in our
564
- [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite).
569
+ [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite-post).
565
570
 
566
571
  Examples:
567
572
  response = authn.user.invite(
@@ -606,7 +611,7 @@ class AuthN(ServiceBase):
606
611
  Returns:
607
612
  A PangeaResponse with a user and its information in the response.result field.
608
613
  Available response fields can be found in our
609
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update).
614
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/update-post).
610
615
 
611
616
  Examples:
612
617
  response = authn.user.update(
@@ -649,7 +654,7 @@ class AuthN(ServiceBase):
649
654
  Returns:
650
655
  A PangeaResponse with a list of users in the response.result field.
651
656
  Available response fields can be found in our
652
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list).
657
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/list-post).
653
658
 
654
659
  Examples:
655
660
  response = authn.user.list()
@@ -703,7 +708,7 @@ class AuthN(ServiceBase):
703
708
  Returns:
704
709
  A PangeaResponse with a list of pending user invitations in the response.result field.
705
710
  Available response fields can be found in our
706
- [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list).
711
+ [API Documentation](https://pangea.cloud/docs/api/authn/invite#/v2/user/invite/list-post).
707
712
  Examples:
708
713
  response = authn.user.invites.list()
709
714
  """
@@ -807,7 +812,7 @@ class AuthN(ServiceBase):
807
812
  Returns:
808
813
  A PangeaResponse with a list of authenticators in the response.result field.
809
814
  Available response fields can be found in our
810
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list).
815
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/authenticators/list-post).
811
816
 
812
817
  Examples:
813
818
  response = authn.user.authenticators.list(
@@ -850,7 +855,7 @@ class AuthN(ServiceBase):
850
855
  Returns:
851
856
  A PangeaResponse with a user and its information in the response.result field.
852
857
  Available response fields can be found in our
853
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get).
858
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/get-post).
854
859
 
855
860
  Examples:
856
861
  response = authn.user.profile.get(
@@ -864,7 +869,7 @@ class AuthN(ServiceBase):
864
869
 
865
870
  def update(
866
871
  self,
867
- profile: m.Profile,
872
+ profile: Mapping[str, str],
868
873
  id: str | None = None,
869
874
  email: str | None = None,
870
875
  *,
@@ -886,7 +891,7 @@ class AuthN(ServiceBase):
886
891
  Returns:
887
892
  A PangeaResponse with a user and its information in the response.result field.
888
893
  Available response fields can be found in our
889
- [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update).
894
+ [API Documentation](https://pangea.cloud/docs/api/authn/user#/v2/user/profile/update-post).
890
895
 
891
896
  Examples:
892
897
  response = authn.user.profile.update(
@@ -980,7 +985,7 @@ class AuthN(ServiceBase):
980
985
  Returns:
981
986
  A PangeaResponse with credentials for a login session in the response.result field.
982
987
  Available response fields can be found in our
983
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete).
988
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/complete-post).
984
989
 
985
990
  Examples:
986
991
  response = authn.flow.complete(
@@ -991,7 +996,10 @@ class AuthN(ServiceBase):
991
996
  return self.request.post("v2/flow/complete", m.FlowCompleteResult, data=input.model_dump(exclude_none=True))
992
997
 
993
998
  def restart(
994
- self, flow_id: str, choice: m.FlowChoice, data: m.FlowRestartData = {}
999
+ self,
1000
+ flow_id: str,
1001
+ choice: m.FlowChoice,
1002
+ data: m.FlowRestartData = {}, # noqa: B006
995
1003
  ) -> PangeaResponse[m.FlowRestartResult]:
996
1004
  """
997
1005
  Restart a sign-up/sign-in flow
@@ -1009,7 +1017,7 @@ class AuthN(ServiceBase):
1009
1017
  A PangeaResponse with information about next steps needed
1010
1018
  to complete a flow in the response.result field.
1011
1019
  Available response fields can be found in our
1012
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart).
1020
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/restart-post).
1013
1021
 
1014
1022
  Examples:
1015
1023
  response = authn.flow.restart(
@@ -1046,7 +1054,7 @@ class AuthN(ServiceBase):
1046
1054
  A PangeaResponse with information about next steps needed
1047
1055
  to complete a flow in the response.result field.
1048
1056
  Available response fields can be found in our
1049
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start).
1057
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/start-post).
1050
1058
 
1051
1059
  Examples:
1052
1060
  response = authn.flow.start(
@@ -1062,7 +1070,10 @@ class AuthN(ServiceBase):
1062
1070
  return self.request.post("v2/flow/start", m.FlowStartResult, data=input.model_dump(exclude_none=True))
1063
1071
 
1064
1072
  def update(
1065
- self, flow_id: str, choice: m.FlowChoice, data: m.FlowUpdateData = {}
1073
+ self,
1074
+ flow_id: str,
1075
+ choice: m.FlowChoice,
1076
+ data: m.FlowUpdateData = {}, # noqa: B006
1066
1077
  ) -> PangeaResponse[m.FlowUpdateResult]:
1067
1078
  """
1068
1079
  Update a sign-up/sign-in flow
@@ -1080,7 +1091,7 @@ class AuthN(ServiceBase):
1080
1091
  A PangeaResponse with information about next steps needed
1081
1092
  to complete a flow in the response.result field.
1082
1093
  Available response fields can be found in our
1083
- [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update).
1094
+ [API Documentation](https://pangea.cloud/docs/api/authn/flow#/v2/flow/update-post).
1084
1095
 
1085
1096
  Examples:
1086
1097
  response = authn.flow.update(
@@ -1125,7 +1136,7 @@ class AuthN(ServiceBase):
1125
1136
  Returns:
1126
1137
  A PangeaResponse with a EULA object in the response.result field.
1127
1138
  Available response fields can be found in our
1128
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create).
1139
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/create-post).
1129
1140
 
1130
1141
  Examples:
1131
1142
  response = authn.agreements.create(
@@ -1192,7 +1203,7 @@ class AuthN(ServiceBase):
1192
1203
  Returns:
1193
1204
  A PangeaResponse with a list of EULA objects in the response.result field.
1194
1205
  Available response fields can be found in our
1195
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list).
1206
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/list-post).
1196
1207
 
1197
1208
  Examples:
1198
1209
  response = authn.agreements.list()
@@ -1231,7 +1242,7 @@ class AuthN(ServiceBase):
1231
1242
  Returns:
1232
1243
  A PangeaResponse with the updated EULA object in the response.result field.
1233
1244
  Available response fields can be found in our
1234
- [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update).
1245
+ [API Documentation](https://pangea.cloud/docs/api/authn/agreements#/v2/agreements/update-post).
1235
1246
 
1236
1247
  Examples:
1237
1248
  response = authn.agreements.update(
@@ -1,68 +1,22 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
3
 
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
4
7
  from __future__ import annotations
5
8
 
6
9
  import enum
10
+ from collections.abc import Mapping
7
11
  from typing import Dict, List, NewType, Optional, Union
8
- from warnings import warn
9
-
10
- from typing_extensions import deprecated
11
12
 
12
13
  import pangea.services.intel as im
13
- from pangea.deprecated import pangea_deprecated
14
14
  from pangea.response import APIRequestModel, APIResponseModel, PangeaResponseResult
15
15
  from pangea.services.vault.models.common import JWK, JWKec, JWKrsa
16
16
 
17
17
  Scopes = NewType("Scopes", List[str])
18
18
 
19
19
 
20
- class Profile(Dict[str, str]):
21
- @property
22
- def first_name(self) -> str:
23
- warn(
24
- '`Profile.first_name` is deprecated. Use `Profile["first_name"]` instead.', DeprecationWarning, stacklevel=2
25
- )
26
- return self["first_name"]
27
-
28
- @first_name.setter
29
- def first_name(self, value: str) -> None:
30
- warn(
31
- '`Profile.first_name` is deprecated. Use `Profile["first_name"]` instead.', DeprecationWarning, stacklevel=2
32
- )
33
- self["first_name"] = value
34
-
35
- @property
36
- def last_name(self) -> str:
37
- warn('`Profile.last_name` is deprecated. Use `Profile["last_name"]` instead.', DeprecationWarning, stacklevel=2)
38
- return self["last_name"]
39
-
40
- @last_name.setter
41
- def last_name(self, value: str) -> None:
42
- warn('`Profile.last_name` is deprecated. Use `Profile["last_name"]` instead.', DeprecationWarning, stacklevel=2)
43
- self["last_name"] = value
44
-
45
- @property
46
- def phone(self) -> str:
47
- warn('`Profile.phone` is deprecated. Use `Profile["phone"]` instead.', DeprecationWarning, stacklevel=2)
48
- return self["phone"]
49
-
50
- @phone.setter
51
- def phone(self, value: str) -> None:
52
- warn('`Profile.phone` is deprecated. Use `Profile["phone"]` instead.', DeprecationWarning, stacklevel=2)
53
- self["phone"] = value
54
-
55
- @deprecated("`Profile.model_dump()` is deprecated. `Profile` is already a `dict[str, str]`.")
56
- @pangea_deprecated(reason="`Profile` is already a `dict[str, str]`.")
57
- def model_dump(self, *, exclude_none: bool = False) -> dict[str, str]:
58
- warn(
59
- "`Profile.model_dump()` is deprecated. `Profile` is already a `dict[str, str]`.",
60
- DeprecationWarning,
61
- stacklevel=2,
62
- )
63
- return self
64
-
65
-
66
20
  class ClientPasswordChangeRequest(APIRequestModel):
67
21
  token: str
68
22
  old_password: str
@@ -105,7 +59,7 @@ class SessionToken(PangeaResponseResult):
105
59
  identity: str
106
60
  email: str
107
61
  scopes: Optional[Scopes] = None
108
- profile: Union[Profile, Dict[str, str]]
62
+ profile: dict[str, str]
109
63
  created_at: str
110
64
  intelligence: Optional[Intelligence] = None
111
65
 
@@ -245,7 +199,7 @@ class User(PangeaResponseResult):
245
199
  username: str
246
200
  """A username."""
247
201
 
248
- profile: Union[Profile, Dict[str, str]]
202
+ profile: dict[str, str]
249
203
  """A user profile as a collection of string properties."""
250
204
 
251
205
  verified: bool
@@ -278,7 +232,7 @@ class UserCreateRequest(APIRequestModel):
278
232
  email: str
279
233
  """An email address."""
280
234
 
281
- profile: Union[Profile, Dict[str, str]]
235
+ profile: Mapping[str, str]
282
236
  """A user profile as a collection of string properties."""
283
237
 
284
238
  username: Optional[str] = None
@@ -468,7 +422,7 @@ class UserProfileGetResult(User):
468
422
 
469
423
 
470
424
  class UserProfileUpdateRequest(APIRequestModel):
471
- profile: Union[Profile, Dict[str, str]]
425
+ profile: Mapping[str, str]
472
426
  """Updates to a user profile."""
473
427
 
474
428
  id: Optional[str] = None
@@ -655,7 +609,7 @@ class FlowUpdateDataPassword(APIRequestModel):
655
609
 
656
610
 
657
611
  class FlowUpdateDataProfile(APIRequestModel):
658
- profile: Union[Profile, Dict[str, str]]
612
+ profile: dict[str, str]
659
613
 
660
614
 
661
615
  class FlowUpdateDataProvisionalEnrollment(APIRequestModel):
@@ -777,7 +731,7 @@ class SessionItem(APIResponseModel):
777
731
  expire: str
778
732
  email: str
779
733
  scopes: Optional[Scopes] = None
780
- profile: Union[Profile, Dict[str, str]]
734
+ profile: dict[str, str]
781
735
  created_at: str
782
736
  active_token: Optional[SessionToken] = None
783
737
 
pangea/services/authz.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
@@ -243,7 +247,7 @@ class AuthZ(ServiceBase):
243
247
  Returns:
244
248
  Pangea Response with empty result.
245
249
  Available response fields can be found in our
246
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/create).
250
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/create-post).
247
251
 
248
252
  Examples:
249
253
  response = authz.tuple_create(
@@ -287,7 +291,7 @@ class AuthZ(ServiceBase):
287
291
  Returns:
288
292
  Pangea Response with a list of tuples and the last token.
289
293
  Available response fields can be found in our
290
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/list).
294
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/list-post).
291
295
 
292
296
  Examples:
293
297
  authz.tuple_list(TupleListFilter(subject_type="user", subject_id="user_1"))
@@ -311,7 +315,7 @@ class AuthZ(ServiceBase):
311
315
  Returns:
312
316
  Pangea Response with empty result.
313
317
  Available response fields can be found in our
314
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/delete).
318
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/delete-post).
315
319
 
316
320
  Examples:
317
321
  response = authz.tuple_delete(
@@ -353,7 +357,7 @@ class AuthZ(ServiceBase):
353
357
  Returns:
354
358
  Pangea Response with the result of the check.
355
359
  Available response fields can be found in our
356
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/check).
360
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/check-post).
357
361
 
358
362
  Examples:
359
363
  response = authz.check(
@@ -387,7 +391,7 @@ class AuthZ(ServiceBase):
387
391
  Returns:
388
392
  Pangea Response with a list of resource IDs.
389
393
  Available response fields can be found in our
390
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-resources).
394
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-resources-post).
391
395
 
392
396
  Examples:
393
397
  authz.list_resources(
@@ -422,7 +426,7 @@ class AuthZ(ServiceBase):
422
426
  Returns:
423
427
  Pangea Response with a list of subjects.
424
428
  Available response fields can be found in our
425
- [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-subjects).
429
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-subjects-post).
426
430
 
427
431
  Examples:
428
432
  response = authz.list_subjects(
pangea/services/base.py CHANGED
@@ -1,10 +1,14 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import copy
6
10
  import logging
7
- from typing import Dict, Optional, Type, Union
11
+ from typing import Optional, Type, Union
8
12
 
9
13
  from typing_extensions import TypeVar
10
14
 
@@ -17,7 +21,7 @@ from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult
17
21
  TResult = TypeVar("TResult", bound=PangeaResponseResult, default=PangeaResponseResult)
18
22
 
19
23
 
20
- class ServiceBase(object):
24
+ class ServiceBase:
21
25
  service_name: str = "base"
22
26
 
23
27
  def __init__(
@@ -43,8 +47,7 @@ class ServiceBase(object):
43
47
  self._token = token
44
48
  self.config_id: Optional[str] = config_id
45
49
  self._request: Optional[Union[PangeaRequest, PangeaRequestAsync]] = None
46
- extra_headers: Dict = {}
47
- self.request.set_extra_headers(extra_headers)
50
+ self.request.set_extra_headers({})
48
51
 
49
52
  @property
50
53
  def token(self) -> str: