Skip to content

Commit ce3021f

Browse files
authored
feat: add batch operations for roles and permissions (#789)
* feat: add batch operations for roles and permissions * delete roles batch * delete roles batch
1 parent d0af6f6 commit ce3021f

File tree

8 files changed

+589
-2
lines changed

8 files changed

+589
-2
lines changed

README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,16 +1008,34 @@ descope_client.mgmt.permission.create(
10081008
description="Optional description to briefly explain what this permission allows."
10091009
)
10101010

1011+
# Create a batch of permissions in a single atomic transaction.
1012+
descope_client.mgmt.permission.create_batch(
1013+
permissions=[
1014+
{"name": "Permission 1", "description": "First permission"},
1015+
{"name": "Permission 2", "description": "Second permission"},
1016+
]
1017+
)
1018+
10111019
# Update will override all fields as is. Use carefully.
10121020
descope_client.mgmt.permission.update(
10131021
name="My Permission",
10141022
new_name="My Updated Permission",
10151023
description="A revised description"
10161024
)
10171025

1026+
# Update a batch of permissions in a single atomic transaction.
1027+
descope_client.mgmt.permission.update_batch(
1028+
permissions=[
1029+
{"name": "Permission 1", "newName": "Updated Permission 1", "description": "Updated description"},
1030+
]
1031+
)
1032+
10181033
# Permission deletion cannot be undone. Use carefully.
10191034
descope_client.mgmt.permission.delete("My Updated Permission")
10201035

1036+
# Delete a batch of permissions in a single atomic transaction. Cannot be undone. Use carefully.
1037+
descope_client.mgmt.permission.delete_batch(["Permission 1", "Permission 2"])
1038+
10211039
# Load all permissions
10221040
permissions_resp = descope_client.mgmt.permission.load_all()
10231041
permissions = permissions_resp["permissions"]
@@ -1036,19 +1054,44 @@ descope_client.mgmt.role.create(
10361054
description="Optional description to briefly explain what this role allows.",
10371055
permission_names=["My Updated Permission"],
10381056
tenant_id="Optionally scope this role for this specific tenant. If left empty, the role will be available to all tenants.",
1057+
default=False, # Optional, marks this role as default role
10391058
private=False # Optional, marks this role as private role
10401059
)
10411060

1061+
# Create a batch of roles in a single atomic transaction.
1062+
descope_client.mgmt.role.create_batch(
1063+
roles=[
1064+
{"name": "Role 1", "description": "First role", "permissionNames": ["Permission 1"]},
1065+
{"name": "Role 2", "description": "Second role", "permissionNames": ["Permission 2"], "default": True},
1066+
]
1067+
)
1068+
10421069
# Update will override all fields as is. Use carefully.
10431070
descope_client.mgmt.role.update(
10441071
name="My Role",
10451072
new_name="My Updated Role",
10461073
description="A revised description",
10471074
permission_names=["My Updated Permission", "Another Permission"],
10481075
tenant_id="The tenant ID to which this role is associated, leave empty, if role is a global one",
1076+
default=False, # Optional, marks this role as default role
10491077
private=True # Optional, marks this role as private role
10501078
)
10511079

1080+
# Update a batch of roles in a single atomic transaction.
1081+
descope_client.mgmt.role.update_batch(
1082+
roles=[
1083+
{"name": "Role 1", "newName": "Updated Role 1", "description": "Updated description", "permissionNames": ["Permission 1"]},
1084+
]
1085+
)
1086+
1087+
# Delete a batch of roles in a single atomic transaction. This action is irreversible. Use carefully.
1088+
descope_client.mgmt.role.delete_batch(
1089+
roles=[
1090+
{"name": "Role 1"},
1091+
{"name": "Role 2", "tenantId": "<tenant_id>"},
1092+
]
1093+
)
1094+
10521095
# Role deletion cannot be undone. Use carefully.
10531096
descope_client.mgmt.role.delete("My Updated Role", "<tenant_id>")
10541097

descope/management/common.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,20 @@ class MgmtV1:
197197

198198
# permission
199199
permission_create_path = "/v1/mgmt/permission/create"
200+
permission_create_batch_path = "/v1/mgmt/permission/create/batch"
200201
permission_update_path = "/v1/mgmt/permission/update"
202+
permission_update_batch_path = "/v1/mgmt/permission/update/batch"
201203
permission_delete_path = "/v1/mgmt/permission/delete"
204+
permission_delete_batch_path = "/v1/mgmt/permission/delete/batch"
202205
permission_load_all_path = "/v1/mgmt/permission/all"
203206

204207
# role
205208
role_create_path = "/v1/mgmt/role/create"
209+
role_create_batch_path = "/v1/mgmt/role/create/batch"
206210
role_update_path = "/v1/mgmt/role/update"
211+
role_update_batch_path = "/v1/mgmt/role/update/batch"
207212
role_delete_path = "/v1/mgmt/role/delete"
213+
role_delete_batch_path = "/v1/mgmt/role/delete/batch"
208214
role_load_all_path = "/v1/mgmt/role/all"
209215
role_search_path = "/v1/mgmt/role/search"
210216

descope/management/permission.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Optional
1+
from typing import List, Optional
22

33
from descope._http_base import HTTPBase
44
from descope.management.common import MgmtV1
@@ -25,6 +25,66 @@ def create(
2525
body={"name": name, "description": description},
2626
)
2727

28+
def create_batch(
29+
self,
30+
permissions: List[dict],
31+
):
32+
"""
33+
Create a batch of permissions in a single atomic transaction.
34+
35+
Args:
36+
permissions (List[dict]): List of permission objects, each with:
37+
- name (str): permission name.
38+
- description (str): Optional description.
39+
40+
Raise:
41+
AuthException: raised if creation operation fails
42+
"""
43+
self._http.post(
44+
MgmtV1.permission_create_batch_path,
45+
body={"permissions": permissions},
46+
)
47+
48+
def update_batch(
49+
self,
50+
permissions: List[dict],
51+
):
52+
"""
53+
Update a batch of permissions in a single atomic transaction.
54+
55+
Args:
56+
permissions (List[dict]): List of permission objects, each with:
57+
- name (str): current permission name.
58+
- newName (str): new permission name.
59+
- description (str): Optional new description.
60+
61+
Raise:
62+
AuthException: raised if update operation fails
63+
"""
64+
self._http.post(
65+
MgmtV1.permission_update_batch_path,
66+
body={"permissions": permissions},
67+
)
68+
69+
def delete_batch(
70+
self,
71+
names: List[str],
72+
):
73+
"""
74+
Delete a batch of permissions in a single atomic transaction.
75+
IMPORTANT: This action is irreversible. Use carefully.
76+
77+
Args:
78+
names (List[str]): List of permission names to delete.
79+
80+
Raise:
81+
AuthException: raised if deletion operation fails
82+
"""
83+
self._http.post(
84+
MgmtV1.permission_delete_batch_path,
85+
body={"names": names},
86+
)
87+
2888
def update(
2989
self,
3090
name: str,

descope/management/role.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,76 @@ def create(
4444
},
4545
)
4646

47+
def create_batch(
48+
self,
49+
roles: List[dict],
50+
):
51+
"""
52+
Create a batch of roles in a single atomic transaction.
53+
54+
Args:
55+
roles (List[dict]): List of role objects, each with:
56+
- name (str): role name.
57+
- description (str): Optional description.
58+
- permissionNames (List[str]): Optional list of permission names.
59+
- tenantId (str): Optional tenant ID.
60+
- default (bool): Optional default flag.
61+
- private (bool): Optional private flag.
62+
63+
Raise:
64+
AuthException: raised if creation operation fails
65+
"""
66+
self._http.post(
67+
MgmtV1.role_create_batch_path,
68+
body={"roles": roles},
69+
)
70+
71+
def update_batch(
72+
self,
73+
roles: List[dict],
74+
):
75+
"""
76+
Update a batch of roles in a single atomic transaction.
77+
78+
Args:
79+
roles (List[dict]): List of role objects, each with:
80+
- name (str): current role name.
81+
- newName (str): new role name.
82+
- description (str): Optional new description.
83+
- permissionNames (List[str]): Optional list of permission names.
84+
- tenantId (str): Optional tenant ID.
85+
- default (bool): Optional default flag.
86+
- private (bool): Optional private flag.
87+
88+
Raise:
89+
AuthException: raised if update operation fails
90+
"""
91+
self._http.post(
92+
MgmtV1.role_update_batch_path,
93+
body={"roles": roles},
94+
)
95+
96+
def delete_batch(
97+
self,
98+
roles: List[dict],
99+
):
100+
"""
101+
Delete a batch of roles in a single atomic transaction.
102+
IMPORTANT: This action is irreversible. Use carefully.
103+
104+
Args:
105+
roles (List[dict]): List of role objects to delete, each with:
106+
- name (str): role name.
107+
- tenantId (str): Optional tenant ID.
108+
109+
Raise:
110+
AuthException: raised if deletion operation fails
111+
"""
112+
self._http.post(
113+
MgmtV1.role_delete_batch_path,
114+
body={"roles": roles},
115+
)
116+
47117
def update(
48118
self,
49119
name: str,

samples/management/permission_sample_app.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,24 @@ def main():
2222
except AuthException as e:
2323
logging.info(f"Permission creation failed {e}")
2424

25+
try:
26+
logging.info("Going to create a batch of permissions")
27+
descope_client.mgmt.permission.create_batch(
28+
[
29+
{
30+
"name": "Batch Permission 1",
31+
"description": "First batch permission",
32+
},
33+
{
34+
"name": "Batch Permission 2",
35+
"description": "Second batch permission",
36+
},
37+
]
38+
)
39+
40+
except AuthException as e:
41+
logging.info(f"Permission batch creation failed {e}")
42+
2543
try:
2644
logging.info("Loading all permissions")
2745
permissions_resp = descope_client.mgmt.permission.load_all()
@@ -43,13 +61,37 @@ def main():
4361
except AuthException as e:
4462
logging.info(f"Permission update failed {e}")
4563

64+
try:
65+
logging.info("Updating a batch of permissions")
66+
descope_client.mgmt.permission.update_batch(
67+
[
68+
{
69+
"name": "Batch Permission 1",
70+
"newName": "Updated Batch Permission 1",
71+
"description": "Updated description",
72+
},
73+
]
74+
)
75+
76+
except AuthException as e:
77+
logging.info(f"Permission batch update failed {e}")
78+
4679
try:
4780
logging.info("Deleting newly created permission")
4881
descope_client.mgmt.permission.delete("My Updated Permission")
4982

5083
except AuthException as e:
5184
logging.info(f"Permission deletion failed {e}")
5285

86+
try:
87+
logging.info("Deleting a batch of permissions")
88+
descope_client.mgmt.permission.delete_batch(
89+
["Updated Batch Permission 1", "Batch Permission 2"]
90+
)
91+
92+
except AuthException as e:
93+
logging.info(f"Permission batch deletion failed {e}")
94+
5395
except AuthException:
5496
raise
5597

0 commit comments

Comments
 (0)