pangea-sdk 3.8.0b1__py3-none-any.whl → 5.3.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 (48) hide show
  1. pangea/__init__.py +1 -1
  2. pangea/asyncio/file_uploader.py +1 -1
  3. pangea/asyncio/request.py +49 -31
  4. pangea/asyncio/services/__init__.py +2 -0
  5. pangea/asyncio/services/audit.py +192 -31
  6. pangea/asyncio/services/authn.py +187 -109
  7. pangea/asyncio/services/authz.py +285 -0
  8. pangea/asyncio/services/base.py +21 -2
  9. pangea/asyncio/services/embargo.py +2 -2
  10. pangea/asyncio/services/file_scan.py +24 -9
  11. pangea/asyncio/services/intel.py +108 -34
  12. pangea/asyncio/services/redact.py +72 -4
  13. pangea/asyncio/services/sanitize.py +217 -0
  14. pangea/asyncio/services/share.py +246 -73
  15. pangea/asyncio/services/vault.py +1710 -750
  16. pangea/crypto/rsa.py +135 -0
  17. pangea/deep_verify.py +7 -1
  18. pangea/dump_audit.py +9 -8
  19. pangea/request.py +83 -59
  20. pangea/response.py +49 -31
  21. pangea/services/__init__.py +2 -0
  22. pangea/services/audit/audit.py +205 -42
  23. pangea/services/audit/models.py +56 -8
  24. pangea/services/audit/signing.py +6 -5
  25. pangea/services/audit/util.py +3 -3
  26. pangea/services/authn/authn.py +140 -70
  27. pangea/services/authn/models.py +167 -11
  28. pangea/services/authz.py +400 -0
  29. pangea/services/base.py +39 -8
  30. pangea/services/embargo.py +2 -2
  31. pangea/services/file_scan.py +32 -15
  32. pangea/services/intel.py +157 -32
  33. pangea/services/redact.py +152 -4
  34. pangea/services/sanitize.py +388 -0
  35. pangea/services/share/share.py +683 -107
  36. pangea/services/vault/models/asymmetric.py +120 -18
  37. pangea/services/vault/models/common.py +439 -141
  38. pangea/services/vault/models/keys.py +94 -0
  39. pangea/services/vault/models/secret.py +27 -3
  40. pangea/services/vault/models/symmetric.py +68 -22
  41. pangea/services/vault/vault.py +1690 -749
  42. pangea/tools.py +6 -7
  43. pangea/utils.py +16 -27
  44. pangea/verify_audit.py +270 -83
  45. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/METADATA +43 -35
  46. pangea_sdk-5.3.0.dist-info/RECORD +56 -0
  47. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/WHEEL +1 -1
  48. 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))