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.
- pangea/__init__.py +1 -1
- pangea/asyncio/file_uploader.py +1 -1
- pangea/asyncio/request.py +49 -31
- pangea/asyncio/services/__init__.py +2 -0
- pangea/asyncio/services/audit.py +192 -31
- pangea/asyncio/services/authn.py +187 -109
- pangea/asyncio/services/authz.py +285 -0
- pangea/asyncio/services/base.py +21 -2
- pangea/asyncio/services/embargo.py +2 -2
- pangea/asyncio/services/file_scan.py +24 -9
- pangea/asyncio/services/intel.py +108 -34
- pangea/asyncio/services/redact.py +72 -4
- pangea/asyncio/services/sanitize.py +217 -0
- pangea/asyncio/services/share.py +246 -73
- pangea/asyncio/services/vault.py +1710 -750
- pangea/crypto/rsa.py +135 -0
- pangea/deep_verify.py +7 -1
- pangea/dump_audit.py +9 -8
- pangea/request.py +83 -59
- pangea/response.py +49 -31
- pangea/services/__init__.py +2 -0
- pangea/services/audit/audit.py +205 -42
- pangea/services/audit/models.py +56 -8
- pangea/services/audit/signing.py +6 -5
- pangea/services/audit/util.py +3 -3
- pangea/services/authn/authn.py +140 -70
- pangea/services/authn/models.py +167 -11
- pangea/services/authz.py +400 -0
- pangea/services/base.py +39 -8
- pangea/services/embargo.py +2 -2
- pangea/services/file_scan.py +32 -15
- pangea/services/intel.py +157 -32
- pangea/services/redact.py +152 -4
- pangea/services/sanitize.py +388 -0
- pangea/services/share/share.py +683 -107
- pangea/services/vault/models/asymmetric.py +120 -18
- pangea/services/vault/models/common.py +439 -141
- pangea/services/vault/models/keys.py +94 -0
- pangea/services/vault/models/secret.py +27 -3
- pangea/services/vault/models/symmetric.py +68 -22
- pangea/services/vault/vault.py +1690 -749
- pangea/tools.py +6 -7
- pangea/utils.py +16 -27
- pangea/verify_audit.py +270 -83
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/METADATA +43 -35
- pangea_sdk-5.3.0.dist-info/RECORD +56 -0
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.3.0.dist-info}/WHEEL +1 -1
- pangea_sdk-3.8.0b1.dist-info/RECORD +0 -50
pangea/services/authn/models.py
CHANGED
@@ -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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
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
|
-
|
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
|
|
pangea/services/authz.py
ADDED
@@ -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))
|