From 203efc3e7412a54384612762bf93f0c9d91ee020 Mon Sep 17 00:00:00 2001 From: auslin-aot Date: Wed, 5 Jun 2024 16:09:14 +0530 Subject: [PATCH 1/2] FWF-3325: [Feature] Save group role mapping --- .../src/formsflow_api/schemas/roles.py | 1 + .../factory/keycloak_client_service.py | 22 +++++++++++++------ .../factory/keycloak_group_service.py | 22 +++++++++++++++++++ forms-flow-api/tests/unit/api/test_roles.py | 2 +- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/forms-flow-api/src/formsflow_api/schemas/roles.py b/forms-flow-api/src/formsflow_api/schemas/roles.py index 22ec4d2aef..26a8bca7a8 100644 --- a/forms-flow-api/src/formsflow_api/schemas/roles.py +++ b/forms-flow-api/src/formsflow_api/schemas/roles.py @@ -14,3 +14,4 @@ class Meta: # pylint: disable=too-few-public-methods id = fields.Str(dump_only=True) name = fields.Str(required=True) description = fields.Str() + permissions = fields.List(fields.Str()) diff --git a/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py b/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py index 5080c78555..f49abc628b 100644 --- a/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py +++ b/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py @@ -12,6 +12,7 @@ from formsflow_api.services import KeycloakAdminAPIService, UserService from .keycloak_admin import KeycloakAdmin +from .keycloak_group_service import KeycloakGroupService class KeycloakClientService(KeycloakAdmin): @@ -93,14 +94,21 @@ def delete_group(self, group_id: str): url_path=f"clients/{client_id}/roles/{group_id}" ) - def create_group_role(self, data: Dict): + @user_context + def create_group_role(self, data: Dict, **kwargs): """Create role.""" - client_id = self.client.get_client_id() - response = self.client.create_request( - url_path=f"clients/{client_id}/roles", data=data - ) - role_name = response.headers["Location"].split("/")[-1] - return {"id": role_name} + current_app.logger.debug("Creating tenant group...") + user: UserContext = kwargs["user"] + tenant_key = user.tenant_key + # Append tenantKey to group in the group hierarchy. + # If user input is "group/sub-group" append tenantKey to each group + groups = [group for group in data["name"].split("/") if group] + appended_groups = [f"{tenant_key}-{group}" for group in groups] + + data["name"] = "/".join(appended_groups) + current_app.logger.debug(f"Tenant group: {data['name']}") + group_servie = KeycloakGroupService() + return group_servie.create_group_role(data) def add_user_to_group_role(self, user_id: str, group_id: str, payload: Dict): """Add user to role.""" diff --git a/forms-flow-api/src/formsflow_api/services/factory/keycloak_group_service.py b/forms-flow-api/src/formsflow_api/services/factory/keycloak_group_service.py index f3fc166739..bb4cc20128 100644 --- a/forms-flow-api/src/formsflow_api/services/factory/keycloak_group_service.py +++ b/forms-flow-api/src/formsflow_api/services/factory/keycloak_group_service.py @@ -91,6 +91,7 @@ def create_group_role(self, data: Dict): Split name parameter to create group/subgroups """ + permissions = data.pop("permissions") data = self.add_description(data) data["name"] = ( data["name"].lstrip("/") if data["name"].startswith("/") else data["name"] @@ -119,6 +120,8 @@ def create_group_role(self, data: Dict): ) group_id = response["id"] url_path = f"groups/{group_id}/children" + client_id = self.client.get_client_id() + self.create_group_permission_mapping(group_id, permissions, client_id) return {"id": group_id} def add_description(self, data: Dict): @@ -218,3 +221,22 @@ def add_user_to_tenant(self, data: Dict): return { "message": "The requested operation is not supported." }, HTTPStatus.BAD_REQUEST + + def create_group_permission_mapping(self, group_id, permissions, client_id): + """Set permission mapping to group.""" + current_app.logger.debug("Setting permission mapping to group") + roles = self.client.get_roles() + role_data_list = [] + for role in roles: + if permissions and role.get("name") in permissions: + role_data = { + "containerId": client_id, + "id": role.get("id"), + "clientRole": True, + "name": role.get("name"), + } + role_data_list.append(role_data) + self.client.create_request( + url_path=f"groups/{group_id}/role-mappings/clients/{client_id}", + data=role_data_list, + ) diff --git a/forms-flow-api/tests/unit/api/test_roles.py b/forms-flow-api/tests/unit/api/test_roles.py index c8c3779b37..f6d3e73f95 100644 --- a/forms-flow-api/tests/unit/api/test_roles.py +++ b/forms-flow-api/tests/unit/api/test_roles.py @@ -24,7 +24,7 @@ def test_keycloak_role_crud(self, app, client, session, jwt): "content-type": "application/json", } # Create new user group. - data = {"name": "new-test-group", "description": "Group"} + data = {"name": "new-test-group", "description": "Group", "permissions": ["view_designs", "create_designs"]} rv = client.post("/roles", headers=headers, json=data) assert rv.status_code == 201 assert rv.json.get("id") is not None From 90c7a357e93f4f1d73fed71b4ee389d5de864964 Mon Sep 17 00:00:00 2001 From: auslin-aot Date: Thu, 6 Jun 2024 11:16:17 +0530 Subject: [PATCH 2/2] FWF-3325: [Feature] Added tenantKey to main group --- .../services/factory/keycloak_client_service.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py b/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py index f49abc628b..dd04b43c0a 100644 --- a/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py +++ b/forms-flow-api/src/formsflow_api/services/factory/keycloak_client_service.py @@ -96,19 +96,16 @@ def delete_group(self, group_id: str): @user_context def create_group_role(self, data: Dict, **kwargs): - """Create role.""" + """Create tenant group.""" current_app.logger.debug("Creating tenant group...") user: UserContext = kwargs["user"] tenant_key = user.tenant_key - # Append tenantKey to group in the group hierarchy. - # If user input is "group/sub-group" append tenantKey to each group - groups = [group for group in data["name"].split("/") if group] - appended_groups = [f"{tenant_key}-{group}" for group in groups] - - data["name"] = "/".join(appended_groups) + name = data["name"].lstrip("/") + # Prefix the tenant_key to the main group + data["name"] = f"{tenant_key}-{name}" current_app.logger.debug(f"Tenant group: {data['name']}") - group_servie = KeycloakGroupService() - return group_servie.create_group_role(data) + group_service = KeycloakGroupService() + return group_service.create_group_role(data) def add_user_to_group_role(self, user_id: str, group_id: str, payload: Dict): """Add user to role."""