From 305021ff0944da1e4f78fe6dcc2abb9c457f4265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20Hru=C5=A1ka?= Date: Mon, 2 Sep 2024 16:44:06 +0200 Subject: [PATCH 1/2] copy role --- seacatauth/authz/role/handler/role.py | 12 +++++++++++- seacatauth/authz/role/service.py | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/seacatauth/authz/role/handler/role.py b/seacatauth/authz/role/handler/role.py index 839d26dc..da149f46 100644 --- a/seacatauth/authz/role/handler/role.py +++ b/seacatauth/authz/role/handler/role.py @@ -138,11 +138,21 @@ async def get(self, request): async def create(self, request, *, tenant, json_data): """ Create a new role + + --- + parameters: + - name: copy + in: query + description: + Copy resources and description from a specified existing role. + Resources non-applicable for the new role will be excluded. + schema: + type: string """ role_name = request.match_info["role_name"] role_id = "{}/{}".format(tenant, role_name) try: - role_id = await self.RoleService.create(role_id, **json_data) + role_id = await self.RoleService.create(role_id, from_role=request.query.get("copy"), **json_data) except exceptions.ResourceNotFoundError as e: return asab.web.rest.json_response(request, status=404, data={ "result": "ERROR", diff --git a/seacatauth/authz/role/service.py b/seacatauth/authz/role/service.py index 45400080..6c5318b9 100644 --- a/seacatauth/authz/role/service.py +++ b/seacatauth/authz/role/service.py @@ -221,6 +221,7 @@ async def create( description: str = None, resources: typing.Optional[typing.Iterable] = None, propagated: bool = False, + from_role: typing.Optional[str] = None, _managed_by_seacat_auth: bool = False, ): tenant_id, role_name = self.parse_role_id(role_id) @@ -241,6 +242,21 @@ async def create( except exceptions.RoleNotFoundError: pass + if from_role: + # Use specified role as a template + source_role = await self.get(from_role) + if not description: + description = source_role.get("description") + if not resources: + if tenant_id is not None or propagated is True: + # Tenant and propagated roles cannot access global-only resources + resources = [ + resource_id for resource_id in source_role.get("resources") + if not self.ResourceService.is_global_only_resource(resource_id) + ] + else: + resources = source_role.get("resources") + upsertor = self.StorageService.upsertor( self.RoleCollection, role_id From 4dceb909aa0a8e7ab2b3d2a8360cd08ad363c2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20Hru=C5=A1ka?= Date: Thu, 5 Sep 2024 14:16:51 +0200 Subject: [PATCH 2/2] update CHANGELOG.md --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26b29a82..c9d3b4ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # CHANGELOG +## v24.36 + +### Pre-releases +- v24.36-alpha1 + +### Features +- Duplicating roles (#416, `v24.36-alpha1`) + +--- + + ## v24.29 ### Pre-releases