-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschool_roles.sql
More file actions
249 lines (210 loc) · 8.06 KB
/
school_roles.sql
File metadata and controls
249 lines (210 loc) · 8.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
SELECT current_user;
/* ADMIN SUPER USER ROLE
- assign to (1, 'James', 'Smith') -- Governor (Headteacher)
- assign to (6, 'Elizabeth', 'Taylor') -- Deputy Headteacher
*/
CREATE ROLE admin_su WITH SUPERUSER LOGIN PASSWORD 'admin.su_password';
GRANT USAGE, CREATE ON SCHEMA public TO admin_su;
GRANT ALL PRIVILEGES ON DATABASE school TO admin_su;
CREATE USER james_smith WITH SUPERUSER LOGIN PASSWORD 'j.smith_password';
CREATE USER elizabeth_taylor WITH SUPERUSER LOGIN PASSWORD 'e.taylor_password';
GRANT admin_su TO james_smith;
GRANT admin_su TO elizabeth_taylor;
/* STUDENT ROLE
- can select their own data
- can select staff name, job title and department
*/
CREATE ROLE student_role;
GRANT USAGE ON SCHEMA public TO student_role;
GRANT SELECT ON student TO student_role;
GRANT SELECT ON student_subject_choice TO student_role;
GRANT SELECT ON subject TO student_role;
GRANT SELECT ON person TO student_role;
GRANT SELECT ON tutor_group TO student_role;
GRANT SELECT ON department TO student_role;
GRANT SELECT ON job TO student_role;
GRANT SELECT ON staff_job TO student_role;
GRANT SELECT ON staff TO student_role;
GRANT SELECT ON school TO student_role;
ALTER TABLE student ENABLE ROW LEVEL SECURITY;
ALTER TABLE student_subject_choice ENABLE ROW LEVEL SECURITY;
ALTER TABLE person ENABLE ROW LEVEL SECURITY;
CREATE POLICY student_data_policy ON student FOR SELECT
USING (person_id = (SELECT id FROM person WHERE LOWER(first_name) || '_' || LOWER(last_name) = CURRENT_USER));
CREATE POLICY student_subject_choice_policy ON student_subject_choice FOR SELECT
USING (student_id = (SELECT id FROM student WHERE person_id = (SELECT id FROM person WHERE LOWER(first_name) || '_' || LOWER(last_name) = CURRENT_USER)));
CREATE POLICY student_person_policy ON person FOR SELECT
USING (LOWER(first_name) || '_' || LOWER(last_name) = CURRENT_USER);
CREATE POLICY student_staff_policy ON person FOR SELECT
USING (EXISTS(SELECT 1 FROM staff WHERE staff.person_id = person.id));
CREATE USER alexander_lewis WITH LOGIN PASSWORD 'a.lewis_password';
GRANT student_role TO alexander_lewis;
CREATE USER amelia_cook WITH LOGIN PASSWORD 'a.cook_password';
GRANT student_role TO amelia_cook;
-- continue to create users and grant student_role to all students
/* GOVERNOR ROLE
- can select their own data
- can select staff name, job title and department
- can select governor's start and end dates
*/
CREATE ROLE governor_role;
GRANT USAGE ON SCHEMA public TO governor_role;
GRANT SELECT ON governor TO governor_role;
GRANT SELECT ON department TO governor_role;
GRANT SELECT ON job TO governor_role;
GRANT SELECT ON staff_job TO governor_role;
GRANT SELECT ON staff TO governor_role;
GRANT SELECT ON person TO governor_role;
GRANT SELECT ON school TO governor_role;
CREATE POLICY governor_person_select_policy ON person FOR SELECT
USING (LOWER(first_name) || '_' || LOWER(last_name) = CURRENT_USER);
CREATE USER emily_johnson WITH LOGIN PASSWORD 'e.johnson_password';
GRANT governor_role TO emily_johnson;
-- continue to create users and grant governor_role to all governors
/* STAFF ROLE
- can select their own data
- can select staff name, job title and department
- can view student subject choices
*/
CREATE ROLE staff_role;
GRANT SELECT ON department TO staff_role;
GRANT SELECT ON job TO staff_role;
GRANT SELECT ON staff_job TO staff_role;
GRANT SELECT ON staff TO staff_role;
GRANT SELECT ON person TO staff_role;
GRANT SELECT ON student_subject_choice TO staff_role;
GRANT SELECT ON student TO staff_role;
GRANT SELECT ON subject TO staff_role;
GRANT SELECT ON tutor_group TO staff_role;
GRANT SELECT ON school TO staff_role;
CREATE POLICY staff_person_select_policy ON person FOR SELECT
USING (pg_has_role(current_user, 'staff_role', 'member'));
CREATE POLICY staff_student_select_all_policy ON student FOR SELECT
USING (pg_has_role(current_user, 'staff_role', 'member'));
CREATE POLICY staff_student_subject_choice_select_all_policy ON student_subject_choice FOR SELECT
USING (pg_has_role(current_user, 'staff_role', 'member'));
CREATE USER david_wilson WITH LOGIN PASSWORD 'd.wilson_password';
GRANT staff_role TO david_wilson;
-- continue to create users and grant staff_role to all staff
-- View all policies on database
SELECT *
FROM pg_policies;
/* TEST ROLES
- test to see that the roles allow the user to interact with the database as expected
- test to see that the roles block the user from doing anything they are not allowed to do
*/
/* TEST admin_su */
SET ROLE james_smith;
SELECT current_user; -- check using database as james_smith
-- Select students in years 10 and 11 and show their name, tutor group and subjects
SELECT
p.first_name,
p.last_name,
tg.group_code AS tutor_group,
string_agg(sub.subject, ' -- ') AS subjects
FROM student AS s
JOIN person AS p
ON s.person_id = p.id
JOIN tutor_group AS tg
ON s.tutor_group_id = tg.id
JOIN student_subject_choice AS ssc
ON s.id = ssc.student_id
JOIN subject AS sub
ON ssc.subject_id = sub.id
WHERE s.year_group IN (10, 11)
GROUP BY p.first_name, p.last_name, tutor_group
ORDER BY p.last_name, p.first_name;
-- Add test department, check added, delete test department, check deleted
INSERT INTO department(id, name, school_id)
VALUES (13, 'Test Department', 1);
SELECT * FROM department
WHERE id = 13;
DELETE FROM department
WHERE id = 13;
SELECT * FROM department;
/* TEST student_role */
SET ROLE alexander_lewis;
SELECT current_user; -- check using database as alexander_lewis
-- Ran same queries as admin_su test:
-- only saw data for alexander_lewis in search query
-- received permission denied for insert statement
-- saw department data for all department search query
-- Ran test to check can see staff information, select maths department staff
SELECT
p.first_name,
p.last_name,
string_agg(j.job_title, ' -- ') AS job_titles,
d.name AS department_name
FROM staff AS st
JOIN person AS p
ON st.person_id = p.id
JOIN staff_job AS st_j
ON st.id = st_j.staff_id
JOIN job AS j
ON st_j.job_id = j.id
JOIN department AS d
ON j.department_id = d.id
WHERE d.name = 'Mathematics'
GROUP BY p.first_name, p.last_name, d.name
ORDER BY p.last_name, p.first_name;
SET ROLE amelia_cook;
SELECT current_user; -- check using database as amelia_cook
-- Ran above test to check can see staff information, select maths department staff
-- Ran test to check can see own data
SELECT
p.first_name,
p.last_name,
tg.group_code AS tutor_group
FROM student AS s
JOIN person AS p
ON s.person_id = p.id
JOIN tutor_group AS tg
ON s.tutor_group_id = tg.id
WHERE LOWER(p.first_name) || '_' || LOWER(p.last_name) = current_user
GROUP BY p.first_name, p.last_name, tutor_group;
/* TEST governor_role */
SET ROLE emily_johnson;
SELECT current_user; -- check using database as emily_johnson
-- Ran same queries as admin_su test:
-- received permission denied for search query
-- received permission denied for insert statement
-- saw department data for all department search query
-- Ran above test to check can see staff information, select maths department staff
-- Ran test to check can see own data
SELECT
p.first_name,
p.last_name,
p.email,
g.start_date,
g.end_date
FROM person AS p
JOIN governor AS g
ON p.id = g.person_id
WHERE LOWER(first_name) || '_' || LOWER(last_name) = current_user;
/* TEST staff_role */
SET ROLE david_wilson;
SELECT current_user; -- check using database as david_wilson
-- Ran same queries as admin_su test:
-- saw student data for years 10 and 11 for search query
-- received permission denied for insert statement
-- saw department data for all department search query
-- Ran above test to check can see staff information, select maths department staff
-- Ran test to check can see own data
SELECT
p.first_name,
p.last_name,
p.email,
string_agg(j.job_title, ' -- ') AS job_titles,
d.name AS department_name
FROM staff AS st
JOIN person AS p
ON st.person_id = p.id
JOIN staff_job AS st_j
ON st.id = st_j.staff_id
JOIN job AS j
ON st_j.job_id = j.id
JOIN department AS d
ON j.department_id = d.id
WHERE LOWER(first_name) || '_' || LOWER(last_name) = current_user
GROUP BY p.first_name, p.last_name, p.email, d.name
ORDER BY p.last_name, p.first_name;