49 lines
1.6 KiB
PL/PgSQL
49 lines
1.6 KiB
PL/PgSQL
CREATE OR REPLACE FUNCTION has_node_access(p_node_id UUID, p_user_id UUID)
|
|
RETURNS BOOLEAN
|
|
LANGUAGE sql
|
|
STABLE
|
|
AS $$
|
|
WITH RECURSIVE ancestors AS (
|
|
SELECT id, parent_id FROM files_nodes WHERE id = p_node_id AND deleted_at IS NULL
|
|
UNION ALL
|
|
SELECT p.id, p.parent_id
|
|
FROM files_nodes p
|
|
JOIN ancestors a ON a.parent_id = p.id
|
|
WHERE p.deleted_at IS NULL
|
|
)
|
|
SELECT EXISTS (
|
|
SELECT 1
|
|
FROM ancestors a
|
|
JOIN files_access fa ON fa.node_id = a.id
|
|
WHERE fa.user_id = p_user_id
|
|
);
|
|
$$;
|
|
|
|
CREATE OR REPLACE FUNCTION effective_node_access(p_node_id UUID, p_user_id UUID, p_subordinate_ids TEXT[])
|
|
RETURNS TEXT
|
|
LANGUAGE sql
|
|
STABLE
|
|
AS $$
|
|
WITH RECURSIVE ancestors AS (
|
|
SELECT id, parent_id, owner_user_id FROM files_nodes WHERE id = p_node_id AND deleted_at IS NULL
|
|
UNION ALL
|
|
SELECT p.id, p.parent_id, p.owner_user_id
|
|
FROM files_nodes p
|
|
JOIN ancestors a ON a.parent_id = p.id
|
|
WHERE p.deleted_at IS NULL
|
|
),
|
|
direct_access AS (
|
|
SELECT fa.access_level
|
|
FROM ancestors a
|
|
JOIN files_access fa ON fa.node_id = a.id
|
|
WHERE fa.user_id = p_user_id
|
|
)
|
|
SELECT CASE
|
|
WHEN EXISTS (SELECT 1 FROM files_nodes n WHERE n.id = p_node_id AND n.owner_user_id = p_user_id AND n.deleted_at IS NULL) THEN 'edit'
|
|
WHEN EXISTS (SELECT 1 FROM files_nodes n WHERE n.id = p_node_id AND n.owner_user_id::text = ANY(p_subordinate_ids) AND n.deleted_at IS NULL) THEN 'view'
|
|
WHEN EXISTS (SELECT 1 FROM direct_access WHERE access_level = 'edit') THEN 'edit'
|
|
WHEN EXISTS (SELECT 1 FROM direct_access) THEN 'view'
|
|
ELSE ''
|
|
END;
|
|
$$;
|