pangea-sdk 6.0.0__py3-none-any.whl → 6.1.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/services/authn.py +171 -14
- pangea/asyncio/services/authz.py +28 -28
- pangea/services/authn/authn.py +177 -18
- pangea/services/authn/models.py +94 -0
- pangea/services/authz.py +65 -30
- {pangea_sdk-6.0.0.dist-info → pangea_sdk-6.1.0.dist-info}/METADATA +1 -1
- {pangea_sdk-6.0.0.dist-info → pangea_sdk-6.1.0.dist-info}/RECORD +9 -9
- {pangea_sdk-6.0.0.dist-info → pangea_sdk-6.1.0.dist-info}/WHEEL +0 -0
pangea/__init__.py
CHANGED
pangea/asyncio/services/authn.py
CHANGED
@@ -2,14 +2,17 @@
|
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from typing import Dict, List, Optional, Union
|
5
|
+
from typing import Dict, List, Literal, Optional, Union
|
6
6
|
|
7
7
|
import pangea.services.authn.models as m
|
8
8
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
9
9
|
from pangea.config import PangeaConfig
|
10
10
|
from pangea.response import PangeaResponse, PangeaResponseResult
|
11
11
|
|
12
|
-
|
12
|
+
__all__ = ["AuthNAsync"]
|
13
|
+
|
14
|
+
|
15
|
+
_SERVICE_NAME = "authn"
|
13
16
|
|
14
17
|
|
15
18
|
class AuthNAsync(ServiceBaseAsync):
|
@@ -35,7 +38,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
35
38
|
authn = AuthNAsync(token=PANGEA_TOKEN, config=authn_config)
|
36
39
|
"""
|
37
40
|
|
38
|
-
service_name =
|
41
|
+
service_name = _SERVICE_NAME
|
39
42
|
|
40
43
|
def __init__(
|
41
44
|
self,
|
@@ -65,7 +68,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
65
68
|
self.agreements = AuthNAsync.AgreementsAsync(token, config, logger_name=logger_name)
|
66
69
|
|
67
70
|
class SessionAsync(ServiceBaseAsync):
|
68
|
-
service_name =
|
71
|
+
service_name = _SERVICE_NAME
|
69
72
|
|
70
73
|
def __init__(
|
71
74
|
self,
|
@@ -162,7 +165,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
162
165
|
)
|
163
166
|
|
164
167
|
class ClientAsync(ServiceBaseAsync):
|
165
|
-
service_name =
|
168
|
+
service_name = _SERVICE_NAME
|
166
169
|
|
167
170
|
def __init__(
|
168
171
|
self,
|
@@ -222,7 +225,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
222
225
|
return await self.request.post("v2/client/jwks", m.ClientJWKSResult, {})
|
223
226
|
|
224
227
|
class SessionAsync(ServiceBaseAsync):
|
225
|
-
service_name =
|
228
|
+
service_name = _SERVICE_NAME
|
226
229
|
|
227
230
|
def __init__(
|
228
231
|
self,
|
@@ -359,7 +362,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
359
362
|
)
|
360
363
|
|
361
364
|
class PasswordAsync(ServiceBaseAsync):
|
362
|
-
service_name =
|
365
|
+
service_name = _SERVICE_NAME
|
363
366
|
|
364
367
|
def __init__(
|
365
368
|
self,
|
@@ -419,7 +422,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
419
422
|
return await self.request.post("v2/user/password/expire", PangeaResponseResult, {"id": user_id})
|
420
423
|
|
421
424
|
class TokenAsync(ServiceBaseAsync):
|
422
|
-
service_name =
|
425
|
+
service_name = _SERVICE_NAME
|
423
426
|
|
424
427
|
def __init__(
|
425
428
|
self,
|
@@ -456,7 +459,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
456
459
|
)
|
457
460
|
|
458
461
|
class UserAsync(ServiceBaseAsync):
|
459
|
-
service_name =
|
462
|
+
service_name = _SERVICE_NAME
|
460
463
|
|
461
464
|
def __init__(
|
462
465
|
self,
|
@@ -667,7 +670,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
667
670
|
return await self.request.post("v2/user/list", m.UserListResult, data=input.model_dump(exclude_none=True))
|
668
671
|
|
669
672
|
class InvitesAsync(ServiceBaseAsync):
|
670
|
-
service_name =
|
673
|
+
service_name = _SERVICE_NAME
|
671
674
|
|
672
675
|
def __init__(
|
673
676
|
self,
|
@@ -739,7 +742,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
739
742
|
)
|
740
743
|
|
741
744
|
class AuthenticatorsAsync(ServiceBaseAsync):
|
742
|
-
service_name =
|
745
|
+
service_name = _SERVICE_NAME
|
743
746
|
|
744
747
|
def __init__(
|
745
748
|
self,
|
@@ -821,7 +824,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
821
824
|
)
|
822
825
|
|
823
826
|
class ProfileAsync(ServiceBaseAsync):
|
824
|
-
service_name =
|
827
|
+
service_name = _SERVICE_NAME
|
825
828
|
|
826
829
|
def __init__(
|
827
830
|
self,
|
@@ -905,8 +908,57 @@ class AuthNAsync(ServiceBaseAsync):
|
|
905
908
|
"v2/user/profile/update", m.UserProfileUpdateResult, data=input.model_dump(exclude_none=True)
|
906
909
|
)
|
907
910
|
|
911
|
+
class GroupAsync(ServiceBaseAsync):
|
912
|
+
service_name = _SERVICE_NAME
|
913
|
+
|
914
|
+
def __init__(
|
915
|
+
self,
|
916
|
+
token: str,
|
917
|
+
config: PangeaConfig | None = None,
|
918
|
+
logger_name: str = "pangea",
|
919
|
+
) -> None:
|
920
|
+
super().__init__(token, config, logger_name=logger_name)
|
921
|
+
|
922
|
+
async def assign(self, user_id: str, group_ids: list[str]) -> PangeaResponse[PangeaResponseResult]:
|
923
|
+
"""
|
924
|
+
Assign groups to a user
|
925
|
+
|
926
|
+
Add a list of groups to a specified user
|
927
|
+
|
928
|
+
OperationId: authn_post_v2_user_group_assign
|
929
|
+
"""
|
930
|
+
return await self.request.post(
|
931
|
+
"v2/user/group/assign",
|
932
|
+
data={"id": user_id, "group_ids": group_ids},
|
933
|
+
result_class=m.PangeaResponseResult,
|
934
|
+
)
|
935
|
+
|
936
|
+
async def remove(self, user_id: str, group_id: str) -> PangeaResponse[PangeaResponseResult]:
|
937
|
+
"""
|
938
|
+
Remove a group assigned to a user
|
939
|
+
|
940
|
+
Remove a group assigned to a user
|
941
|
+
|
942
|
+
OperationId: authn_post_v2_user_group_remove
|
943
|
+
"""
|
944
|
+
return await self.request.post(
|
945
|
+
"v2/user/group/remove",
|
946
|
+
data={"id": user_id, "group_id": group_id},
|
947
|
+
result_class=m.PangeaResponseResult,
|
948
|
+
)
|
949
|
+
|
950
|
+
async def list(self, user_id: str) -> PangeaResponse[m.GroupList]:
|
951
|
+
"""
|
952
|
+
List of groups assigned to a user
|
953
|
+
|
954
|
+
Return a list of ids for groups assigned to a user
|
955
|
+
|
956
|
+
OperationId: authn_post_v2_user_group_list
|
957
|
+
"""
|
958
|
+
return await self.request.post("v2/user/group/list", data={"id": user_id}, result_class=m.GroupList)
|
959
|
+
|
908
960
|
class FlowAsync(ServiceBaseAsync):
|
909
|
-
service_name =
|
961
|
+
service_name = _SERVICE_NAME
|
910
962
|
|
911
963
|
def __init__(
|
912
964
|
self,
|
@@ -1052,7 +1104,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1052
1104
|
)
|
1053
1105
|
|
1054
1106
|
class AgreementsAsync(ServiceBaseAsync):
|
1055
|
-
service_name =
|
1107
|
+
service_name = _SERVICE_NAME
|
1056
1108
|
|
1057
1109
|
def __init__(
|
1058
1110
|
self,
|
@@ -1201,3 +1253,108 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1201
1253
|
return await self.request.post(
|
1202
1254
|
"v2/agreements/update", m.AgreementUpdateResult, data=input.model_dump(exclude_none=True)
|
1203
1255
|
)
|
1256
|
+
|
1257
|
+
class GroupAsync(ServiceBaseAsync):
|
1258
|
+
service_name = _SERVICE_NAME
|
1259
|
+
|
1260
|
+
def __init__(
|
1261
|
+
self,
|
1262
|
+
token: str,
|
1263
|
+
config: PangeaConfig | None = None,
|
1264
|
+
logger_name: str = "pangea",
|
1265
|
+
) -> None:
|
1266
|
+
super().__init__(token, config, logger_name=logger_name)
|
1267
|
+
|
1268
|
+
async def create(
|
1269
|
+
self, name: str, type: str, *, description: str | None = None, attributes: dict[str, str] | None = None
|
1270
|
+
) -> PangeaResponse[m.GroupInfo]:
|
1271
|
+
"""
|
1272
|
+
Create a new group
|
1273
|
+
|
1274
|
+
Create a new group
|
1275
|
+
|
1276
|
+
OperationId: authn_post_v2_group_create
|
1277
|
+
"""
|
1278
|
+
return await self.request.post(
|
1279
|
+
"v2/group/create",
|
1280
|
+
data={"name": name, "type": type, "description": description, "attributes": attributes},
|
1281
|
+
result_class=m.GroupInfo,
|
1282
|
+
)
|
1283
|
+
|
1284
|
+
async def delete(self, id: str) -> PangeaResponse[PangeaResponseResult]:
|
1285
|
+
"""
|
1286
|
+
Delete a group
|
1287
|
+
|
1288
|
+
Delete a group
|
1289
|
+
|
1290
|
+
OperationId: authn_post_v2_group_delete
|
1291
|
+
"""
|
1292
|
+
return await self.request.post("v2/group/delete", data={"id": id}, result_class=PangeaResponseResult)
|
1293
|
+
|
1294
|
+
async def get(self, id: str) -> PangeaResponse[m.GroupInfo]:
|
1295
|
+
"""
|
1296
|
+
Get group information
|
1297
|
+
|
1298
|
+
Look up a group by ID and return its information.
|
1299
|
+
|
1300
|
+
OperationId: authn_post_v2_group_get
|
1301
|
+
"""
|
1302
|
+
return await self.request.post("v2/group/get", data={"id": id}, result_class=m.GroupInfo)
|
1303
|
+
|
1304
|
+
async def list(
|
1305
|
+
self,
|
1306
|
+
*,
|
1307
|
+
filter: m.GroupsFilter | None = None,
|
1308
|
+
last: str | None = None,
|
1309
|
+
order: Literal["asc", "desc"] | None = None,
|
1310
|
+
order_by: Literal["id", "created_at", "updated_at", "name", "type"] | None = None,
|
1311
|
+
size: int | None = None,
|
1312
|
+
) -> PangeaResponse[m.GroupList]:
|
1313
|
+
"""
|
1314
|
+
List groups
|
1315
|
+
|
1316
|
+
Look up groups by name, type, or attributes.
|
1317
|
+
"""
|
1318
|
+
return await self.request.post(
|
1319
|
+
"v2/group/list",
|
1320
|
+
data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
|
1321
|
+
result_class=m.GroupList,
|
1322
|
+
)
|
1323
|
+
|
1324
|
+
async def list_users(
|
1325
|
+
self, id: str, *, last: str | None = None, size: int | None = None
|
1326
|
+
) -> PangeaResponse[m.GroupUserList]:
|
1327
|
+
"""
|
1328
|
+
List of users assigned to a group
|
1329
|
+
|
1330
|
+
Return a list of ids for users assigned to a group
|
1331
|
+
|
1332
|
+
OperationId: authn_post_v2_group_user_list
|
1333
|
+
"""
|
1334
|
+
return await self.request.post(
|
1335
|
+
"v2/group/user/list",
|
1336
|
+
data={"id": id, "last": last, "size": size},
|
1337
|
+
result_class=m.GroupUserList,
|
1338
|
+
)
|
1339
|
+
|
1340
|
+
async def update(
|
1341
|
+
self,
|
1342
|
+
id: str,
|
1343
|
+
*,
|
1344
|
+
name: str | None = None,
|
1345
|
+
description: str | None = None,
|
1346
|
+
type: str | None = None,
|
1347
|
+
attributes: dict[str, str] | None = None,
|
1348
|
+
) -> PangeaResponse[m.GroupInfo]:
|
1349
|
+
"""
|
1350
|
+
Update group information
|
1351
|
+
|
1352
|
+
Update group information
|
1353
|
+
|
1354
|
+
OperationId: authn_post_v2_group_update
|
1355
|
+
"""
|
1356
|
+
return await self.request.post(
|
1357
|
+
"v2/group/update",
|
1358
|
+
data={"id": id, "name": name, "description": description, "type": type, "attributes": attributes},
|
1359
|
+
result_class=m.GroupInfo,
|
1360
|
+
)
|
pangea/asyncio/services/authz.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
|
-
from typing import Any
|
6
|
+
from typing import Any
|
7
7
|
|
8
8
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
9
9
|
from pangea.config import PangeaConfig
|
@@ -73,14 +73,14 @@ class AuthZAsync(ServiceBaseAsync):
|
|
73
73
|
|
74
74
|
super().__init__(token, config, logger_name, config_id=config_id)
|
75
75
|
|
76
|
-
async def tuple_create(self, tuples:
|
76
|
+
async def tuple_create(self, tuples: list[Tuple]) -> PangeaResponse[TupleCreateResult]:
|
77
77
|
"""Create tuples.
|
78
78
|
|
79
79
|
Create tuples in the AuthZ Service. The request will fail if there is no schema
|
80
80
|
or the tuples do not validate against the schema.
|
81
81
|
|
82
82
|
Args:
|
83
|
-
tuples
|
83
|
+
tuples: Tuples to be created.
|
84
84
|
|
85
85
|
Raises:
|
86
86
|
PangeaAPIException: If an API Error happens.
|
@@ -110,10 +110,10 @@ class AuthZAsync(ServiceBaseAsync):
|
|
110
110
|
async def tuple_list(
|
111
111
|
self,
|
112
112
|
filter: TupleListFilter,
|
113
|
-
size:
|
114
|
-
last:
|
115
|
-
order:
|
116
|
-
order_by:
|
113
|
+
size: int | None = None,
|
114
|
+
last: str | None = None,
|
115
|
+
order: ItemOrder | None = None,
|
116
|
+
order_by: TupleOrderBy | None = None,
|
117
117
|
) -> PangeaResponse[TupleListResult]:
|
118
118
|
"""List tuples.
|
119
119
|
|
@@ -122,11 +122,11 @@ class AuthZAsync(ServiceBaseAsync):
|
|
122
122
|
is empty it will return all the tuples.
|
123
123
|
|
124
124
|
Args:
|
125
|
-
filter
|
126
|
-
size
|
127
|
-
last
|
128
|
-
order
|
129
|
-
order_by
|
125
|
+
filter: The filter for listing tuples.
|
126
|
+
size: The size of the result set. Default is None.
|
127
|
+
last: The last token from a previous response. Default is None.
|
128
|
+
order: Order results asc(ending) or desc(ending).
|
129
|
+
order_by: Which field to order results by.
|
130
130
|
|
131
131
|
Raises:
|
132
132
|
PangeaAPIException: If an API Error happens.
|
@@ -144,13 +144,13 @@ class AuthZAsync(ServiceBaseAsync):
|
|
144
144
|
)
|
145
145
|
return await self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
|
146
146
|
|
147
|
-
async def tuple_delete(self, tuples:
|
147
|
+
async def tuple_delete(self, tuples: list[Tuple]) -> PangeaResponse[TupleDeleteResult]:
|
148
148
|
"""Delete tuples.
|
149
149
|
|
150
150
|
Delete tuples in the AuthZ Service.
|
151
151
|
|
152
152
|
Args:
|
153
|
-
tuples
|
153
|
+
tuples: Tuples to be deleted.
|
154
154
|
|
155
155
|
Raises:
|
156
156
|
PangeaAPIException: If an API Error happens.
|
@@ -182,8 +182,8 @@ class AuthZAsync(ServiceBaseAsync):
|
|
182
182
|
resource: Resource,
|
183
183
|
action: str,
|
184
184
|
subject: Subject,
|
185
|
-
debug:
|
186
|
-
attributes:
|
185
|
+
debug: bool | None = None,
|
186
|
+
attributes: dict[str, Any] | None = None,
|
187
187
|
) -> PangeaResponse[CheckResult]:
|
188
188
|
"""Perform a check request.
|
189
189
|
|
@@ -192,9 +192,9 @@ class AuthZAsync(ServiceBaseAsync):
|
|
192
192
|
Args:
|
193
193
|
resource (Resource): The resource to check.
|
194
194
|
action (str): The action to check.
|
195
|
-
subject
|
196
|
-
debug
|
197
|
-
attributes
|
195
|
+
subject: The subject to check.
|
196
|
+
debug: Setting this value to True will provide a detailed analysis of the check.
|
197
|
+
attributes: Additional attributes for the check.
|
198
198
|
|
199
199
|
Raises:
|
200
200
|
PangeaAPIException: If an API Error happens.
|
@@ -217,7 +217,7 @@ class AuthZAsync(ServiceBaseAsync):
|
|
217
217
|
return await self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
|
218
218
|
|
219
219
|
async def list_resources(
|
220
|
-
self, type: str, action: str, subject: Subject, attributes:
|
220
|
+
self, type: str, action: str, subject: Subject, attributes: dict[str, Any] | None = None
|
221
221
|
) -> PangeaResponse[ListResourcesResult]:
|
222
222
|
"""List resources.
|
223
223
|
|
@@ -225,10 +225,10 @@ class AuthZAsync(ServiceBaseAsync):
|
|
225
225
|
type that the subject has access to the action with.
|
226
226
|
|
227
227
|
Args:
|
228
|
-
type
|
229
|
-
action
|
230
|
-
subject
|
231
|
-
attributes
|
228
|
+
type: The type to filter resources.
|
229
|
+
action: The action to filter resources.
|
230
|
+
subject: The subject to filter resources.
|
231
|
+
attributes: A JSON object of attribute data.
|
232
232
|
|
233
233
|
Raises:
|
234
234
|
PangeaAPIException: If an API Error happens.
|
@@ -252,7 +252,7 @@ class AuthZAsync(ServiceBaseAsync):
|
|
252
252
|
)
|
253
253
|
|
254
254
|
async def list_subjects(
|
255
|
-
self, resource: Resource, action: str, attributes:
|
255
|
+
self, resource: Resource, action: str, attributes: dict[str, Any] | None = None
|
256
256
|
) -> PangeaResponse[ListSubjectsResult]:
|
257
257
|
"""List subjects.
|
258
258
|
|
@@ -260,9 +260,9 @@ class AuthZAsync(ServiceBaseAsync):
|
|
260
260
|
access to the action for the given resource.
|
261
261
|
|
262
262
|
Args:
|
263
|
-
resource
|
264
|
-
action
|
265
|
-
attributes
|
263
|
+
resource: The resource to filter subjects.
|
264
|
+
action: The action to filter subjects.
|
265
|
+
attributes: A JSON object of attribute data.
|
266
266
|
|
267
267
|
Raises:
|
268
268
|
PangeaAPIException: If an API Error happens.
|
pangea/services/authn/authn.py
CHANGED
@@ -2,14 +2,17 @@
|
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from typing import Dict, List, Optional, Union
|
5
|
+
from typing import Dict, List, Literal, Optional, Union
|
6
6
|
|
7
7
|
import pangea.services.authn.models as m
|
8
8
|
from pangea.config import PangeaConfig
|
9
9
|
from pangea.response import PangeaResponse, PangeaResponseResult
|
10
10
|
from pangea.services.base import ServiceBase
|
11
11
|
|
12
|
-
|
12
|
+
__all__ = ["AuthN"]
|
13
|
+
|
14
|
+
|
15
|
+
_SERVICE_NAME = "authn"
|
13
16
|
|
14
17
|
|
15
18
|
class AuthN(ServiceBase):
|
@@ -35,7 +38,7 @@ class AuthN(ServiceBase):
|
|
35
38
|
authn = AuthN(token=PANGEA_TOKEN, config=authn_config)
|
36
39
|
"""
|
37
40
|
|
38
|
-
service_name =
|
41
|
+
service_name = _SERVICE_NAME
|
39
42
|
|
40
43
|
def __init__(
|
41
44
|
self,
|
@@ -63,9 +66,10 @@ class AuthN(ServiceBase):
|
|
63
66
|
self.client = AuthN.Client(token, config, logger_name=logger_name)
|
64
67
|
self.session = AuthN.Session(token, config, logger_name=logger_name)
|
65
68
|
self.agreements = AuthN.Agreements(token, config, logger_name=logger_name)
|
69
|
+
self.group = AuthN.Group(token, config, logger_name=logger_name)
|
66
70
|
|
67
71
|
class Session(ServiceBase):
|
68
|
-
service_name =
|
72
|
+
service_name = _SERVICE_NAME
|
69
73
|
|
70
74
|
def __init__(
|
71
75
|
self,
|
@@ -161,7 +165,7 @@ class AuthN(ServiceBase):
|
|
161
165
|
)
|
162
166
|
|
163
167
|
class Client(ServiceBase):
|
164
|
-
service_name =
|
168
|
+
service_name = _SERVICE_NAME
|
165
169
|
|
166
170
|
def __init__(
|
167
171
|
self,
|
@@ -221,7 +225,7 @@ class AuthN(ServiceBase):
|
|
221
225
|
return self.request.post("v2/client/jwks", m.ClientJWKSResult, {})
|
222
226
|
|
223
227
|
class Session(ServiceBase):
|
224
|
-
service_name =
|
228
|
+
service_name = _SERVICE_NAME
|
225
229
|
|
226
230
|
def __init__(
|
227
231
|
self,
|
@@ -359,7 +363,7 @@ class AuthN(ServiceBase):
|
|
359
363
|
)
|
360
364
|
|
361
365
|
class Password(ServiceBase):
|
362
|
-
service_name =
|
366
|
+
service_name = _SERVICE_NAME
|
363
367
|
|
364
368
|
def __init__(
|
365
369
|
self,
|
@@ -419,7 +423,7 @@ class AuthN(ServiceBase):
|
|
419
423
|
return self.request.post("v2/user/password/expire", PangeaResponseResult, {"id": user_id})
|
420
424
|
|
421
425
|
class Token(ServiceBase):
|
422
|
-
service_name =
|
426
|
+
service_name = _SERVICE_NAME
|
423
427
|
|
424
428
|
def __init__(
|
425
429
|
self,
|
@@ -456,18 +460,19 @@ class AuthN(ServiceBase):
|
|
456
460
|
)
|
457
461
|
|
458
462
|
class User(ServiceBase):
|
459
|
-
service_name =
|
463
|
+
service_name = _SERVICE_NAME
|
460
464
|
|
461
465
|
def __init__(
|
462
466
|
self,
|
463
|
-
token,
|
464
|
-
config=None,
|
465
|
-
logger_name="pangea",
|
466
|
-
):
|
467
|
+
token: str,
|
468
|
+
config: PangeaConfig | None = None,
|
469
|
+
logger_name: str = "pangea",
|
470
|
+
) -> None:
|
467
471
|
super().__init__(token, config, logger_name=logger_name)
|
468
472
|
self.profile = AuthN.User.Profile(token, config, logger_name=logger_name)
|
469
473
|
self.authenticators = AuthN.User.Authenticators(token, config, logger_name=logger_name)
|
470
474
|
self.invites = AuthN.User.Invites(token, config, logger_name=logger_name)
|
475
|
+
self.group = AuthN.User.Group(token, config, logger_name=logger_name)
|
471
476
|
|
472
477
|
def create(
|
473
478
|
self,
|
@@ -663,7 +668,7 @@ class AuthN(ServiceBase):
|
|
663
668
|
return self.request.post("v2/user/list", m.UserListResult, data=input.model_dump(exclude_none=True))
|
664
669
|
|
665
670
|
class Invites(ServiceBase):
|
666
|
-
service_name =
|
671
|
+
service_name = _SERVICE_NAME
|
667
672
|
|
668
673
|
def __init__(
|
669
674
|
self,
|
@@ -735,7 +740,7 @@ class AuthN(ServiceBase):
|
|
735
740
|
)
|
736
741
|
|
737
742
|
class Authenticators(ServiceBase):
|
738
|
-
service_name =
|
743
|
+
service_name = _SERVICE_NAME
|
739
744
|
|
740
745
|
def __init__(
|
741
746
|
self,
|
@@ -817,7 +822,7 @@ class AuthN(ServiceBase):
|
|
817
822
|
)
|
818
823
|
|
819
824
|
class Profile(ServiceBase):
|
820
|
-
service_name =
|
825
|
+
service_name = _SERVICE_NAME
|
821
826
|
|
822
827
|
def __init__(
|
823
828
|
self,
|
@@ -901,8 +906,57 @@ class AuthN(ServiceBase):
|
|
901
906
|
"v2/user/profile/update", m.UserProfileUpdateResult, data=input.model_dump(exclude_none=True)
|
902
907
|
)
|
903
908
|
|
909
|
+
class Group(ServiceBase):
|
910
|
+
service_name = _SERVICE_NAME
|
911
|
+
|
912
|
+
def __init__(
|
913
|
+
self,
|
914
|
+
token: str,
|
915
|
+
config: PangeaConfig | None = None,
|
916
|
+
logger_name: str = "pangea",
|
917
|
+
) -> None:
|
918
|
+
super().__init__(token, config, logger_name=logger_name)
|
919
|
+
|
920
|
+
def assign(self, user_id: str, group_ids: list[str]) -> PangeaResponse[PangeaResponseResult]:
|
921
|
+
"""
|
922
|
+
Assign groups to a user
|
923
|
+
|
924
|
+
Add a list of groups to a specified user
|
925
|
+
|
926
|
+
OperationId: authn_post_v2_user_group_assign
|
927
|
+
"""
|
928
|
+
return self.request.post(
|
929
|
+
"v2/user/group/assign",
|
930
|
+
data={"id": user_id, "group_ids": group_ids},
|
931
|
+
result_class=m.PangeaResponseResult,
|
932
|
+
)
|
933
|
+
|
934
|
+
def remove(self, user_id: str, group_id: str) -> PangeaResponse[PangeaResponseResult]:
|
935
|
+
"""
|
936
|
+
Remove a group assigned to a user
|
937
|
+
|
938
|
+
Remove a group assigned to a user
|
939
|
+
|
940
|
+
OperationId: authn_post_v2_user_group_remove
|
941
|
+
"""
|
942
|
+
return self.request.post(
|
943
|
+
"v2/user/group/remove",
|
944
|
+
data={"id": user_id, "group_id": group_id},
|
945
|
+
result_class=m.PangeaResponseResult,
|
946
|
+
)
|
947
|
+
|
948
|
+
def list(self, user_id: str) -> PangeaResponse[m.GroupList]:
|
949
|
+
"""
|
950
|
+
List of groups assigned to a user
|
951
|
+
|
952
|
+
Return a list of ids for groups assigned to a user
|
953
|
+
|
954
|
+
OperationId: authn_post_v2_user_group_list
|
955
|
+
"""
|
956
|
+
return self.request.post("v2/user/group/list", data={"id": user_id}, result_class=m.GroupList)
|
957
|
+
|
904
958
|
class Flow(ServiceBase):
|
905
|
-
service_name =
|
959
|
+
service_name = _SERVICE_NAME
|
906
960
|
|
907
961
|
def __init__(
|
908
962
|
self,
|
@@ -1042,7 +1096,7 @@ class AuthN(ServiceBase):
|
|
1042
1096
|
return self.request.post("v2/flow/update", m.FlowUpdateResult, data=input.model_dump(exclude_none=True))
|
1043
1097
|
|
1044
1098
|
class Agreements(ServiceBase):
|
1045
|
-
service_name =
|
1099
|
+
service_name = _SERVICE_NAME
|
1046
1100
|
|
1047
1101
|
def __init__(
|
1048
1102
|
self,
|
@@ -1192,3 +1246,108 @@ class AuthN(ServiceBase):
|
|
1192
1246
|
return self.request.post(
|
1193
1247
|
"v2/agreements/update", m.AgreementUpdateResult, data=input.model_dump(exclude_none=True)
|
1194
1248
|
)
|
1249
|
+
|
1250
|
+
class Group(ServiceBase):
|
1251
|
+
service_name = _SERVICE_NAME
|
1252
|
+
|
1253
|
+
def __init__(
|
1254
|
+
self,
|
1255
|
+
token: str,
|
1256
|
+
config: PangeaConfig | None = None,
|
1257
|
+
logger_name: str = "pangea",
|
1258
|
+
) -> None:
|
1259
|
+
super().__init__(token, config, logger_name=logger_name)
|
1260
|
+
|
1261
|
+
def create(
|
1262
|
+
self, name: str, type: str, *, description: str | None = None, attributes: dict[str, str] | None = None
|
1263
|
+
) -> PangeaResponse[m.GroupInfo]:
|
1264
|
+
"""
|
1265
|
+
Create a new group
|
1266
|
+
|
1267
|
+
Create a new group
|
1268
|
+
|
1269
|
+
OperationId: authn_post_v2_group_create
|
1270
|
+
"""
|
1271
|
+
return self.request.post(
|
1272
|
+
"v2/group/create",
|
1273
|
+
data={"name": name, "type": type, "description": description, "attributes": attributes},
|
1274
|
+
result_class=m.GroupInfo,
|
1275
|
+
)
|
1276
|
+
|
1277
|
+
def delete(self, id: str) -> PangeaResponse[PangeaResponseResult]:
|
1278
|
+
"""
|
1279
|
+
Delete a group
|
1280
|
+
|
1281
|
+
Delete a group
|
1282
|
+
|
1283
|
+
OperationId: authn_post_v2_group_delete
|
1284
|
+
"""
|
1285
|
+
return self.request.post("v2/group/delete", data={"id": id}, result_class=PangeaResponseResult)
|
1286
|
+
|
1287
|
+
def get(self, id: str) -> PangeaResponse[m.GroupInfo]:
|
1288
|
+
"""
|
1289
|
+
Get group information
|
1290
|
+
|
1291
|
+
Look up a group by ID and return its information.
|
1292
|
+
|
1293
|
+
OperationId: authn_post_v2_group_get
|
1294
|
+
"""
|
1295
|
+
return self.request.post("v2/group/get", data={"id": id}, result_class=m.GroupInfo)
|
1296
|
+
|
1297
|
+
def list(
|
1298
|
+
self,
|
1299
|
+
*,
|
1300
|
+
filter: m.GroupsFilter | None = None,
|
1301
|
+
last: str | None = None,
|
1302
|
+
order: Literal["asc", "desc"] | None = None,
|
1303
|
+
order_by: Literal["id", "created_at", "updated_at", "name", "type"] | None = None,
|
1304
|
+
size: int | None = None,
|
1305
|
+
) -> PangeaResponse[m.GroupList]:
|
1306
|
+
"""
|
1307
|
+
List groups
|
1308
|
+
|
1309
|
+
Look up groups by name, type, or attributes.
|
1310
|
+
"""
|
1311
|
+
return self.request.post(
|
1312
|
+
"v2/group/list",
|
1313
|
+
data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
|
1314
|
+
result_class=m.GroupList,
|
1315
|
+
)
|
1316
|
+
|
1317
|
+
def list_users(
|
1318
|
+
self, id: str, *, last: str | None = None, size: int | None = None
|
1319
|
+
) -> PangeaResponse[m.GroupUserList]:
|
1320
|
+
"""
|
1321
|
+
List of users assigned to a group
|
1322
|
+
|
1323
|
+
Return a list of ids for users assigned to a group
|
1324
|
+
|
1325
|
+
OperationId: authn_post_v2_group_user_list
|
1326
|
+
"""
|
1327
|
+
return self.request.post(
|
1328
|
+
"v2/group/user/list",
|
1329
|
+
data={"id": id, "last": last, "size": size},
|
1330
|
+
result_class=m.GroupUserList,
|
1331
|
+
)
|
1332
|
+
|
1333
|
+
def update(
|
1334
|
+
self,
|
1335
|
+
id: str,
|
1336
|
+
*,
|
1337
|
+
name: str | None = None,
|
1338
|
+
description: str | None = None,
|
1339
|
+
type: str | None = None,
|
1340
|
+
attributes: dict[str, str] | None = None,
|
1341
|
+
) -> PangeaResponse[m.GroupInfo]:
|
1342
|
+
"""
|
1343
|
+
Update group information
|
1344
|
+
|
1345
|
+
Update group information
|
1346
|
+
|
1347
|
+
OperationId: authn_post_v2_group_update
|
1348
|
+
"""
|
1349
|
+
return self.request.post(
|
1350
|
+
"v2/group/update",
|
1351
|
+
data={"id": id, "name": name, "description": description, "type": type, "attributes": attributes},
|
1352
|
+
result_class=m.GroupInfo,
|
1353
|
+
)
|
pangea/services/authn/models.py
CHANGED
@@ -939,3 +939,97 @@ class AgreementUpdateRequest(APIRequestModel):
|
|
939
939
|
|
940
940
|
class AgreementUpdateResult(AgreementInfo):
|
941
941
|
pass
|
942
|
+
|
943
|
+
|
944
|
+
class GroupInfo(PangeaResponseResult):
|
945
|
+
"""A group and its information"""
|
946
|
+
|
947
|
+
id: str
|
948
|
+
name: str
|
949
|
+
type: str
|
950
|
+
|
951
|
+
description: Optional[str] = None
|
952
|
+
attributes: Optional[Dict[str, str]] = None
|
953
|
+
created_at: Optional[str] = None
|
954
|
+
updated_at: Optional[str] = None
|
955
|
+
|
956
|
+
|
957
|
+
class GroupsFilter(APIRequestModel):
|
958
|
+
"""Search filter for groups"""
|
959
|
+
|
960
|
+
created_at: Optional[str] = None
|
961
|
+
"""Only records where created_at equals this value."""
|
962
|
+
|
963
|
+
created_at__gt: Optional[str] = None
|
964
|
+
"""Only records where created_at is greater than this value."""
|
965
|
+
|
966
|
+
created_at__gte: Optional[str] = None
|
967
|
+
"""Only records where created_at is greater than or equal to this value."""
|
968
|
+
|
969
|
+
created_at__lt: Optional[str] = None
|
970
|
+
"""Only records where created_at is less than this value."""
|
971
|
+
|
972
|
+
created_at__lte: Optional[str] = None
|
973
|
+
"""Only records where created_at is less than or equal to this value."""
|
974
|
+
|
975
|
+
created_at__contains: Optional[str] = None
|
976
|
+
"""Only records where created_at includes this value."""
|
977
|
+
|
978
|
+
id: Optional[str] = None
|
979
|
+
"""Only records where id equals this value."""
|
980
|
+
|
981
|
+
id__contains: Optional[List[str]] = None
|
982
|
+
"""Only records where id includes each substring."""
|
983
|
+
|
984
|
+
id__in: Optional[List[str]] = None
|
985
|
+
"""Only records where id equals one of the provided substrings."""
|
986
|
+
|
987
|
+
name: Optional[str] = None
|
988
|
+
"""Only records where name equals this value."""
|
989
|
+
|
990
|
+
name__contains: Optional[List[str]] = None
|
991
|
+
"""Only records where name includes each substring."""
|
992
|
+
|
993
|
+
name__in: Optional[List[str]] = None
|
994
|
+
"""Only records where name equals one of the provided substrings."""
|
995
|
+
|
996
|
+
type: Optional[str] = None
|
997
|
+
"""Only records where type equals this value."""
|
998
|
+
|
999
|
+
type__contains: Optional[List[str]] = None
|
1000
|
+
"""Only records where type includes each substring."""
|
1001
|
+
|
1002
|
+
type__in: Optional[List[str]] = None
|
1003
|
+
"""Only records where type equals one of the provided substrings."""
|
1004
|
+
|
1005
|
+
updated_at: Optional[str] = None
|
1006
|
+
"""Only records where updated_at equals this value."""
|
1007
|
+
|
1008
|
+
updated_at__gt: Optional[str] = None
|
1009
|
+
"""Only records where updated_at is greater than this value."""
|
1010
|
+
|
1011
|
+
updated_at__gte: Optional[str] = None
|
1012
|
+
"""Only records where updated_at is greater than or equal to this value."""
|
1013
|
+
|
1014
|
+
updated_at__lt: Optional[str] = None
|
1015
|
+
"""Only records where updated_at is less than this value."""
|
1016
|
+
|
1017
|
+
updated_at__lte: Optional[str] = None
|
1018
|
+
"""Only records where updated_at is less than or equal to this value."""
|
1019
|
+
|
1020
|
+
updated_at__contains: Optional[str] = None
|
1021
|
+
"""Only records where updated_at includes this value."""
|
1022
|
+
|
1023
|
+
|
1024
|
+
class GroupList(PangeaResponseResult):
|
1025
|
+
groups: List[GroupInfo]
|
1026
|
+
"""List of matching groups"""
|
1027
|
+
|
1028
|
+
count: int
|
1029
|
+
last: Optional[str] = None
|
1030
|
+
|
1031
|
+
|
1032
|
+
class GroupUserList(PangeaResponseResult):
|
1033
|
+
users: List[User]
|
1034
|
+
count: int
|
1035
|
+
last: Optional[str] = None
|
pangea/services/authz.py
CHANGED
@@ -51,6 +51,8 @@ class Tuple(PangeaResponseResult):
|
|
51
51
|
resource: Resource
|
52
52
|
relation: str
|
53
53
|
subject: Subject
|
54
|
+
expires_at: Optional[str] = None
|
55
|
+
"""A time in ISO-8601 format"""
|
54
56
|
|
55
57
|
|
56
58
|
class TupleCreateRequest(APIRequestModel):
|
@@ -63,23 +65,51 @@ class TupleCreateResult(PangeaResponseResult):
|
|
63
65
|
|
64
66
|
class TupleListFilter(APIRequestModel):
|
65
67
|
resource_type: Optional[str] = None
|
68
|
+
"""Only records where resource type equals this value."""
|
66
69
|
resource_type__contains: Optional[List[str]] = None
|
70
|
+
"""Only records where resource type includes each substring."""
|
67
71
|
resource_type__in: Optional[List[str]] = None
|
72
|
+
"""Only records where resource type equals one of the provided substrings."""
|
68
73
|
resource_id: Optional[str] = None
|
74
|
+
"""Only records where resource id equals this value."""
|
69
75
|
resource_id__contains: Optional[List[str]] = None
|
76
|
+
"""Only records where resource id includes each substring."""
|
70
77
|
resource_id__in: Optional[List[str]] = None
|
78
|
+
"""Only records where resource id equals one of the provided substrings."""
|
71
79
|
relation: Optional[str] = None
|
80
|
+
"""Only records where relation equals this value."""
|
72
81
|
relation__contains: Optional[List[str]] = None
|
82
|
+
"""Only records where relation includes each substring."""
|
73
83
|
relation__in: Optional[List[str]] = None
|
84
|
+
"""Only records where relation equals one of the provided substrings."""
|
74
85
|
subject_type: Optional[str] = None
|
86
|
+
"""Only records where subject type equals this value."""
|
75
87
|
subject_type__contains: Optional[List[str]] = None
|
88
|
+
"""Only records where subject type includes each substring."""
|
76
89
|
subject_type__in: Optional[List[str]] = None
|
90
|
+
"""Only records where subject type equals one of the provided substrings."""
|
77
91
|
subject_id: Optional[str] = None
|
92
|
+
"""Only records where subject id equals this value."""
|
78
93
|
subject_id__contains: Optional[List[str]] = None
|
94
|
+
"""Only records where subject id includes each substring."""
|
79
95
|
subject_id__in: Optional[List[str]] = None
|
96
|
+
"""Only records where subject id equals one of the provided substrings."""
|
80
97
|
subject_action: Optional[str] = None
|
98
|
+
"""Only records where subject action equals this value."""
|
81
99
|
subject_action__contains: Optional[List[str]] = None
|
100
|
+
"""Only records where subject action includes each substring."""
|
82
101
|
subject_action__in: Optional[List[str]] = None
|
102
|
+
"""Only records where subject action equals one of the provided substrings."""
|
103
|
+
expires_at: Optional[str] = None
|
104
|
+
"""Only records where expires_at equals this value."""
|
105
|
+
expires_at__gt: Optional[str] = None
|
106
|
+
"""Only records where expires_at is greater than this value."""
|
107
|
+
expires_at__gte: Optional[str] = None
|
108
|
+
"""Only records where expires_at is greater than or equal to this value."""
|
109
|
+
expires_at__lt: Optional[str] = None
|
110
|
+
"""Only records where expires_at is less than this value."""
|
111
|
+
expires_at__lte: Optional[str] = None
|
112
|
+
"""Only records where expires_at is less than or equal to this value."""
|
83
113
|
|
84
114
|
|
85
115
|
class TupleListRequest(APIRequestModel):
|
@@ -109,7 +139,9 @@ class CheckRequest(APIRequestModel):
|
|
109
139
|
action: str
|
110
140
|
subject: Subject
|
111
141
|
debug: Optional[bool] = None
|
142
|
+
"""In the event of an allowed check, return a path that granted access."""
|
112
143
|
attributes: Optional[Dict[str, Any]] = None
|
144
|
+
"""A JSON object of attribute data."""
|
113
145
|
|
114
146
|
|
115
147
|
class DebugPath(APIResponseModel):
|
@@ -145,6 +177,8 @@ class ListSubjectsRequest(APIRequestModel):
|
|
145
177
|
resource: Resource
|
146
178
|
action: str
|
147
179
|
attributes: Optional[Dict[str, Any]] = None
|
180
|
+
debug: Optional[bool] = None
|
181
|
+
"""Return a path for each found subject"""
|
148
182
|
|
149
183
|
|
150
184
|
class ListSubjectsResult(PangeaResponseResult):
|
@@ -194,14 +228,14 @@ class AuthZ(ServiceBase):
|
|
194
228
|
|
195
229
|
super().__init__(token, config, logger_name, config_id=config_id)
|
196
230
|
|
197
|
-
def tuple_create(self, tuples:
|
231
|
+
def tuple_create(self, tuples: list[Tuple]) -> PangeaResponse[TupleCreateResult]:
|
198
232
|
"""Create tuples.
|
199
233
|
|
200
234
|
Create tuples in the AuthZ Service. The request will fail if there is no schema
|
201
235
|
or the tuples do not validate against the schema.
|
202
236
|
|
203
237
|
Args:
|
204
|
-
tuples
|
238
|
+
tuples: Tuples to be created.
|
205
239
|
|
206
240
|
Raises:
|
207
241
|
PangeaAPIException: If an API Error happens.
|
@@ -229,10 +263,10 @@ class AuthZ(ServiceBase):
|
|
229
263
|
def tuple_list(
|
230
264
|
self,
|
231
265
|
filter: TupleListFilter,
|
232
|
-
size:
|
233
|
-
last:
|
234
|
-
order:
|
235
|
-
order_by:
|
266
|
+
size: int | None = None,
|
267
|
+
last: str | None = None,
|
268
|
+
order: ItemOrder | None = None,
|
269
|
+
order_by: TupleOrderBy | None = None,
|
236
270
|
) -> PangeaResponse[TupleListResult]:
|
237
271
|
"""List tuples.
|
238
272
|
|
@@ -241,11 +275,11 @@ class AuthZ(ServiceBase):
|
|
241
275
|
is empty it will return all the tuples.
|
242
276
|
|
243
277
|
Args:
|
244
|
-
filter
|
245
|
-
size
|
246
|
-
last
|
247
|
-
order
|
248
|
-
order_by
|
278
|
+
filter: The filter for listing tuples.
|
279
|
+
size: The size of the result set. Default is None.
|
280
|
+
last: The last token from a previous response. Default is None.
|
281
|
+
order: Order results asc(ending) or desc(ending).
|
282
|
+
order_by: Which field to order results by.
|
249
283
|
|
250
284
|
Raises:
|
251
285
|
PangeaAPIException: If an API Error happens.
|
@@ -263,13 +297,13 @@ class AuthZ(ServiceBase):
|
|
263
297
|
)
|
264
298
|
return self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
|
265
299
|
|
266
|
-
def tuple_delete(self, tuples:
|
300
|
+
def tuple_delete(self, tuples: list[Tuple]) -> PangeaResponse[TupleDeleteResult]:
|
267
301
|
"""Delete tuples.
|
268
302
|
|
269
303
|
Delete tuples in the AuthZ Service.
|
270
304
|
|
271
305
|
Args:
|
272
|
-
tuples
|
306
|
+
tuples: Tuples to be deleted.
|
273
307
|
|
274
308
|
Raises:
|
275
309
|
PangeaAPIException: If an API Error happens.
|
@@ -299,19 +333,19 @@ class AuthZ(ServiceBase):
|
|
299
333
|
resource: Resource,
|
300
334
|
action: str,
|
301
335
|
subject: Subject,
|
302
|
-
debug:
|
303
|
-
attributes:
|
336
|
+
debug: bool | None = None,
|
337
|
+
attributes: dict[str, Any] | None = None,
|
304
338
|
) -> PangeaResponse[CheckResult]:
|
305
339
|
"""Perform a check request.
|
306
340
|
|
307
341
|
Check if a subject has permission to perform an action on the resource.
|
308
342
|
|
309
343
|
Args:
|
310
|
-
resource
|
311
|
-
action
|
312
|
-
subject
|
313
|
-
debug
|
314
|
-
attributes
|
344
|
+
resource: The resource to check.
|
345
|
+
action: The action to check.
|
346
|
+
subject: The subject to check.
|
347
|
+
debug: In the event of an allowed check, return a path that granted access.
|
348
|
+
attributes: Additional attributes for the check.
|
315
349
|
|
316
350
|
Raises:
|
317
351
|
PangeaAPIException: If an API Error happens.
|
@@ -334,7 +368,7 @@ class AuthZ(ServiceBase):
|
|
334
368
|
return self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
|
335
369
|
|
336
370
|
def list_resources(
|
337
|
-
self, type: str, action: str, subject: Subject, attributes:
|
371
|
+
self, type: str, action: str, subject: Subject, attributes: dict[str, Any] | None = None
|
338
372
|
) -> PangeaResponse[ListResourcesResult]:
|
339
373
|
"""List resources.
|
340
374
|
|
@@ -342,10 +376,10 @@ class AuthZ(ServiceBase):
|
|
342
376
|
type that the subject has access to the action with.
|
343
377
|
|
344
378
|
Args:
|
345
|
-
type
|
346
|
-
action
|
347
|
-
subject
|
348
|
-
attributes
|
379
|
+
type: The type to filter resources.
|
380
|
+
action: The action to filter resources.
|
381
|
+
subject: The subject to filter resources.
|
382
|
+
attributes: A JSON object of attribute data.
|
349
383
|
|
350
384
|
Raises:
|
351
385
|
PangeaAPIException: If an API Error happens.
|
@@ -369,7 +403,7 @@ class AuthZ(ServiceBase):
|
|
369
403
|
)
|
370
404
|
|
371
405
|
def list_subjects(
|
372
|
-
self, resource: Resource, action: str, attributes:
|
406
|
+
self, resource: Resource, action: str, attributes: dict[str, Any] | None = None, *, debug: bool | None = None
|
373
407
|
) -> PangeaResponse[ListSubjectsResult]:
|
374
408
|
"""List subjects.
|
375
409
|
|
@@ -377,9 +411,10 @@ class AuthZ(ServiceBase):
|
|
377
411
|
access to the action for the given resource.
|
378
412
|
|
379
413
|
Args:
|
380
|
-
resource
|
381
|
-
action
|
382
|
-
attributes
|
414
|
+
resource: The resource to filter subjects.
|
415
|
+
action: The action to filter subjects.
|
416
|
+
attributes: A JSON object of attribute data.
|
417
|
+
debug: Return a path for each found subject.
|
383
418
|
|
384
419
|
Raises:
|
385
420
|
PangeaAPIException: If an API Error happens.
|
@@ -396,5 +431,5 @@ class AuthZ(ServiceBase):
|
|
396
431
|
)
|
397
432
|
"""
|
398
433
|
|
399
|
-
input_data = ListSubjectsRequest(resource=resource, action=action, attributes=attributes)
|
434
|
+
input_data = ListSubjectsRequest(resource=resource, action=action, attributes=attributes, debug=debug)
|
400
435
|
return self.request.post("v1/list-subjects", ListSubjectsResult, data=input_data.model_dump(exclude_none=True))
|
@@ -1,12 +1,12 @@
|
|
1
|
-
pangea/__init__.py,sha256=
|
1
|
+
pangea/__init__.py,sha256=SsSFodzFjA5wp7MeTcC2YDLJyt4DeR98QUsA7pVkhf0,246
|
2
2
|
pangea/asyncio/__init__.py,sha256=kjEMkqMQ521LlMSu5jn3_WgweyArwVZ2C-s3x7mR6Pk,45
|
3
3
|
pangea/asyncio/file_uploader.py,sha256=wI7epib7Rc5jtZw4eJ1L1SlmutDG6CPv59C8N2UPhtY,1436
|
4
4
|
pangea/asyncio/request.py,sha256=lpLY-o405r3-VUfrAE5uxYxI8UjM4hjPqUzAUtOGE5o,18040
|
5
5
|
pangea/asyncio/services/__init__.py,sha256=L6Tdhjfx_ZECHskhLMPaCcOefi-r-imw6q_zlU4j-FY,464
|
6
6
|
pangea/asyncio/services/ai_guard.py,sha256=rFksT8LQkyioW3QOq4fLCEZbW5SXiYWpWjLbVovRouE,6294
|
7
7
|
pangea/asyncio/services/audit.py,sha256=Ue3KDmTn-a2KsqlzxbakLQJAWiRyLaJrYVi1hO7a6sw,26030
|
8
|
-
pangea/asyncio/services/authn.py,sha256=
|
9
|
-
pangea/asyncio/services/authz.py,sha256=
|
8
|
+
pangea/asyncio/services/authn.py,sha256=apa0kcxmSXH2ChJbTYVFvXTB4cn69cN9O7tW_jOXy_w,52100
|
9
|
+
pangea/asyncio/services/authz.py,sha256=ocImj2g-P9wAo6CqAvZs7YR4wOTUAx0ZWmenKh6HwLk,9691
|
10
10
|
pangea/asyncio/services/base.py,sha256=vRFVcO_uEAGJte3OUUBLD43RoiiFB1vC7SPyN6yEMoA,3158
|
11
11
|
pangea/asyncio/services/embargo.py,sha256=ctzj3kip6xos-Eu3JuOskrCGYC8T3JlsgAopZHiPSXM,3068
|
12
12
|
pangea/asyncio/services/file_scan.py,sha256=PLG1O-PL4Yk9uY9D6NbMrZ5LHg70Z311s7bFe46UMZA,7108
|
@@ -34,9 +34,9 @@ pangea/services/audit/exceptions.py,sha256=bhVuYe4ammacOVxwg98CChxvwZf5FKgR2Dcgq
|
|
34
34
|
pangea/services/audit/models.py,sha256=1h1B9eSYQMYG3f8WNi1UcDX2-impRrET_ErjJYUnj7M,14678
|
35
35
|
pangea/services/audit/signing.py,sha256=5A4hvPtpfP2kMz8bsiiKUACriXbh5dv9gb_rbqiUtuI,5583
|
36
36
|
pangea/services/audit/util.py,sha256=Zq1qvfeplYfhCP_ud5YMvntSB0UvnCdsuYbOzZkHbjg,7620
|
37
|
-
pangea/services/authn/authn.py,sha256=
|
38
|
-
pangea/services/authn/models.py,sha256=
|
39
|
-
pangea/services/authz.py,sha256=
|
37
|
+
pangea/services/authn/authn.py,sha256=AkGyjGz5eHpMkxMn0F-xP94DCV7Ai88yaI4pSqAQ_qc,51021
|
38
|
+
pangea/services/authn/models.py,sha256=EOoseAWVhr7Gy2HHqxqtvyUNimoi6OVc-x9OMxEeRX8,25253
|
39
|
+
pangea/services/authz.py,sha256=fOPucOMdoYee5B4FXYgM8d6HHUeGg8QwiyTfKcD1JCk,14581
|
40
40
|
pangea/services/base.py,sha256=43pWQcR9CeT4sGzgctF3Sy4M_h7DaUzkuZD2Z7CcDUU,3845
|
41
41
|
pangea/services/embargo.py,sha256=9Wfku4td5ORaIENKmnGmS5jxJJIRfWp6Q51L36Jsy0I,3897
|
42
42
|
pangea/services/file_scan.py,sha256=QiO80uKqB_BnAOiYQKznXfxpa5j40qqETE3-zBRT_QE,7813
|
@@ -55,6 +55,6 @@ pangea/services/vault/vault.py,sha256=ow-Zm7PYzfWIfUcA4UNnpeL2DHfZM4C7inRDmNR3zQ
|
|
55
55
|
pangea/tools.py,sha256=icHduOfZLi02UYdGb5Xl1fQqu-PBRB4tiDPT_nL2Q8E,6380
|
56
56
|
pangea/utils.py,sha256=dZ6MwFVEWXUgXvvDg-k6JnvVfsgslvtaBd7ez7afrqk,4983
|
57
57
|
pangea/verify_audit.py,sha256=nSP17OzoSPdvezRExwfcf45H8ZPZnxZu-CbEp3qFJO0,17354
|
58
|
-
pangea_sdk-6.
|
59
|
-
pangea_sdk-6.
|
60
|
-
pangea_sdk-6.
|
58
|
+
pangea_sdk-6.1.0.dist-info/METADATA,sha256=PaLI_RGtc8TJeHm1gv4Mg7sYe8vK1zwEdDHVm_8hr1Y,6886
|
59
|
+
pangea_sdk-6.1.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
60
|
+
pangea_sdk-6.1.0.dist-info/RECORD,,
|
File without changes
|