map groups to roles instead of having separate groups table
This commit is contained in:
parent
d3a9a50892
commit
8bdbf7ef95
3 changed files with 101 additions and 199 deletions
|
|
@ -18,8 +18,6 @@ def convert_client_resource_update_input_to_provider_resource_update_input(
|
||||||
result = {}
|
result = {}
|
||||||
if "displayName" in client_input:
|
if "displayName" in client_input:
|
||||||
result["name"] = client_input["displayName"]
|
result["name"] = client_input["displayName"]
|
||||||
if "externalId" in client_input:
|
|
||||||
result["external_id"] = client_input["externalId"]
|
|
||||||
if "members" in client_input:
|
if "members" in client_input:
|
||||||
members = client_input["members"] or []
|
members = client_input["members"] or []
|
||||||
result["user_ids"] = [int(member["value"]) for member in members]
|
result["user_ids"] = [int(member["value"]) for member in members]
|
||||||
|
|
@ -32,15 +30,14 @@ def convert_provider_resource_to_client_resource(
|
||||||
members = provider_resource["users"] or []
|
members = provider_resource["users"] or []
|
||||||
return {
|
return {
|
||||||
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
|
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
|
||||||
"id": str(provider_resource["group_id"]),
|
"id": str(provider_resource["role_id"]),
|
||||||
"externalId": provider_resource["external_id"],
|
|
||||||
"meta": {
|
"meta": {
|
||||||
"resourceType": "Group",
|
"resourceType": "Group",
|
||||||
"created": provider_resource["created_at"].strftime("%Y-%m-%dT%H:%M:%SZ"),
|
"created": provider_resource["created_at"].strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||||
"lastModified": provider_resource["updated_at"].strftime(
|
"lastModified": provider_resource["updated_at"].strftime(
|
||||||
"%Y-%m-%dT%H:%M:%SZ"
|
"%Y-%m-%dT%H:%M:%SZ"
|
||||||
),
|
),
|
||||||
"location": f"Groups/{provider_resource['group_id']}",
|
"location": f"Groups/{provider_resource['role_id']}",
|
||||||
},
|
},
|
||||||
"displayName": provider_resource["name"],
|
"displayName": provider_resource["name"],
|
||||||
"members": [
|
"members": [
|
||||||
|
|
@ -60,8 +57,10 @@ def get_active_resource_count(tenant_id: int) -> int:
|
||||||
cur.mogrify(
|
cur.mogrify(
|
||||||
"""
|
"""
|
||||||
SELECT COUNT(*)
|
SELECT COUNT(*)
|
||||||
FROM public.groups
|
FROM public.roles
|
||||||
WHERE groups.tenant_id = %(tenant_id)s
|
WHERE
|
||||||
|
roles.tenant_id = %(tenant_id)s
|
||||||
|
AND roles.deleted_at IS NULL
|
||||||
""",
|
""",
|
||||||
{"tenant_id": tenant_id},
|
{"tenant_id": tenant_id},
|
||||||
)
|
)
|
||||||
|
|
@ -77,18 +76,19 @@ def get_provider_resource_chunk(
|
||||||
cur.mogrify(
|
cur.mogrify(
|
||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
groups.*,
|
roles.*,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
(
|
(
|
||||||
SELECT json_agg(users)
|
SELECT json_agg(users)
|
||||||
FROM public.user_group
|
FROM public.users
|
||||||
JOIN public.users USING (user_id)
|
WHERE users.role_id = roles.role_id
|
||||||
WHERE user_group.group_id = groups.group_id
|
|
||||||
),
|
),
|
||||||
'[]'
|
'[]'
|
||||||
) AS users
|
) AS users
|
||||||
FROM public.groups
|
FROM public.roles
|
||||||
WHERE groups.tenant_id = %(tenant_id)s
|
WHERE
|
||||||
|
roles.tenant_id = %(tenant_id)s
|
||||||
|
AND roles.deleted_at IS NULL
|
||||||
LIMIT %(limit)s
|
LIMIT %(limit)s
|
||||||
OFFSET %(offset)s;
|
OFFSET %(offset)s;
|
||||||
""",
|
""",
|
||||||
|
|
@ -110,23 +110,23 @@ def get_provider_resource(
|
||||||
cur.mogrify(
|
cur.mogrify(
|
||||||
"""
|
"""
|
||||||
SELECT
|
SELECT
|
||||||
groups.*,
|
roles.*,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
(
|
(
|
||||||
SELECT json_agg(users)
|
SELECT json_agg(users)
|
||||||
FROM public.user_group
|
FROM public.users
|
||||||
JOIN public.users USING (user_id)
|
WHERE users.role_id = roles.role_id
|
||||||
WHERE user_group.group_id = groups.group_id
|
|
||||||
),
|
),
|
||||||
'[]'
|
'[]'
|
||||||
) AS users
|
) AS users
|
||||||
FROM public.groups
|
FROM public.roles
|
||||||
WHERE
|
WHERE
|
||||||
groups.tenant_id = %(tenant_id)s
|
roles.tenant_id = %(tenant_id)s
|
||||||
AND groups.group_id = %(group_id)s
|
AND roles.role_id = %(resource_id)s
|
||||||
|
AND roles.deleted_at IS NULL
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
""",
|
""",
|
||||||
{"group_id": resource_id, "tenant_id": tenant_id},
|
{"resource_id": resource_id, "tenant_id": tenant_id},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return cur.fetchone()
|
return cur.fetchone()
|
||||||
|
|
@ -135,7 +135,7 @@ def get_provider_resource(
|
||||||
def get_provider_resource_from_unique_fields(
|
def get_provider_resource_from_unique_fields(
|
||||||
**kwargs: dict[str, Any],
|
**kwargs: dict[str, Any],
|
||||||
) -> ProviderResource | None:
|
) -> ProviderResource | None:
|
||||||
# note(jon): we do not really use this for groups as we don't have unique values outside
|
# note(jon): we do not really use this for scim.groups (openreplay.roles) as we don't have unique values outside
|
||||||
# of the primary key
|
# of the primary key
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -145,7 +145,6 @@ def convert_client_resource_creation_input_to_provider_resource_creation_input(
|
||||||
) -> ProviderInput:
|
) -> ProviderInput:
|
||||||
return {
|
return {
|
||||||
"name": client_input["displayName"],
|
"name": client_input["displayName"],
|
||||||
"external_id": client_input.get("externalId"),
|
|
||||||
"user_ids": [
|
"user_ids": [
|
||||||
int(member["value"]) for member in client_input.get("members", [])
|
int(member["value"]) for member in client_input.get("members", [])
|
||||||
],
|
],
|
||||||
|
|
@ -157,7 +156,6 @@ def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input(
|
||||||
) -> ProviderInput:
|
) -> ProviderInput:
|
||||||
return {
|
return {
|
||||||
"name": client_input["displayName"],
|
"name": client_input["displayName"],
|
||||||
"external_id": client_input.get("externalId"),
|
|
||||||
"user_ids": [
|
"user_ids": [
|
||||||
int(member["value"]) for member in client_input.get("members", [])
|
int(member["value"]) for member in client_input.get("members", [])
|
||||||
],
|
],
|
||||||
|
|
@ -189,50 +187,37 @@ def create_provider_resource(
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"""
|
f"""
|
||||||
WITH
|
WITH
|
||||||
g AS (
|
r AS (
|
||||||
INSERT INTO public.groups ({column_clause})
|
INSERT INTO public.roles ({column_clause})
|
||||||
VALUES ({value_clause})
|
VALUES ({value_clause})
|
||||||
RETURNING *
|
RETURNING *
|
||||||
),
|
),
|
||||||
ugs AS (
|
linked_users AS (
|
||||||
INSERT INTO public.user_group (user_id, group_id)
|
UPDATE public.users
|
||||||
SELECT users.user_id, g.group_id
|
SET
|
||||||
FROM g
|
updated_at = now(),
|
||||||
JOIN public.users ON users.user_id = ANY({user_id_clause})
|
role_id = (SELECT r.role_id FROM r)
|
||||||
|
WHERE users.user_id = ANY({user_id_clause})
|
||||||
RETURNING *
|
RETURNING *
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
g.*,
|
r.*,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
(
|
(
|
||||||
SELECT json_agg(users)
|
SELECT json_agg(linked_users.*)
|
||||||
FROM ugs
|
FROM linked_users
|
||||||
JOIN public.users USING (user_id)
|
|
||||||
),
|
),
|
||||||
'[]'
|
'[]'
|
||||||
) AS users
|
) AS users
|
||||||
FROM g
|
FROM r
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return cur.fetchone()
|
return cur.fetchone()
|
||||||
|
|
||||||
|
|
||||||
def delete_provider_resource(resource_id: ResourceId, tenant_id: int) -> None:
|
|
||||||
with pg_client.PostgresClient() as cur:
|
|
||||||
cur.execute(
|
|
||||||
cur.mogrify(
|
|
||||||
"""
|
|
||||||
DELETE FROM public.groups
|
|
||||||
WHERE groups.group_id = %(group_id)s AND groups.tenant_id = %(tenant_id)s;
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
{"tenant_id": tenant_id, "group_id": resource_id},
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _update_resource_sql(
|
def _update_resource_sql(
|
||||||
group_id: int,
|
resource_id: int,
|
||||||
tenant_id: int,
|
tenant_id: int,
|
||||||
user_ids: list[int] | None = None,
|
user_ids: list[int] | None = None,
|
||||||
**kwargs: dict[str, Any],
|
**kwargs: dict[str, Any],
|
||||||
|
|
@ -251,46 +236,71 @@ def _update_resource_sql(
|
||||||
user_id_clause = f"ARRAY[{', '.join(user_id_fragments)}]::int[]"
|
user_id_clause = f"ARRAY[{', '.join(user_id_fragments)}]::int[]"
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"""
|
f"""
|
||||||
DELETE FROM public.user_group
|
UPDATE public.users
|
||||||
WHERE user_group.group_id = {group_id}
|
SET role_id = NULL
|
||||||
|
WHERE users.role_id = {resource_id}
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"""
|
f"""
|
||||||
WITH
|
WITH
|
||||||
g AS (
|
r AS (
|
||||||
UPDATE public.groups
|
UPDATE public.roles
|
||||||
SET {set_clause}
|
SET {set_clause}
|
||||||
WHERE
|
WHERE
|
||||||
groups.group_id = {group_id}
|
roles.role_id = {resource_id}
|
||||||
AND groups.tenant_id = {tenant_id}
|
AND roles.tenant_id = {tenant_id}
|
||||||
|
AND roles.deleted_at IS NULL
|
||||||
RETURNING *
|
RETURNING *
|
||||||
),
|
),
|
||||||
linked_user_group AS (
|
linked_users AS (
|
||||||
INSERT INTO public.user_group (user_id, group_id)
|
UPDATE public.users
|
||||||
SELECT users.user_id, g.group_id
|
SET
|
||||||
FROM g
|
updated_at = now(),
|
||||||
JOIN public.users ON users.user_id = ANY({user_id_clause})
|
role_id = {resource_id}
|
||||||
WHERE users.deleted_at IS NULL AND users.tenant_id = {tenant_id}
|
WHERE users.user_id = ANY({user_id_clause})
|
||||||
RETURNING *
|
RETURNING *
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
g.*,
|
r.*,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
(
|
(
|
||||||
SELECT json_agg(users)
|
SELECT json_agg(linked_users.*)
|
||||||
FROM linked_user_group
|
FROM linked_users
|
||||||
JOIN public.users USING (user_id)
|
|
||||||
),
|
),
|
||||||
'[]'
|
'[]'
|
||||||
) AS users
|
) AS users
|
||||||
FROM g
|
FROM r
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return cur.fetchone()
|
return cur.fetchone()
|
||||||
|
|
||||||
|
|
||||||
|
def delete_provider_resource(resource_id: ResourceId, tenant_id: int) -> None:
|
||||||
|
_update_resource_sql(
|
||||||
|
resource_id=resource_id,
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
deleted_at=datetime.now(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def restore_provider_resource(
|
||||||
|
resource_id: int,
|
||||||
|
tenant_id: int,
|
||||||
|
name: str,
|
||||||
|
**kwargs: dict[str, Any],
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
return _update_resource_sql(
|
||||||
|
resource_id=resource_id,
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
name=name,
|
||||||
|
created_at=datetime.now(),
|
||||||
|
deleted_at=None,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def rewrite_provider_resource(
|
def rewrite_provider_resource(
|
||||||
resource_id: int,
|
resource_id: int,
|
||||||
tenant_id: int,
|
tenant_id: int,
|
||||||
|
|
@ -298,7 +308,7 @@ def rewrite_provider_resource(
|
||||||
**kwargs: dict[str, Any],
|
**kwargs: dict[str, Any],
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
return _update_resource_sql(
|
return _update_resource_sql(
|
||||||
group_id=resource_id,
|
resource_id=resource_id,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
name=name,
|
name=name,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
|
@ -311,7 +321,7 @@ def update_provider_resource(
|
||||||
**kwargs: dict[str, Any],
|
**kwargs: dict[str, Any],
|
||||||
):
|
):
|
||||||
return _update_resource_sql(
|
return _update_resource_sql(
|
||||||
group_id=resource_id,
|
resource_id=resource_id,
|
||||||
tenant_id=tenant_id,
|
tenant_id=tenant_id,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,6 @@ def convert_client_resource_update_input_to_provider_resource_update_input(
|
||||||
tenant_id: int, client_input: ClientInput
|
tenant_id: int, client_input: ClientInput
|
||||||
) -> ProviderInput:
|
) -> ProviderInput:
|
||||||
result = {}
|
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
|
|
||||||
if "name" in client_input:
|
if "name" in client_input:
|
||||||
# note(jon): we're currently not handling the case where the client
|
# note(jon): we're currently not handling the case where the client
|
||||||
# send patches of individual name components (e.g. name.middleName)
|
# send patches of individual name components (e.g. name.middleName)
|
||||||
|
|
@ -38,10 +35,6 @@ def convert_client_resource_update_input_to_provider_resource_update_input(
|
||||||
def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input(
|
def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input(
|
||||||
tenant_id: int, client_input: ClientInput
|
tenant_id: int, client_input: ClientInput
|
||||||
) -> ProviderInput:
|
) -> ProviderInput:
|
||||||
role_id = 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
|
|
||||||
name = client_input.get("name", {}).get("formatted")
|
name = client_input.get("name", {}).get("formatted")
|
||||||
if not name:
|
if not name:
|
||||||
name = " ".join(
|
name = " ".join(
|
||||||
|
|
@ -61,7 +54,6 @@ def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input(
|
||||||
"email": client_input["userName"],
|
"email": client_input["userName"],
|
||||||
"internal_id": client_input.get("externalId"),
|
"internal_id": client_input.get("externalId"),
|
||||||
"name": name,
|
"name": name,
|
||||||
"role_id": role_id,
|
|
||||||
}
|
}
|
||||||
result = {k: v for k, v in result.items() if v is not None}
|
result = {k: v for k, v in result.items() if v is not None}
|
||||||
return result
|
return result
|
||||||
|
|
@ -70,10 +62,6 @@ def convert_client_resource_rewrite_input_to_provider_resource_rewrite_input(
|
||||||
def convert_client_resource_creation_input_to_provider_resource_creation_input(
|
def convert_client_resource_creation_input_to_provider_resource_creation_input(
|
||||||
tenant_id: int, client_input: ClientInput
|
tenant_id: int, client_input: ClientInput
|
||||||
) -> ProviderInput:
|
) -> ProviderInput:
|
||||||
role_id = 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
|
|
||||||
name = client_input.get("name", {}).get("formatted")
|
name = client_input.get("name", {}).get("formatted")
|
||||||
if not name:
|
if not name:
|
||||||
name = " ".join(
|
name = " ".join(
|
||||||
|
|
@ -93,7 +81,6 @@ def convert_client_resource_creation_input_to_provider_resource_creation_input(
|
||||||
"email": client_input["userName"],
|
"email": client_input["userName"],
|
||||||
"internal_id": client_input.get("externalId"),
|
"internal_id": client_input.get("externalId"),
|
||||||
"name": name,
|
"name": name,
|
||||||
"role_id": role_id,
|
|
||||||
}
|
}
|
||||||
result = {k: v for k, v in result.items() if v is not None}
|
result = {k: v for k, v in result.items() if v is not None}
|
||||||
return result
|
return result
|
||||||
|
|
@ -124,7 +111,7 @@ def delete_provider_resource(resource_id: ResourceId, tenant_id: int) -> None:
|
||||||
UPDATE public.users
|
UPDATE public.users
|
||||||
SET
|
SET
|
||||||
deleted_at = NULL,
|
deleted_at = NULL,
|
||||||
updated_at = default
|
updated_at = now()
|
||||||
WHERE
|
WHERE
|
||||||
users.user_id = %(user_id)s
|
users.user_id = %(user_id)s
|
||||||
AND users.tenant_id = %(tenant_id)s
|
AND users.tenant_id = %(tenant_id)s
|
||||||
|
|
@ -137,6 +124,14 @@ def delete_provider_resource(resource_id: ResourceId, tenant_id: int) -> None:
|
||||||
def convert_provider_resource_to_client_resource(
|
def convert_provider_resource_to_client_resource(
|
||||||
provider_resource: ProviderResource,
|
provider_resource: ProviderResource,
|
||||||
) -> ClientResource:
|
) -> ClientResource:
|
||||||
|
groups = []
|
||||||
|
if provider_resource["role_id"]:
|
||||||
|
groups.append(
|
||||||
|
{
|
||||||
|
"value": str(provider_resource["role_id"]),
|
||||||
|
"$ref": f"Groups/{provider_resource['role_id']}",
|
||||||
|
}
|
||||||
|
)
|
||||||
return {
|
return {
|
||||||
"id": str(provider_resource["user_id"]),
|
"id": str(provider_resource["user_id"]),
|
||||||
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||||
|
|
@ -154,15 +149,8 @@ def convert_provider_resource_to_client_resource(
|
||||||
"formatted": provider_resource["name"],
|
"formatted": provider_resource["name"],
|
||||||
},
|
},
|
||||||
"displayName": provider_resource["name"] or provider_resource["email"],
|
"displayName": provider_resource["name"] or provider_resource["email"],
|
||||||
"userType": provider_resource.get("role_name"),
|
|
||||||
"active": provider_resource["deleted_at"] is None,
|
"active": provider_resource["deleted_at"] is None,
|
||||||
"groups": [
|
"groups": groups,
|
||||||
{
|
|
||||||
"value": str(group["group_id"]),
|
|
||||||
"$ref": f"Groups/{group['group_id']}",
|
|
||||||
}
|
|
||||||
for group in provider_resource["groups"]
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -190,20 +178,8 @@ def get_provider_resource_chunk(
|
||||||
cur.execute(
|
cur.execute(
|
||||||
cur.mogrify(
|
cur.mogrify(
|
||||||
"""
|
"""
|
||||||
SELECT
|
SELECT *
|
||||||
users.*,
|
|
||||||
roles.name AS role_name,
|
|
||||||
COALESCE(
|
|
||||||
(
|
|
||||||
SELECT json_agg(groups)
|
|
||||||
FROM public.user_group
|
|
||||||
JOIN public.groups USING (group_id)
|
|
||||||
WHERE user_group.user_id = users.user_id
|
|
||||||
),
|
|
||||||
'[]'
|
|
||||||
) AS groups
|
|
||||||
FROM public.users
|
FROM public.users
|
||||||
LEFT JOIN public.roles USING (role_id)
|
|
||||||
WHERE
|
WHERE
|
||||||
users.tenant_id = %(tenant_id)s
|
users.tenant_id = %(tenant_id)s
|
||||||
AND users.deleted_at IS NULL
|
AND users.deleted_at IS NULL
|
||||||
|
|
@ -223,20 +199,8 @@ def get_provider_resource(
|
||||||
cur.execute(
|
cur.execute(
|
||||||
cur.mogrify(
|
cur.mogrify(
|
||||||
"""
|
"""
|
||||||
SELECT
|
SELECT *
|
||||||
users.*,
|
|
||||||
roles.name AS role_name,
|
|
||||||
COALESCE(
|
|
||||||
(
|
|
||||||
SELECT json_agg(groups)
|
|
||||||
FROM public.user_group
|
|
||||||
JOIN public.groups USING (group_id)
|
|
||||||
WHERE user_group.user_id = users.user_id
|
|
||||||
),
|
|
||||||
'[]'
|
|
||||||
) AS groups
|
|
||||||
FROM public.users
|
FROM public.users
|
||||||
LEFT JOIN public.roles USING (role_id)
|
|
||||||
WHERE
|
WHERE
|
||||||
users.user_id = %(user_id)s
|
users.user_id = %(user_id)s
|
||||||
AND users.tenant_id = %(tenant_id)s
|
AND users.tenant_id = %(tenant_id)s
|
||||||
|
|
@ -257,7 +221,6 @@ def create_provider_resource(
|
||||||
tenant_id: int,
|
tenant_id: int,
|
||||||
name: str = "",
|
name: str = "",
|
||||||
internal_id: str | None = None,
|
internal_id: str | None = None,
|
||||||
role_id: int | None = None,
|
|
||||||
) -> ProviderResource:
|
) -> ProviderResource:
|
||||||
with pg_client.PostgresClient() as cur:
|
with pg_client.PostgresClient() as cur:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
|
|
@ -268,39 +231,24 @@ def create_provider_resource(
|
||||||
tenant_id,
|
tenant_id,
|
||||||
email,
|
email,
|
||||||
name,
|
name,
|
||||||
internal_id,
|
internal_id
|
||||||
role_id
|
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
%(tenant_id)s,
|
%(tenant_id)s,
|
||||||
%(email)s,
|
%(email)s,
|
||||||
%(name)s,
|
%(name)s,
|
||||||
%(internal_id)s,
|
%(internal_id)s
|
||||||
%(role_id)s
|
|
||||||
)
|
)
|
||||||
RETURNING *
|
RETURNING *
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT *
|
||||||
u.*,
|
|
||||||
roles.name as role_name,
|
|
||||||
COALESCE(
|
|
||||||
(
|
|
||||||
SELECT json_agg(groups)
|
|
||||||
FROM public.user_group
|
|
||||||
JOIN public.groups USING (group_id)
|
|
||||||
WHERE user_group.user_id = u.user_id
|
|
||||||
),
|
|
||||||
'[]'
|
|
||||||
) AS groups
|
|
||||||
FROM u
|
FROM u
|
||||||
LEFT JOIN public.roles USING (role_id)
|
|
||||||
""",
|
""",
|
||||||
{
|
{
|
||||||
"tenant_id": tenant_id,
|
"tenant_id": tenant_id,
|
||||||
"email": email,
|
"email": email,
|
||||||
"name": name,
|
"name": name,
|
||||||
"internal_id": internal_id,
|
"internal_id": internal_id,
|
||||||
"role_id": role_id,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -312,7 +260,6 @@ def restore_provider_resource(
|
||||||
email: str,
|
email: str,
|
||||||
name: str = "",
|
name: str = "",
|
||||||
internal_id: str | None = None,
|
internal_id: str | None = None,
|
||||||
role_id: int | None = None,
|
|
||||||
**kwargs: dict[str, Any],
|
**kwargs: dict[str, Any],
|
||||||
) -> ProviderResource:
|
) -> ProviderResource:
|
||||||
with pg_client.PostgresClient() as cur:
|
with pg_client.PostgresClient() as cur:
|
||||||
|
|
@ -326,7 +273,6 @@ def restore_provider_resource(
|
||||||
email = %(email)s,
|
email = %(email)s,
|
||||||
name = %(name)s,
|
name = %(name)s,
|
||||||
internal_id = %(internal_id)s,
|
internal_id = %(internal_id)s,
|
||||||
role_id = %(role_id)s,
|
|
||||||
deleted_at = NULL,
|
deleted_at = NULL,
|
||||||
created_at = now(),
|
created_at = now(),
|
||||||
updated_at = now(),
|
updated_at = now(),
|
||||||
|
|
@ -336,26 +282,14 @@ def restore_provider_resource(
|
||||||
WHERE users.email = %(email)s
|
WHERE users.email = %(email)s
|
||||||
RETURNING *
|
RETURNING *
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT *
|
||||||
u.*,
|
FROM u
|
||||||
roles.name as role_name,
|
|
||||||
COALESCE(
|
|
||||||
(
|
|
||||||
SELECT json_agg(groups)
|
|
||||||
FROM public.user_group
|
|
||||||
JOIN public.groups USING (group_id)
|
|
||||||
WHERE user_group.user_id = u.user_id
|
|
||||||
),
|
|
||||||
'[]'
|
|
||||||
) AS groups
|
|
||||||
FROM u LEFT JOIN public.roles USING (role_id);
|
|
||||||
""",
|
""",
|
||||||
{
|
{
|
||||||
"tenant_id": tenant_id,
|
"tenant_id": tenant_id,
|
||||||
"email": email,
|
"email": email,
|
||||||
"name": name,
|
"name": name,
|
||||||
"internal_id": internal_id,
|
"internal_id": internal_id,
|
||||||
"role_id": role_id,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -368,7 +302,6 @@ def rewrite_provider_resource(
|
||||||
email: str,
|
email: str,
|
||||||
name: str = "",
|
name: str = "",
|
||||||
internal_id: str | None = None,
|
internal_id: str | None = None,
|
||||||
role_id: int | None = None,
|
|
||||||
):
|
):
|
||||||
with pg_client.PostgresClient() as cur:
|
with pg_client.PostgresClient() as cur:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
|
|
@ -380,7 +313,6 @@ def rewrite_provider_resource(
|
||||||
email = %(email)s,
|
email = %(email)s,
|
||||||
name = %(name)s,
|
name = %(name)s,
|
||||||
internal_id = %(internal_id)s,
|
internal_id = %(internal_id)s,
|
||||||
role_id = %(role_id)s,
|
|
||||||
updated_at = now()
|
updated_at = now()
|
||||||
WHERE
|
WHERE
|
||||||
users.user_id = %(user_id)s
|
users.user_id = %(user_id)s
|
||||||
|
|
@ -388,19 +320,8 @@ def rewrite_provider_resource(
|
||||||
AND users.deleted_at IS NULL
|
AND users.deleted_at IS NULL
|
||||||
RETURNING *
|
RETURNING *
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT *
|
||||||
u.*,
|
FROM u
|
||||||
roles.name as role_name,
|
|
||||||
COALESCE(
|
|
||||||
(
|
|
||||||
SELECT json_agg(groups)
|
|
||||||
FROM public.user_group
|
|
||||||
JOIN public.groups USING (group_id)
|
|
||||||
WHERE user_group.user_id = u.user_id
|
|
||||||
),
|
|
||||||
'[]'
|
|
||||||
) AS groups
|
|
||||||
FROM u LEFT JOIN public.roles USING (role_id);
|
|
||||||
""",
|
""",
|
||||||
{
|
{
|
||||||
"tenant_id": tenant_id,
|
"tenant_id": tenant_id,
|
||||||
|
|
@ -408,7 +329,6 @@ def rewrite_provider_resource(
|
||||||
"email": email,
|
"email": email,
|
||||||
"name": name,
|
"name": name,
|
||||||
"internal_id": internal_id,
|
"internal_id": internal_id,
|
||||||
"role_id": role_id,
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
@ -441,19 +361,8 @@ def update_provider_resource(
|
||||||
AND users.deleted_at IS NULL
|
AND users.deleted_at IS NULL
|
||||||
RETURNING *
|
RETURNING *
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT *
|
||||||
u.*,
|
FROM u
|
||||||
roles.name as role_name,
|
|
||||||
COALESCE(
|
|
||||||
(
|
|
||||||
SELECT json_agg(groups)
|
|
||||||
FROM public.user_group
|
|
||||||
JOIN public.groups USING (group_id)
|
|
||||||
WHERE user_group.user_id = u.user_id
|
|
||||||
),
|
|
||||||
'[]'
|
|
||||||
) AS groups
|
|
||||||
FROM u LEFT JOIN public.roles USING (role_id)
|
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return cur.fetchone()
|
return cur.fetchone()
|
||||||
|
|
|
||||||
|
|
@ -118,20 +118,11 @@ CREATE TABLE public.roles
|
||||||
protected bool NOT NULL DEFAULT FALSE,
|
protected bool NOT NULL DEFAULT FALSE,
|
||||||
all_projects bool NOT NULL DEFAULT TRUE,
|
all_projects bool NOT NULL DEFAULT TRUE,
|
||||||
created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
created_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||||
|
updated_at timestamp NOT NULL DEFAULT timezone('utc'::text, now()),
|
||||||
deleted_at timestamp NULL DEFAULT NULL,
|
deleted_at timestamp NULL DEFAULT NULL,
|
||||||
service_role bool NOT NULL DEFAULT FALSE
|
service_role bool NOT NULL DEFAULT FALSE
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE public.groups
|
|
||||||
(
|
|
||||||
group_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
||||||
tenant_id integer NOT NULL REFERENCES public.tenants (tenant_id) ON DELETE CASCADE,
|
|
||||||
external_id text,
|
|
||||||
name text NOT NULL,
|
|
||||||
created_at timestamp without time zone NOT NULL DEFAULT (now() at time zone 'utc'),
|
|
||||||
updated_at timestamp without time zone NOT NULL DEFAULT (now() at time zone 'utc')
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TYPE user_role AS ENUM ('owner','admin','member','service');
|
CREATE TYPE user_role AS ENUM ('owner','admin','member','service');
|
||||||
|
|
||||||
CREATE TABLE public.users
|
CREATE TABLE public.users
|
||||||
|
|
@ -167,14 +158,6 @@ CREATE TABLE public.users
|
||||||
CREATE INDEX users_tenant_id_deleted_at_N_idx ON public.users (tenant_id) WHERE deleted_at ISNULL;
|
CREATE INDEX users_tenant_id_deleted_at_N_idx ON public.users (tenant_id) WHERE deleted_at ISNULL;
|
||||||
CREATE INDEX users_name_gin_idx ON public.users USING GIN (name gin_trgm_ops);
|
CREATE INDEX users_name_gin_idx ON public.users USING GIN (name gin_trgm_ops);
|
||||||
|
|
||||||
CREATE TABLE public.user_group
|
|
||||||
(
|
|
||||||
user_group_id integer generated BY DEFAULT AS IDENTITY PRIMARY KEY,
|
|
||||||
user_id integer REFERENCES public.users (user_id) ON DELETE CASCADE,
|
|
||||||
group_id integer REFERENCES public.groups (group_id) ON DELETE CASCADE,
|
|
||||||
UNIQUE (user_id, group_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE public.basic_authentication
|
CREATE TABLE public.basic_authentication
|
||||||
(
|
(
|
||||||
user_id integer NOT NULL REFERENCES public.users (user_id) ON DELETE CASCADE,
|
user_id integer NOT NULL REFERENCES public.users (user_id) ON DELETE CASCADE,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue