Skip to content

Commit cb504a8

Browse files
committed
Generalize to work with any permission
1 parent a01ef79 commit cb504a8

File tree

1 file changed

+15
-19
lines changed

1 file changed

+15
-19
lines changed
Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
-- The previous user_has_project_permission function is called on _every_ project when doing global omnisearch,
22
-- which is too slow.
33

4-
-- Create a view which serves as join table for finding projects we should consider in search, it's much faster
5-
-- than running a permission check for every private project.
6-
CREATE FUNCTION projects_searchable_by_user(arg_user_id UUID)
4+
-- Create a view which serves as join table for finding projects for which the user has a given permission, it's much faster
5+
-- than running a permission check for every private project when we need to discover the list of all projects a user
6+
-- has access to.
7+
--
8+
-- This special-cases the 'project:view' permission to be even faster, it's the most common case.
9+
CREATE FUNCTION projects_by_user_permission(arg_user_id UUID, arg_permission permission)
710
-- Returns a subset of the projects table
811
RETURNS SETOF projects AS $$
912
-- Get all public projects and projects owned by the user,
1013
-- as well as all public projects.
1114
SELECT p.*
1215
FROM projects p
1316
WHERE p.owner_user_id = arg_user_id
14-
OR NOT p.private
17+
OR (arg_permission = 'project:view' AND NOT p.private)
1518
UNION
1619
SELECT
1720
p.*
@@ -20,9 +23,9 @@ UNION
2023
ON om.organization_user_id = p.owner_user_id
2124
JOIN roles r ON om.role_id = r.id
2225
WHERE om.member_user_id = arg_user_id
23-
AND 'project:view' = ANY(r.permissions)
24-
-- All public projects are already included above
25-
AND p.private
26+
AND arg_permission = ANY(r.permissions)
27+
-- All public projects are already included above if the permission is 'project:view'
28+
AND (p.private OR arg_permission <> 'project:view')
2629
UNION
2730
-- Include projects the user is a direct maintainer of
2831
SELECT
@@ -32,18 +35,11 @@ UNION
3235
JOIN roles r ON rm.role_id = r.id
3336
JOIN projects p ON rm.resource_id = p.resource_id
3437
WHERE u.id = arg_user_id
35-
AND 'project:view' = ANY(r.permissions)
36-
AND p.private;
38+
AND arg_permission = ANY(r.permissions)
39+
-- All public projects are already included above if the permission is 'project:view'
40+
AND (p.private OR arg_permission <> 'project:view')
3741
$$ LANGUAGE sql STABLE PARALLEL SAFE;
3842

3943
-- A better index for this query.
40-
-- CREATE INDEX idx_projects_by_owner_and_privacy
41-
-- ON projects (private, owner_user_id);
42-
43-
CREATE INDEX idx_public_projects_by_owner
44-
ON projects (owner_user_id)
45-
WHERE NOT private;
46-
47-
CREATE INDEX idx_private_projects_by_owner
48-
ON projects (owner_user_id)
49-
WHERE private;
44+
CREATE INDEX idx_projects_by_owner_and_privacy
45+
ON projects (private, owner_user_id);

0 commit comments

Comments
 (0)