update mapping for userType and role

This commit is contained in:
Jonathan Griffin 2025-04-28 14:20:09 +02:00
parent 7af24f59c3
commit c37b1e79d4
3 changed files with 30 additions and 46 deletions

View file

@ -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],
)

View file

@ -182,7 +182,8 @@
"caseExact": false,
"mutability": "readWrite",
"returned": "default",
"uniqueness": "none"
"uniqueness": "none",
"canonicalValues": ["owner", "admin", "member", "service"]
},
{
"name": "preferredLanguage",

View file

@ -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()