From c37b1e79d40233761f8dccffff51a88945726142 Mon Sep 17 00:00:00 2001 From: Jonathan Griffin Date: Mon, 28 Apr 2025 14:20:09 +0200 Subject: [PATCH] update mapping for userType and role --- ee/api/routers/scim/api.py | 13 +--- ee/api/routers/scim/fixtures/user_schema.json | 3 +- ee/api/routers/scim/users.py | 60 ++++++++----------- 3 files changed, 30 insertions(+), 46 deletions(-) diff --git a/ee/api/routers/scim/api.py b/ee/api/routers/scim/api.py index 2607566cb..e9914c251 100644 --- a/ee/api/routers/scim/api.py +++ b/ee/api/routers/scim/api.py @@ -1,5 +1,4 @@ import logging -from copy import deepcopy from enum import Enum from decouple import config @@ -9,7 +8,7 @@ from fastapi.security import OAuth2PasswordRequestForm from pydantic import BaseModel from psycopg2 import errors -from chalicelib.core import roles, tenants +from chalicelib.core import tenants from chalicelib.utils.scim_auth import ( auth_optional, auth_required, @@ -204,17 +203,9 @@ async def get_schemas(filter_param: str | None = Query(None, alias="filter")): async def get_schema(schema_id: str, tenant_id=Depends(auth_required)): if schema_id not in SCHEMA_IDS_TO_SCHEMA_DETAILS: return _not_found_error_response(schema_id) - schema = deepcopy(SCHEMA_IDS_TO_SCHEMA_DETAILS[schema_id]) - if schema_id == "urn:ietf:params:scim:schemas:core:2.0:User": - db_roles = roles.get_roles(tenant_id) - role_names = [role["name"] for role in db_roles] - user_type_attribute = next( - filter(lambda x: x["name"] == "userType", schema["attributes"]) - ) - user_type_attribute["canonicalValues"] = role_names return JSONResponse( status_code=200, - content=schema, + content=SCHEMA_IDS_TO_SCHEMA_DETAILS[schema_id], ) diff --git a/ee/api/routers/scim/fixtures/user_schema.json b/ee/api/routers/scim/fixtures/user_schema.json index c80a084c5..d2838513e 100644 --- a/ee/api/routers/scim/fixtures/user_schema.json +++ b/ee/api/routers/scim/fixtures/user_schema.json @@ -182,7 +182,8 @@ "caseExact": false, "mutability": "readWrite", "returned": "default", - "uniqueness": "none" + "uniqueness": "none", + "canonicalValues": ["owner", "admin", "member", "service"] }, { "name": "preferredLanguage", diff --git a/ee/api/routers/scim/users.py b/ee/api/routers/scim/users.py index 2444f3f07..50aa0f0cd 100644 --- a/ee/api/routers/scim/users.py +++ b/ee/api/routers/scim/users.py @@ -3,7 +3,6 @@ from datetime import datetime from psycopg2.extensions import AsIs from chalicelib.utils import pg_client -from chalicelib.core import roles from routers.scim.resource_config import ( ProviderResource, ClientResource, @@ -18,8 +17,10 @@ def convert_client_resource_update_input_to_provider_resource_update_input( ) -> ProviderInput: result = {} if "userType" in client_input: - role = roles.get_role_by_name(tenant_id, client_input["userType"]) - result["role_id"] = role["roleId"] if role else None + role = "member" + if client_input["userType"] in {"owner", "admin", "member", "service"}: + role = client_input["userType"] + result["role"] = role if "name" in client_input: # note(jon): we're currently not handling the case where the client # send patches of individual name components (e.g. name.middleName) @@ -38,10 +39,10 @@ def convert_client_resource_update_input_to_provider_resource_update_input( def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input( tenant_id: int, client_input: ClientInput ) -> ProviderInput: - role_id = None + role = None if "userType" in client_input: - role = roles.get_role_by_name(tenant_id, client_input["userType"]) - role_id = role["roleId"] if role else None + if client_input["userType"] in {"owner", "admin", "member", "service"}: + role = client_input["userType"] name = client_input.get("name", {}).get("formatted") if not name: name = " ".join( @@ -61,7 +62,7 @@ def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input( "email": client_input["userName"], "internal_id": client_input.get("externalId"), "name": name, - "role_id": role_id, + "role": role, } result = {k: v for k, v in result.items() if v is not None} return result @@ -70,10 +71,10 @@ def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input( def convert_client_resource_creation_input_to_provider_resource_creation_input( tenant_id: int, client_input: ClientInput ) -> ProviderInput: - role_id = None + role = None if "userType" in client_input: - role = roles.get_role_by_name(tenant_id, client_input["userType"]) - role_id = role["roleId"] if role else None + if client_input["userType"] in {"owner", "admin", "member", "service"}: + role = client_input["userType"] name = client_input.get("name", {}).get("formatted") if not name: name = " ".join( @@ -93,7 +94,7 @@ def convert_client_resource_creation_input_to_provider_resource_creation_input( "email": client_input["userName"], "internal_id": client_input.get("externalId"), "name": name, - "role_id": role_id, + "role": role, } result = {k: v for k, v in result.items() if v is not None} return result @@ -154,7 +155,7 @@ def convert_provider_resource_to_client_resource( "formatted": provider_resource["name"], }, "displayName": provider_resource["name"] or provider_resource["email"], - "userType": provider_resource.get("role_name"), + "userType": provider_resource.get("role"), "active": provider_resource["deleted_at"] is None, "groups": [ { @@ -192,7 +193,6 @@ def get_provider_resource_chunk( """ SELECT users.*, - roles.name AS role_name, COALESCE( ( SELECT json_agg(groups) @@ -203,7 +203,6 @@ def get_provider_resource_chunk( '[]' ) AS groups FROM public.users - LEFT JOIN public.roles USING (role_id) WHERE users.tenant_id = %(tenant_id)s AND users.deleted_at IS NULL @@ -225,7 +224,6 @@ def get_provider_resource( """ SELECT users.*, - roles.name AS role_name, COALESCE( ( SELECT json_agg(groups) @@ -236,7 +234,6 @@ def get_provider_resource( '[]' ) AS groups FROM public.users - LEFT JOIN public.roles USING (role_id) WHERE users.user_id = %(user_id)s AND users.tenant_id = %(tenant_id)s @@ -257,7 +254,7 @@ def create_provider_resource( tenant_id: int, name: str = "", internal_id: str | None = None, - role_id: int | None = None, + role: str = "member", ) -> ProviderResource: with pg_client.PostgresClient() as cur: cur.execute( @@ -269,20 +266,19 @@ def create_provider_resource( email, name, internal_id, - role_id + role ) VALUES ( %(tenant_id)s, %(email)s, %(name)s, %(internal_id)s, - %(role_id)s + %(role)s ) RETURNING * ) SELECT u.*, - roles.name as role_name, COALESCE( ( SELECT json_agg(groups) @@ -293,14 +289,13 @@ def create_provider_resource( '[]' ) AS groups FROM u - LEFT JOIN public.roles USING (role_id) """, { "tenant_id": tenant_id, "email": email, "name": name, "internal_id": internal_id, - "role_id": role_id, + "role": role, }, ) ) @@ -311,8 +306,8 @@ def restore_provider_resource( tenant_id: int, email: str, name: str = "", + role: str = "member", internal_id: str | None = None, - role_id: int | None = None, **kwargs: dict[str, Any], ) -> ProviderResource: with pg_client.PostgresClient() as cur: @@ -326,7 +321,7 @@ def restore_provider_resource( email = %(email)s, name = %(name)s, internal_id = %(internal_id)s, - role_id = %(role_id)s, + role = %(role)s, deleted_at = NULL, created_at = now(), updated_at = now(), @@ -338,7 +333,6 @@ def restore_provider_resource( ) SELECT u.*, - roles.name as role_name, COALESCE( ( SELECT json_agg(groups) @@ -348,14 +342,14 @@ def restore_provider_resource( ), '[]' ) AS groups - FROM u LEFT JOIN public.roles USING (role_id); + FROM u """, { "tenant_id": tenant_id, "email": email, "name": name, "internal_id": internal_id, - "role_id": role_id, + "role": role, }, ) ) @@ -368,7 +362,7 @@ def rewrite_provider_resource( email: str, name: str = "", internal_id: str | None = None, - role_id: int | None = None, + role: str = "member", ): with pg_client.PostgresClient() as cur: cur.execute( @@ -380,7 +374,7 @@ def rewrite_provider_resource( email = %(email)s, name = %(name)s, internal_id = %(internal_id)s, - role_id = %(role_id)s, + role = %(role)s, updated_at = now() WHERE users.user_id = %(user_id)s @@ -390,7 +384,6 @@ def rewrite_provider_resource( ) SELECT u.*, - roles.name as role_name, COALESCE( ( SELECT json_agg(groups) @@ -400,7 +393,7 @@ def rewrite_provider_resource( ), '[]' ) AS groups - FROM u LEFT JOIN public.roles USING (role_id); + FROM u """, { "tenant_id": tenant_id, @@ -408,7 +401,7 @@ def rewrite_provider_resource( "email": email, "name": name, "internal_id": internal_id, - "role_id": role_id, + "role": role, }, ) ) @@ -443,7 +436,6 @@ def update_provider_resource( ) SELECT u.*, - roles.name as role_name, COALESCE( ( SELECT json_agg(groups) @@ -453,7 +445,7 @@ def update_provider_resource( ), '[]' ) AS groups - FROM u LEFT JOIN public.roles USING (role_id) + FROM u """ ) return cur.fetchone()