pangea-sdk 3.8.0b1__py3-none-any.whl → 5.4.0b1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. pangea/__init__.py +1 -1
  2. pangea/asyncio/file_uploader.py +1 -1
  3. pangea/asyncio/request.py +56 -34
  4. pangea/asyncio/services/__init__.py +4 -0
  5. pangea/asyncio/services/ai_guard.py +75 -0
  6. pangea/asyncio/services/audit.py +192 -31
  7. pangea/asyncio/services/authn.py +187 -109
  8. pangea/asyncio/services/authz.py +285 -0
  9. pangea/asyncio/services/base.py +21 -2
  10. pangea/asyncio/services/embargo.py +2 -2
  11. pangea/asyncio/services/file_scan.py +24 -9
  12. pangea/asyncio/services/intel.py +108 -34
  13. pangea/asyncio/services/prompt_guard.py +73 -0
  14. pangea/asyncio/services/redact.py +72 -4
  15. pangea/asyncio/services/sanitize.py +217 -0
  16. pangea/asyncio/services/share.py +246 -73
  17. pangea/asyncio/services/vault.py +1710 -750
  18. pangea/crypto/rsa.py +135 -0
  19. pangea/deep_verify.py +7 -1
  20. pangea/dump_audit.py +9 -8
  21. pangea/request.py +87 -59
  22. pangea/response.py +49 -31
  23. pangea/services/__init__.py +4 -0
  24. pangea/services/ai_guard.py +128 -0
  25. pangea/services/audit/audit.py +205 -42
  26. pangea/services/audit/models.py +56 -8
  27. pangea/services/audit/signing.py +6 -5
  28. pangea/services/audit/util.py +3 -3
  29. pangea/services/authn/authn.py +140 -70
  30. pangea/services/authn/models.py +167 -11
  31. pangea/services/authz.py +400 -0
  32. pangea/services/base.py +39 -8
  33. pangea/services/embargo.py +2 -2
  34. pangea/services/file_scan.py +32 -15
  35. pangea/services/intel.py +157 -32
  36. pangea/services/prompt_guard.py +83 -0
  37. pangea/services/redact.py +152 -4
  38. pangea/services/sanitize.py +371 -0
  39. pangea/services/share/share.py +683 -107
  40. pangea/services/vault/models/asymmetric.py +120 -18
  41. pangea/services/vault/models/common.py +439 -141
  42. pangea/services/vault/models/keys.py +94 -0
  43. pangea/services/vault/models/secret.py +27 -3
  44. pangea/services/vault/models/symmetric.py +68 -22
  45. pangea/services/vault/vault.py +1690 -749
  46. pangea/tools.py +6 -7
  47. pangea/utils.py +16 -27
  48. pangea/verify_audit.py +270 -83
  49. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/METADATA +43 -35
  50. pangea_sdk-5.4.0b1.dist-info/RECORD +60 -0
  51. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/WHEEL +1 -1
  52. pangea_sdk-3.8.0b1.dist-info/RECORD +0 -50
@@ -1,10 +1,16 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
3
 
4
+ from __future__ import annotations
5
+
4
6
  import enum
5
7
  from typing import Dict, List, NewType, Optional, Union
8
+ from warnings import warn
9
+
10
+ from typing_extensions import deprecated
6
11
 
7
12
  import pangea.services.intel as im
13
+ from pangea.deprecated import pangea_deprecated
8
14
  from pangea.response import APIRequestModel, APIResponseModel, PangeaResponseResult
9
15
  from pangea.services.vault.models.common import JWK, JWKec, JWKrsa
10
16
 
@@ -12,9 +18,49 @@ Scopes = NewType("Scopes", List[str])
12
18
 
13
19
 
14
20
  class Profile(Dict[str, str]):
15
- first_name: str
16
- last_name: str
17
- phone: Optional[str] = None
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
18
64
 
19
65
 
20
66
  class ClientPasswordChangeRequest(APIRequestModel):
@@ -59,7 +105,7 @@ class SessionToken(PangeaResponseResult):
59
105
  identity: str
60
106
  email: str
61
107
  scopes: Optional[Scopes] = None
62
- profile: Profile
108
+ profile: Union[Profile, Dict[str, str]]
63
109
  created_at: str
64
110
  intelligence: Optional[Intelligence] = None
65
111
 
@@ -69,7 +115,7 @@ class LoginToken(SessionToken):
69
115
 
70
116
 
71
117
  class ClientTokenCheckResult(SessionToken):
72
- token: Optional[str]
118
+ token: Optional[str] = None
73
119
 
74
120
 
75
121
  class IDProvider(str, enum.Enum):
@@ -150,34 +196,93 @@ class UserListOrderBy(enum.Enum):
150
196
 
151
197
 
152
198
  class Authenticator(APIResponseModel):
199
+ """Authenticator."""
200
+
153
201
  id: str
202
+ """An ID for an authenticator."""
203
+
154
204
  type: str
205
+ """An authentication mechanism."""
206
+
155
207
  enabled: bool
208
+ """Enabled."""
209
+
156
210
  provider: Optional[str] = None
211
+ """Provider."""
212
+
213
+ provider_name: Optional[str] = None
214
+ """Provider name."""
215
+
157
216
  rpid: Optional[str] = None
217
+ """RPID."""
218
+
158
219
  phase: Optional[str] = None
220
+ """Phase."""
221
+
222
+ enrolling_browser: Optional[str] = None
223
+ """Enrolling browser."""
224
+
225
+ enrolling_ip: Optional[str] = None
226
+ """Enrolling IP."""
227
+
228
+ created_at: str
229
+ """A time in ISO-8601 format."""
230
+
231
+ updated_at: str
232
+ """A time in ISO-8601 format."""
233
+
234
+ state: Optional[str] = None
235
+ """State."""
159
236
 
160
237
 
161
238
  class User(PangeaResponseResult):
162
239
  id: str
240
+ """The identity of a user or a service."""
241
+
163
242
  email: str
164
- profile: Profile
243
+ """An email address."""
244
+
245
+ username: str
246
+ """A username."""
247
+
248
+ profile: Union[Profile, Dict[str, str]]
249
+ """A user profile as a collection of string properties."""
250
+
165
251
  verified: bool
252
+ """True if the user's email has been verified."""
253
+
166
254
  disabled: bool
255
+ """True if the service administrator has disabled user account."""
256
+
167
257
  accepted_eula_id: Optional[str] = None
258
+ """An ID for an agreement."""
259
+
168
260
  accepted_privacy_policy_id: Optional[str] = None
261
+ """An ID for an agreement."""
262
+
169
263
  last_login_at: Optional[str] = None
264
+ """A time in ISO-8601 format."""
265
+
170
266
  created_at: str
267
+ """A time in ISO-8601 format."""
268
+
171
269
  login_count: int = 0
172
270
  last_login_ip: Optional[str] = None
173
271
  last_login_city: Optional[str] = None
174
272
  last_login_country: Optional[str] = None
175
273
  authenticators: List[Authenticator] = []
274
+ """A list of authenticators."""
176
275
 
177
276
 
178
277
  class UserCreateRequest(APIRequestModel):
179
278
  email: str
180
- profile: Profile
279
+ """An email address."""
280
+
281
+ profile: Union[Profile, Dict[str, str]]
282
+ """A user profile as a collection of string properties."""
283
+
284
+ username: Optional[str] = None
285
+ """A username."""
181
286
 
182
287
 
183
288
  class UserCreateResult(User):
@@ -186,7 +291,13 @@ class UserCreateResult(User):
186
291
 
187
292
  class UserDeleteRequest(APIRequestModel):
188
293
  email: Optional[str] = None
294
+ """An email address."""
295
+
189
296
  id: Optional[str] = None
297
+ """The identity of a user or a service."""
298
+
299
+ username: Optional[str] = None
300
+ """A username."""
190
301
 
191
302
 
192
303
  class UserDeleteResult(PangeaResponseResult):
@@ -289,7 +400,7 @@ class UserInviterOrderBy(enum.Enum):
289
400
 
290
401
 
291
402
  class UserInviteListFilter(APIRequestModel):
292
- callback: Optional[str]
403
+ callback: Optional[str] = None
293
404
  callback__contains: Optional[List[str]] = None
294
405
  callback__in: Optional[List[str]] = None
295
406
  created_at: Optional[str] = None
@@ -343,7 +454,13 @@ class UserInviteDeleteResult(PangeaResponseResult):
343
454
 
344
455
  class UserProfileGetRequest(APIRequestModel):
345
456
  id: Optional[str] = None
457
+ """The identity of a user or a service."""
458
+
346
459
  email: Optional[str] = None
460
+ """An email address."""
461
+
462
+ username: Optional[str] = None
463
+ """A username."""
347
464
 
348
465
 
349
466
  class UserProfileGetResult(User):
@@ -351,9 +468,17 @@ class UserProfileGetResult(User):
351
468
 
352
469
 
353
470
  class UserProfileUpdateRequest(APIRequestModel):
354
- profile: Profile
471
+ profile: Union[Profile, Dict[str, str]]
472
+ """Updates to a user profile."""
473
+
355
474
  id: Optional[str] = None
475
+ """The identity of a user or a service."""
476
+
356
477
  email: Optional[str] = None
478
+ """An email address."""
479
+
480
+ username: Optional[str] = None
481
+ """A username."""
357
482
 
358
483
 
359
484
  class UserProfileUpdateResult(User):
@@ -362,9 +487,25 @@ class UserProfileUpdateResult(User):
362
487
 
363
488
  class UserUpdateRequest(APIRequestModel):
364
489
  id: Optional[str] = None
490
+ """The identity of a user or a service."""
491
+
365
492
  email: Optional[str] = None
493
+ """An email address."""
494
+
366
495
  disabled: Optional[bool] = None
496
+ """
497
+ New disabled value. Disabling a user account will prevent them from logging
498
+ in.
499
+ """
500
+
367
501
  unlock: Optional[bool] = None
502
+ """
503
+ Unlock a user account if it has been locked out due to failed authentication
504
+ attempts.
505
+ """
506
+
507
+ username: Optional[str] = None
508
+ """A username."""
368
509
 
369
510
 
370
511
  class UserUpdateResult(User):
@@ -386,8 +527,16 @@ class ClientJWKSResult(PangeaResponseResult):
386
527
 
387
528
  class UserAuthenticatorsDeleteRequest(APIRequestModel):
388
529
  id: Optional[str] = None
530
+ """The identity of a user or a service."""
531
+
389
532
  email: Optional[str] = None
533
+ """An email address."""
534
+
390
535
  authenticator_id: str
536
+ """An ID for an authenticator."""
537
+
538
+ username: Optional[str] = None
539
+ """A username."""
391
540
 
392
541
 
393
542
  class UserAuthenticatorsDeleteResult(PangeaResponseResult):
@@ -396,11 +545,18 @@ class UserAuthenticatorsDeleteResult(PangeaResponseResult):
396
545
 
397
546
  class UserAuthenticatorsListRequest(APIRequestModel):
398
547
  email: Optional[str] = None
548
+ """An email address."""
549
+
399
550
  id: Optional[str] = None
551
+ """The identity of a user or a service."""
552
+
553
+ username: Optional[str] = None
554
+ """A username."""
400
555
 
401
556
 
402
557
  class UserAuthenticatorsListResult(PangeaResponseResult):
403
558
  authenticators: List[Authenticator] = []
559
+ """A list of authenticators."""
404
560
 
405
561
 
406
562
  class FlowCompleteRequest(APIRequestModel):
@@ -499,7 +655,7 @@ class FlowUpdateDataPassword(APIRequestModel):
499
655
 
500
656
 
501
657
  class FlowUpdateDataProfile(APIRequestModel):
502
- profile: Profile
658
+ profile: Union[Profile, Dict[str, str]]
503
659
 
504
660
 
505
661
  class FlowUpdateDataProvisionalEnrollment(APIRequestModel):
@@ -621,7 +777,7 @@ class SessionItem(APIResponseModel):
621
777
  expire: str
622
778
  email: str
623
779
  scopes: Optional[Scopes] = None
624
- profile: Profile
780
+ profile: Union[Profile, Dict[str, str]]
625
781
  created_at: str
626
782
  active_token: Optional[SessionToken] = None
627
783
 
@@ -0,0 +1,400 @@
1
+ # Copyright 2022 Pangea Cyber Corporation
2
+ # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
4
+
5
+ import enum
6
+ from typing import Any, Dict, List, Optional, Union
7
+
8
+ from pangea.config import PangeaConfig
9
+ from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
10
+ from pangea.services.base import ServiceBase
11
+
12
+
13
+ class ItemOrder(str, enum.Enum):
14
+ ASC = "asc"
15
+ DESC = "desc"
16
+
17
+ def __str__(self):
18
+ return str(self.value)
19
+
20
+ def __repr__(self):
21
+ return str(self.value)
22
+
23
+
24
+ class TupleOrderBy(str, enum.Enum):
25
+ RESOURCE_TYPE = "resource_type"
26
+ RESOURCE_ID = "resource_id"
27
+ RELATION = "relation"
28
+ SUBJECT_TYPE = "subject_type"
29
+ SUBJECT_ID = "subject_id"
30
+ SUBJECT_ACTION = "subject_action"
31
+
32
+ def __str__(self):
33
+ return str(self.value)
34
+
35
+ def __repr__(self):
36
+ return str(self.value)
37
+
38
+
39
+ class Resource(PangeaResponseResult):
40
+ type: str
41
+ id: Optional[str] = None
42
+
43
+
44
+ class Subject(PangeaResponseResult):
45
+ type: str
46
+ id: Optional[str] = None
47
+ action: Optional[str] = None
48
+
49
+
50
+ class Tuple(PangeaResponseResult):
51
+ resource: Resource
52
+ relation: str
53
+ subject: Subject
54
+
55
+
56
+ class TupleCreateRequest(APIRequestModel):
57
+ tuples: List[Tuple]
58
+
59
+
60
+ class TupleCreateResult(PangeaResponseResult):
61
+ pass
62
+
63
+
64
+ class TupleListFilter(APIRequestModel):
65
+ resource_type: Optional[str] = None
66
+ resource_type__contains: Optional[List[str]] = None
67
+ resource_type__in: Optional[List[str]] = None
68
+ resource_id: Optional[str] = None
69
+ resource_id__contains: Optional[List[str]] = None
70
+ resource_id__in: Optional[List[str]] = None
71
+ relation: Optional[str] = None
72
+ relation__contains: Optional[List[str]] = None
73
+ relation__in: Optional[List[str]] = None
74
+ subject_type: Optional[str] = None
75
+ subject_type__contains: Optional[List[str]] = None
76
+ subject_type__in: Optional[List[str]] = None
77
+ subject_id: Optional[str] = None
78
+ subject_id__contains: Optional[List[str]] = None
79
+ subject_id__in: Optional[List[str]] = None
80
+ subject_action: Optional[str] = None
81
+ subject_action__contains: Optional[List[str]] = None
82
+ subject_action__in: Optional[List[str]] = None
83
+
84
+
85
+ class TupleListRequest(APIRequestModel):
86
+ filter: Optional[Union[Dict, TupleListFilter]] = None
87
+ size: Optional[int] = None
88
+ last: Optional[str] = None
89
+ order: Optional[ItemOrder] = None
90
+ order_by: Optional[TupleOrderBy] = None
91
+
92
+
93
+ class TupleListResult(PangeaResponseResult):
94
+ tuples: List[Tuple]
95
+ last: str
96
+ count: int
97
+
98
+
99
+ class TupleDeleteRequest(APIRequestModel):
100
+ tuples: List[Tuple]
101
+
102
+
103
+ class TupleDeleteResult(PangeaResponseResult):
104
+ pass
105
+
106
+
107
+ class CheckRequest(APIRequestModel):
108
+ resource: Resource
109
+ action: str
110
+ subject: Subject
111
+ debug: Optional[bool] = None
112
+ attributes: Optional[Dict[str, Any]] = None
113
+
114
+
115
+ class DebugPath(APIResponseModel):
116
+ type: str
117
+ id: str
118
+ action: Optional[str] = None
119
+
120
+
121
+ class Debug(APIResponseModel):
122
+ path: List[DebugPath]
123
+
124
+
125
+ class CheckResult(PangeaResponseResult):
126
+ schema_id: str
127
+ schema_version: int
128
+ depth: int
129
+ allowed: bool
130
+ debug: Optional[Debug] = None
131
+
132
+
133
+ class ListResourcesRequest(APIRequestModel):
134
+ type: str
135
+ action: str
136
+ subject: Subject
137
+ attributes: Optional[Dict[str, Any]] = None
138
+
139
+
140
+ class ListResourcesResult(PangeaResponseResult):
141
+ ids: List[str]
142
+
143
+
144
+ class ListSubjectsRequest(APIRequestModel):
145
+ resource: Resource
146
+ action: str
147
+ attributes: Optional[Dict[str, Any]] = None
148
+
149
+
150
+ class ListSubjectsResult(PangeaResponseResult):
151
+ subjects: List[Subject]
152
+
153
+
154
+ class AuthZ(ServiceBase):
155
+ """AuthZ service client.
156
+
157
+ Provides methods to interact with the Pangea AuthZ Service.
158
+ Documentation for the AuthZ Service API can be found at
159
+ <https://pangea.cloud/docs/api/authz>.
160
+
161
+ Examples:
162
+ import os
163
+ from pangea.config import PangeaConfig
164
+ from pangea.services import AuthZ
165
+
166
+ PANGEA_TOKEN = os.getenv("PANGEA_AUTHZ_TOKEN")
167
+
168
+ authz_config = PangeaConfig(domain="aws.us.pangea.cloud")
169
+
170
+ # Setup Pangea AuthZ service client
171
+ authz = AuthZ(token=PANGEA_TOKEN, config=authz_config)
172
+ """
173
+
174
+ service_name = "authz"
175
+
176
+ def __init__(
177
+ self, token: str, config: PangeaConfig | None = None, logger_name: str = "pangea", config_id: str | None = None
178
+ ) -> None:
179
+ """
180
+ AuthZ client
181
+
182
+ Initializes a new AuthZ client.
183
+
184
+ Args:
185
+ token: Pangea API token.
186
+ config: Configuration.
187
+ logger_name: Logger name.
188
+ config_id: Configuration ID.
189
+
190
+ Examples:
191
+ config = PangeaConfig(domain="aws.us.pangea.cloud")
192
+ authz = AuthZ(token="pangea_token", config=config)
193
+ """
194
+
195
+ super().__init__(token, config, logger_name, config_id=config_id)
196
+
197
+ def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateResult]:
198
+ """Create tuples.
199
+
200
+ Create tuples in the AuthZ Service. The request will fail if there is no schema
201
+ or the tuples do not validate against the schema.
202
+
203
+ Args:
204
+ tuples (List[Tuple]): List of tuples to be created.
205
+
206
+ Raises:
207
+ PangeaAPIException: If an API Error happens.
208
+
209
+ Returns:
210
+ Pangea Response with empty result.
211
+ Available response fields can be found in our
212
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/create).
213
+
214
+ Examples:
215
+ response = authz.tuple_create(
216
+ tuples=[
217
+ Tuple(
218
+ resource=Resource(type="file", id="file_1"),
219
+ relation="owner",
220
+ subject=Subject(type="user", id="user_1"),
221
+ )
222
+ ]
223
+ )
224
+ """
225
+
226
+ input_data = TupleCreateRequest(tuples=tuples)
227
+ return self.request.post("v1/tuple/create", TupleCreateResult, data=input_data.model_dump(exclude_none=True))
228
+
229
+ def tuple_list(
230
+ self,
231
+ filter: TupleListFilter,
232
+ size: Optional[int] = None,
233
+ last: Optional[str] = None,
234
+ order: Optional[ItemOrder] = None,
235
+ order_by: Optional[TupleOrderBy] = None,
236
+ ) -> PangeaResponse[TupleListResult]:
237
+ """List tuples.
238
+
239
+ Return a paginated list of filtered tuples. The filter is given in terms
240
+ of a tuple. Fill out the fields that you want to filter. If the filter
241
+ is empty it will return all the tuples.
242
+
243
+ Args:
244
+ filter (TupleListFilter): The filter for listing tuples.
245
+ size (Optional[int]): The size of the result set. Default is None.
246
+ last (Optional[str]): The last token from a previous response. Default is None.
247
+ order (Optional[ItemOrder]): Order results asc(ending) or desc(ending).
248
+ order_by (Optional[TupleOrderBy]): Which field to order results by.
249
+
250
+ Raises:
251
+ PangeaAPIException: If an API Error happens.
252
+
253
+ Returns:
254
+ Pangea Response with a list of tuples and the last token.
255
+ Available response fields can be found in our
256
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/list).
257
+
258
+ Examples:
259
+ authz.tuple_list(TupleListFilter(subject_type="user", subject_id="user_1"))
260
+ """
261
+ input_data = TupleListRequest(
262
+ filter=filter.model_dump(exclude_none=True), size=size, last=last, order=order, order_by=order_by
263
+ )
264
+ return self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
265
+
266
+ def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
267
+ """Delete tuples.
268
+
269
+ Delete tuples in the AuthZ Service.
270
+
271
+ Args:
272
+ tuples (List[Tuple]): List of tuples to be deleted.
273
+
274
+ Raises:
275
+ PangeaAPIException: If an API Error happens.
276
+
277
+ Returns:
278
+ Pangea Response with empty result.
279
+ Available response fields can be found in our
280
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/tuple/delete).
281
+
282
+ Examples:
283
+ response = authz.tuple_delete(
284
+ tuples=[
285
+ Tuple(
286
+ resource=Resource(type="file", id="file_1"),
287
+ relation="owner",
288
+ subject=Subject(type="user", id="user_1"),
289
+ )
290
+ ]
291
+ )
292
+ """
293
+
294
+ input_data = TupleDeleteRequest(tuples=tuples)
295
+ return self.request.post("v1/tuple/delete", TupleDeleteResult, data=input_data.model_dump(exclude_none=True))
296
+
297
+ def check(
298
+ self,
299
+ resource: Resource,
300
+ action: str,
301
+ subject: Subject,
302
+ debug: Optional[bool] = None,
303
+ attributes: Optional[Dict[str, Any]] = None,
304
+ ) -> PangeaResponse[CheckResult]:
305
+ """Perform a check request.
306
+
307
+ Check if a subject has permission to perform an action on the resource.
308
+
309
+ Args:
310
+ resource (Resource): The resource to check.
311
+ action (str): The action to check.
312
+ subject (Subject): The subject to check.
313
+ debug (Optional[bool]): Setting this value to True will provide a detailed analysis of the check.
314
+ attributes (Optional[Dict[str, Any]]): Additional attributes for the check.
315
+
316
+ Raises:
317
+ PangeaAPIException: If an API Error happens.
318
+
319
+ Returns:
320
+ Pangea Response with the result of the check.
321
+ Available response fields can be found in our
322
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/check).
323
+
324
+ Examples:
325
+ response = authz.check(
326
+ resource=Resource(type="file", id="file_1"),
327
+ action="update",
328
+ subject=Subject(type="user", id="user_1"),
329
+ debug=True,
330
+ )
331
+ """
332
+
333
+ input_data = CheckRequest(resource=resource, action=action, subject=subject, debug=debug, attributes=attributes)
334
+ return self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
335
+
336
+ def list_resources(
337
+ self, type: str, action: str, subject: Subject, attributes: Optional[Dict[str, Any]] = None
338
+ ) -> PangeaResponse[ListResourcesResult]:
339
+ """List resources.
340
+
341
+ Given a type, action, and subject, list all the resources in the
342
+ type that the subject has access to the action with.
343
+
344
+ Args:
345
+ type (str): The type to filter resources.
346
+ action (str): The action to filter resources.
347
+ subject (Subject): The subject to filter resources.
348
+ attributes (Optional[Dict[str, Any]]): A JSON object of attribute data.
349
+
350
+ Raises:
351
+ PangeaAPIException: If an API Error happens.
352
+
353
+ Returns:
354
+ Pangea Response with a list of resource IDs.
355
+ Available response fields can be found in our
356
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-resources).
357
+
358
+ Examples:
359
+ authz.list_resources(
360
+ type="file",
361
+ action="update",
362
+ subject=Subject(type="user", id="user_1"),
363
+ )
364
+ """
365
+
366
+ input_data = ListResourcesRequest(type=type, action=action, subject=subject, attributes=attributes)
367
+ return self.request.post(
368
+ "v1/list-resources", ListResourcesResult, data=input_data.model_dump(exclude_none=True)
369
+ )
370
+
371
+ def list_subjects(
372
+ self, resource: Resource, action: str, attributes: Optional[Dict[str, Any]] = None
373
+ ) -> PangeaResponse[ListSubjectsResult]:
374
+ """List subjects.
375
+
376
+ Given a resource and an action, return the list of subjects who have
377
+ access to the action for the given resource.
378
+
379
+ Args:
380
+ resource (Resource): The resource to filter subjects.
381
+ action (str): The action to filter subjects.
382
+ attributes (Optional[Dict[str, Any]]): A JSON object of attribute data.
383
+
384
+ Raises:
385
+ PangeaAPIException: If an API Error happens.
386
+
387
+ Returns:
388
+ Pangea Response with a list of subjects.
389
+ Available response fields can be found in our
390
+ [API Documentation](https://pangea.cloud/docs/api/authz#/v1/list-subjects).
391
+
392
+ Examples:
393
+ response = authz.list_subjects(
394
+ resource=Resource(type="file", id="file_1"),
395
+ action="update",
396
+ )
397
+ """
398
+
399
+ input_data = ListSubjectsRequest(resource=resource, action=action, attributes=attributes)
400
+ return self.request.post("v1/list-subjects", ListSubjectsResult, data=input_data.model_dump(exclude_none=True))