Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1008,16 +1008,34 @@ descope_client.mgmt.permission.create(
description="Optional description to briefly explain what this permission allows."
)

# Create a batch of permissions in a single atomic transaction.
descope_client.mgmt.permission.create_batch(
permissions=[
{"name": "Permission 1", "description": "First permission"},
{"name": "Permission 2", "description": "Second permission"},
]
)

# Update will override all fields as is. Use carefully.
descope_client.mgmt.permission.update(
name="My Permission",
new_name="My Updated Permission",
description="A revised description"
)

# Update a batch of permissions in a single atomic transaction.
descope_client.mgmt.permission.update_batch(
permissions=[
{"name": "Permission 1", "newName": "Updated Permission 1", "description": "Updated description"},
]
)

# Permission deletion cannot be undone. Use carefully.
descope_client.mgmt.permission.delete("My Updated Permission")

# Delete a batch of permissions in a single atomic transaction. Cannot be undone. Use carefully.
descope_client.mgmt.permission.delete_batch(["Permission 1", "Permission 2"])

# Load all permissions
permissions_resp = descope_client.mgmt.permission.load_all()
permissions = permissions_resp["permissions"]
Expand All @@ -1036,19 +1054,44 @@ descope_client.mgmt.role.create(
description="Optional description to briefly explain what this role allows.",
permission_names=["My Updated Permission"],
tenant_id="Optionally scope this role for this specific tenant. If left empty, the role will be available to all tenants.",
default=False, # Optional, marks this role as default role
private=False # Optional, marks this role as private role
)

# Create a batch of roles in a single atomic transaction.
descope_client.mgmt.role.create_batch(
roles=[
{"name": "Role 1", "description": "First role", "permissionNames": ["Permission 1"]},
{"name": "Role 2", "description": "Second role", "permissionNames": ["Permission 2"], "default": True},
]
)

# Update will override all fields as is. Use carefully.
descope_client.mgmt.role.update(
name="My Role",
new_name="My Updated Role",
description="A revised description",
permission_names=["My Updated Permission", "Another Permission"],
tenant_id="The tenant ID to which this role is associated, leave empty, if role is a global one",
default=False, # Optional, marks this role as default role
private=True # Optional, marks this role as private role
)

# Update a batch of roles in a single atomic transaction.
descope_client.mgmt.role.update_batch(
roles=[
{"name": "Role 1", "newName": "Updated Role 1", "description": "Updated description", "permissionNames": ["Permission 1"]},
]
)

# Delete a batch of roles in a single atomic transaction. This action is irreversible. Use carefully.
descope_client.mgmt.role.delete_batch(
roles=[
{"name": "Role 1"},
{"name": "Role 2", "tenantId": "<tenant_id>"},
]
)

# Role deletion cannot be undone. Use carefully.
descope_client.mgmt.role.delete("My Updated Role", "<tenant_id>")

Expand Down
6 changes: 6 additions & 0 deletions descope/management/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,20 @@ class MgmtV1:

# permission
permission_create_path = "/v1/mgmt/permission/create"
permission_create_batch_path = "/v1/mgmt/permission/create/batch"
permission_update_path = "/v1/mgmt/permission/update"
permission_update_batch_path = "/v1/mgmt/permission/update/batch"
permission_delete_path = "/v1/mgmt/permission/delete"
permission_delete_batch_path = "/v1/mgmt/permission/delete/batch"
permission_load_all_path = "/v1/mgmt/permission/all"

# role
role_create_path = "/v1/mgmt/role/create"
role_create_batch_path = "/v1/mgmt/role/create/batch"
role_update_path = "/v1/mgmt/role/update"
role_update_batch_path = "/v1/mgmt/role/update/batch"
role_delete_path = "/v1/mgmt/role/delete"
role_delete_batch_path = "/v1/mgmt/role/delete/batch"
role_load_all_path = "/v1/mgmt/role/all"
role_search_path = "/v1/mgmt/role/search"

Expand Down
62 changes: 61 additions & 1 deletion descope/management/permission.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional
from typing import List, Optional

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

def create_batch(
self,
permissions: List[dict],
):
"""
Create a batch of permissions in a single atomic transaction.

Args:
permissions (List[dict]): List of permission objects, each with:
- name (str): permission name.
- description (str): Optional description.

Raise:
AuthException: raised if creation operation fails
"""
self._http.post(
MgmtV1.permission_create_batch_path,
body={"permissions": permissions},
)

def update_batch(
self,
permissions: List[dict],
):
"""
Update a batch of permissions in a single atomic transaction.

Args:
permissions (List[dict]): List of permission objects, each with:
- name (str): current permission name.
- newName (str): new permission name.
- description (str): Optional new description.

Raise:
AuthException: raised if update operation fails
"""
self._http.post(
MgmtV1.permission_update_batch_path,
body={"permissions": permissions},
)

def delete_batch(
self,
names: List[str],
):
"""
Delete a batch of permissions in a single atomic transaction.
IMPORTANT: This action is irreversible. Use carefully.

Args:
names (List[str]): List of permission names to delete.

Raise:
AuthException: raised if deletion operation fails
"""
self._http.post(
MgmtV1.permission_delete_batch_path,
body={"names": names},
)

def update(
self,
name: str,
Expand Down
70 changes: 70 additions & 0 deletions descope/management/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,76 @@ def create(
},
)

def create_batch(
self,
roles: List[dict],
):
"""
Create a batch of roles in a single atomic transaction.

Args:
roles (List[dict]): List of role objects, each with:
- name (str): role name.
- description (str): Optional description.
- permissionNames (List[str]): Optional list of permission names.
- tenantId (str): Optional tenant ID.
- default (bool): Optional default flag.
- private (bool): Optional private flag.

Raise:
AuthException: raised if creation operation fails
"""
self._http.post(
MgmtV1.role_create_batch_path,
body={"roles": roles},
)

def update_batch(
self,
roles: List[dict],
):
"""
Update a batch of roles in a single atomic transaction.

Args:
roles (List[dict]): List of role objects, each with:
- name (str): current role name.
- newName (str): new role name.
- description (str): Optional new description.
- permissionNames (List[str]): Optional list of permission names.
- tenantId (str): Optional tenant ID.
- default (bool): Optional default flag.
- private (bool): Optional private flag.

Raise:
AuthException: raised if update operation fails
"""
self._http.post(
MgmtV1.role_update_batch_path,
body={"roles": roles},
)

def delete_batch(
self,
roles: List[dict],
):
"""
Delete a batch of roles in a single atomic transaction.
IMPORTANT: This action is irreversible. Use carefully.

Args:
roles (List[dict]): List of role objects to delete, each with:
- name (str): role name.
- tenantId (str): Optional tenant ID.

Raise:
AuthException: raised if deletion operation fails
"""
self._http.post(
MgmtV1.role_delete_batch_path,
body={"roles": roles},
)

def update(
self,
name: str,
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ black = [
[tool.poetry.group.types.dependencies]
mypy = "1.11.2"
types-requests = "2.32.0.20240914"
types-setuptools = "75.1.0.20240917"
types-setuptools = "75.8.2.20250305"

[tool.poetry.group.tests.dependencies]
pytest = "8.3.5"
Expand Down
42 changes: 42 additions & 0 deletions samples/management/permission_sample_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ def main():
except AuthException as e:
logging.info(f"Permission creation failed {e}")

try:
logging.info("Going to create a batch of permissions")
descope_client.mgmt.permission.create_batch(
[
{
"name": "Batch Permission 1",
"description": "First batch permission",
},
{
"name": "Batch Permission 2",
"description": "Second batch permission",
},
]
)

except AuthException as e:
logging.info(f"Permission batch creation failed {e}")

try:
logging.info("Loading all permissions")
permissions_resp = descope_client.mgmt.permission.load_all()
Expand All @@ -43,13 +61,37 @@ def main():
except AuthException as e:
logging.info(f"Permission update failed {e}")

try:
logging.info("Updating a batch of permissions")
descope_client.mgmt.permission.update_batch(
[
{
"name": "Batch Permission 1",
"newName": "Updated Batch Permission 1",
"description": "Updated description",
},
]
)

except AuthException as e:
logging.info(f"Permission batch update failed {e}")

try:
logging.info("Deleting newly created permission")
descope_client.mgmt.permission.delete("My Updated Permission")

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

try:
logging.info("Deleting a batch of permissions")
descope_client.mgmt.permission.delete_batch(
["Updated Batch Permission 1", "Batch Permission 2"]
)

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

except AuthException:
raise

Expand Down
Loading
Loading