1+ -- Create missing indexes to improve query performance.
2+ create index assignments_profile_idx on assignments(profileid);
3+ create index assignments_role_idx on assignments(roleid);
4+ create index comments_org_idx on comments(orgid);
5+ create index comments_person_idx on comments(who);
6+ create index hows_process_idx on hows(processid);
7+ create index processes_accountable_idx on processes(accountable);
8+ create index processes_how_idx on processes(howid);
9+ create index profiles_supervisor_idx on profiles(supervisor);
10+ create index roles_team_index on roles(team);
11+ create index suggestions_lead_index on suggestions(lead);
12+ create index suggestions_who_idx on suggestions(who);
13+
14+ -- More efficient calls to auth.uid().
15+ alter policy " People are viewable by themselves."
16+ on people
17+ using (id = (select auth .uid ()));
18+
19+ alter policy " People can update themselves."
20+ on people
21+ using (id = (select auth .uid ()));
22+
23+ alter policy " People can delete themselves."
24+ on people
25+ using (id = (select auth .uid ()));
26+
27+ alter policy " Admins can update a user's profile, as can a user of their own profile."
28+ on profiles
29+ using ((select auth .uid ()) = personid or isAdmin(orgid));
30+
31+ alter policy " Admins can delete a profile, as can users of their own profile."
32+ on profiles
33+ using ((select auth .uid ()) = personid or isAdmin(orgid));
34+
35+ alter policy " allow comments by members"
36+ on suggestions
37+ using (isAdmin(orgid) or who = (select auth .uid ()));
38+
39+ alter policy " Any admin or the person who reported it can delete a suggestion"
40+ on suggestions
41+ using (isAdmin(orgid) or who = (select auth .uid ()));
42+
43+ alter policy " Any admin or the person who reported it can update a comment."
44+ on comments
45+ using (isAdmin(orgid) or who = (select auth .uid ()));
46+
47+ alter policy " Any admin or the person who reported it can delete a comment."
48+ on comments
49+ using (isAdmin(orgid) or who = (select auth .uid ()));
50+
51+ -- Disallow mutable search paths
52+ create or replace function isAdmin (" _orgid" uuid)
53+ returns boolean
54+ language sql
55+ security definer set search_path = ' '
56+ as $$
57+ select exists (
58+ select personid from public .profiles where
59+ public .profiles .orgid = _orgid and
60+ public .profiles .personid = (select auth .uid ()) and
61+ public .profiles .admin = true
62+ );
63+ $$;
64+
65+ create or replace function getProfileID (" _orgid" uuid)
66+ returns uuid
67+ language sql
68+ security definer set search_path = ' '
69+ as $$
70+ select id from public .profiles where public .profiles .orgid = _orgid and personid = (select auth .uid ())
71+ $$;
72+
73+ create or replace function isEditableHow (" _orgid" uuid, " _processid" uuid)
74+ returns boolean
75+ language sql
76+ security definer set search_path = ' '
77+ as $$
78+ select (
79+ public .isAdmin (_orgid)
80+ -- If no one is accountable, anyone in the org can update it.
81+ or ((select accountable from public .processes where id = _processid) = null and public .isMember (_orgid))
82+ -- If the person is accountable, they can update it.
83+ or exists (select roleid from public .assignments where (select accountable from public .processes where id = _processid) = roleid and public .assignments .profileid = public .getProfileID (_orgid))
84+ -- If there is a how for this process that contains an assignment with this person's ID, they can update it.
85+ or exists (
86+ select id
87+ from public .hows where
88+ hows .processid = _processid AND
89+ (select roleid from public .assignments where public .assignments .profileid = public .getProfileID (_orgid)) = ANY(public .hows .responsible)
90+ )
91+ );
92+ $$;
93+
94+ create or replace function public .create_org(adminname text , orgname text , invite uuid, uid uuid, email text )
95+ returns uuid
96+ language plpgsql
97+ security definer set search_path to ' '
98+ as $function$
99+ declare
100+ orgid uuid;
101+ begin
102+ raise log ' Starting org create' ;
103+ -- Invite already used? Return null;
104+ if not exists (select * from public .invites where id = invite and used = false) then
105+ raise log ' No valid invite' ;
106+ return null ;
107+ end if;
108+ -- Use the invite
109+ raise log ' Updating invite' ;
110+ update public .invites set used = true, who = uid where id = invite;
111+ -- Create the organization
112+ raise log ' Creating the org' ;
113+ insert into public .orgs (name) values (orgName) returning id into orgid;
114+ -- Add the user into the profiles for the organization
115+ raise log ' Adding the profile' ;
116+ insert into public .profiles (orgid, personid, name, email, admin) values (orgid, uid, adminName, email, true);
117+ -- Return the org id
118+ return orgid;
119+ end;
120+ $function$
121+ ;
122+
123+ create or replace function path_available (_path text )
124+ returns boolean
125+ language plpgsql
126+ security definer set search_path = ' '
127+ as $$
128+ begin
129+ if not exists (select from public .orgs where _path = any(paths))
130+ then
131+ return true;
132+ else
133+ return false;
134+ end if;
135+ end;
136+ $$;
137+
138+ create or replace function public .handle_new_profile()
139+ returns trigger
140+ language plpgsql
141+ security definer set search_path = ' '
142+ as $$
143+ begin
144+ update public .profiles set personid = people .id from public .people where public .people .email = new .email AND new .email = public .profiles .email;
145+ return new;
146+ end;
147+ $$;
148+
149+ create or replace function public .handle_new_person()
150+ returns trigger
151+ language plpgsql
152+ security definer set search_path = ' '
153+ as $$
154+ begin
155+ -- Insert the new user into the people table.
156+ insert into public .people (id, email)
157+ values (new .id , new .email );
158+ -- If any profile has this email address, update the profile's personid.
159+ update public .profiles set personid = new .id where email = new .email ;
160+ -- Return the new row.
161+ return new;
162+ end;
163+ $$;
164+
165+ create or replace function getVisibility (" _orgid" uuid)
166+ returns visibility
167+ language sql
168+ security definer set search_path = ' '
169+ as $$
170+ select visibility from public .orgs where id = _orgid;
171+ $$;
172+
173+ create or replace function isMember (" _orgid" uuid)
174+ returns boolean
175+ language sql
176+ security definer set search_path = ' '
177+ as $$
178+ select exists (
179+ select personid from public .profiles where
180+ public .profiles .orgid = _orgid and
181+ public .profiles .personid = auth .uid ()
182+ );
183+ $$;
0 commit comments