Skip to content

Commit 545c4b7

Browse files
feat(db): add RLS policies for child tables, tickets, chats, and lookups
Enable Row-Level Security on 26 remaining unprotected tables: - exam_questions, question_options: authenticated SELECT, teacher/admin ALL - exam_answers, exam_scores, exam_views: user-scoped with teacher/admin access - exercise submissions, completions, files, messages: user-scoped - lesson_comments, lesson_passed, lesson_views: user-scoped - tickets, ticket_messages: user own + admin management - submissions: student own, teacher/admin grading - chats, messages: user own + admin access - comment_flags, comment_reactions: user-scoped moderation - grades, assignments: student view, teacher/admin management - plan_courses, roles, permissions, role_permissions: public SELECT - landing_page_templates: public SELECT, super admin management All 38 previously unprotected tables now have RLS enabled. Anon write access fully revoked across all tables. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 10d5765 commit 545c4b7

6 files changed

Lines changed: 418 additions & 0 deletions
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
-- RLS for exam child tables - Batch 7
2+
3+
-- EXAM_QUESTIONS
4+
ALTER TABLE public.exam_questions ENABLE ROW LEVEL SECURITY;
5+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exam_questions FROM anon;
6+
REVOKE TRUNCATE ON public.exam_questions FROM authenticated;
7+
8+
CREATE POLICY "Authenticated users can view exam questions"
9+
ON public.exam_questions FOR SELECT TO authenticated
10+
USING (true);
11+
12+
CREATE POLICY "Teachers and admins can manage exam questions"
13+
ON public.exam_questions FOR ALL TO authenticated
14+
USING (get_tenant_role() IN ('teacher', 'admin'))
15+
WITH CHECK (get_tenant_role() IN ('teacher', 'admin'));
16+
17+
-- QUESTION_OPTIONS
18+
ALTER TABLE public.question_options ENABLE ROW LEVEL SECURITY;
19+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.question_options FROM anon;
20+
REVOKE TRUNCATE ON public.question_options FROM authenticated;
21+
22+
CREATE POLICY "Authenticated users can view question options"
23+
ON public.question_options FOR SELECT TO authenticated
24+
USING (true);
25+
26+
CREATE POLICY "Teachers and admins can manage question options"
27+
ON public.question_options FOR ALL TO authenticated
28+
USING (get_tenant_role() IN ('teacher', 'admin'))
29+
WITH CHECK (get_tenant_role() IN ('teacher', 'admin'));
30+
31+
-- EXAM_ANSWERS
32+
ALTER TABLE public.exam_answers ENABLE ROW LEVEL SECURITY;
33+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exam_answers FROM anon;
34+
REVOKE TRUNCATE ON public.exam_answers FROM authenticated;
35+
36+
CREATE POLICY "Authenticated users can view exam answers"
37+
ON public.exam_answers FOR SELECT TO authenticated
38+
USING (true);
39+
40+
CREATE POLICY "Authenticated users can create exam answers"
41+
ON public.exam_answers FOR INSERT TO authenticated
42+
WITH CHECK (true);
43+
44+
CREATE POLICY "Teachers and admins can update exam answers"
45+
ON public.exam_answers FOR UPDATE TO authenticated
46+
USING (get_tenant_role() IN ('teacher', 'admin'));
47+
48+
-- EXAM_SCORES
49+
ALTER TABLE public.exam_scores ENABLE ROW LEVEL SECURITY;
50+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exam_scores FROM anon;
51+
REVOKE TRUNCATE ON public.exam_scores FROM authenticated;
52+
53+
CREATE POLICY "Students can view own exam scores"
54+
ON public.exam_scores FOR SELECT TO authenticated
55+
USING (auth.uid() = student_id);
56+
57+
CREATE POLICY "Teachers and admins can view all exam scores"
58+
ON public.exam_scores FOR SELECT TO authenticated
59+
USING (get_tenant_role() IN ('teacher', 'admin'));
60+
61+
CREATE POLICY "Teachers and admins can manage exam scores"
62+
ON public.exam_scores FOR ALL TO authenticated
63+
USING (get_tenant_role() IN ('teacher', 'admin'))
64+
WITH CHECK (get_tenant_role() IN ('teacher', 'admin'));
65+
66+
-- EXAM_VIEWS
67+
ALTER TABLE public.exam_views ENABLE ROW LEVEL SECURITY;
68+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exam_views FROM anon;
69+
REVOKE TRUNCATE ON public.exam_views FROM authenticated;
70+
71+
CREATE POLICY "Users can view own exam views"
72+
ON public.exam_views FOR SELECT TO authenticated
73+
USING (auth.uid() = user_id);
74+
75+
CREATE POLICY "Users can create own exam views"
76+
ON public.exam_views FOR INSERT TO authenticated
77+
WITH CHECK (auth.uid() = user_id);
78+
79+
CREATE POLICY "Teachers and admins can view all exam views"
80+
ON public.exam_views FOR SELECT TO authenticated
81+
USING (get_tenant_role() IN ('teacher', 'admin'));
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
-- RLS for exercise child tables - Batch 8
2+
3+
-- EXERCISE_CODE_STUDENT_SUBMISSIONS
4+
ALTER TABLE public.exercise_code_student_submissions ENABLE ROW LEVEL SECURITY;
5+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exercise_code_student_submissions FROM anon;
6+
REVOKE TRUNCATE ON public.exercise_code_student_submissions FROM authenticated;
7+
8+
CREATE POLICY "Students can manage own code submissions"
9+
ON public.exercise_code_student_submissions FOR ALL TO authenticated
10+
USING (auth.uid() = user_id)
11+
WITH CHECK (auth.uid() = user_id);
12+
13+
CREATE POLICY "Teachers and admins can view all code submissions"
14+
ON public.exercise_code_student_submissions FOR SELECT TO authenticated
15+
USING (get_tenant_role() IN ('teacher', 'admin'));
16+
17+
-- EXERCISE_COMPLETIONS
18+
ALTER TABLE public.exercise_completions ENABLE ROW LEVEL SECURITY;
19+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exercise_completions FROM anon;
20+
REVOKE TRUNCATE ON public.exercise_completions FROM authenticated;
21+
22+
CREATE POLICY "Students can manage own exercise completions"
23+
ON public.exercise_completions FOR ALL TO authenticated
24+
USING (auth.uid() = user_id)
25+
WITH CHECK (auth.uid() = user_id);
26+
27+
CREATE POLICY "Teachers and admins can view all exercise completions"
28+
ON public.exercise_completions FOR SELECT TO authenticated
29+
USING (get_tenant_role() IN ('teacher', 'admin'));
30+
31+
-- EXERCISE_FILES
32+
ALTER TABLE public.exercise_files ENABLE ROW LEVEL SECURITY;
33+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exercise_files FROM anon;
34+
REVOKE TRUNCATE ON public.exercise_files FROM authenticated;
35+
36+
CREATE POLICY "Authenticated users can view exercise files"
37+
ON public.exercise_files FOR SELECT TO authenticated
38+
USING (true);
39+
40+
CREATE POLICY "Teachers and admins can manage exercise files"
41+
ON public.exercise_files FOR ALL TO authenticated
42+
USING (get_tenant_role() IN ('teacher', 'admin'))
43+
WITH CHECK (get_tenant_role() IN ('teacher', 'admin'));
44+
45+
-- EXERCISE_MESSAGES
46+
ALTER TABLE public.exercise_messages ENABLE ROW LEVEL SECURITY;
47+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.exercise_messages FROM anon;
48+
REVOKE TRUNCATE ON public.exercise_messages FROM authenticated;
49+
50+
CREATE POLICY "Students can manage own exercise messages"
51+
ON public.exercise_messages FOR ALL TO authenticated
52+
USING (auth.uid() = user_id)
53+
WITH CHECK (auth.uid() = user_id);
54+
55+
CREATE POLICY "Teachers and admins can view all exercise messages"
56+
ON public.exercise_messages FOR SELECT TO authenticated
57+
USING (get_tenant_role() IN ('teacher', 'admin'));
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
-- RLS for lesson child tables - Batch 9
2+
3+
-- LESSON_COMMENTS
4+
ALTER TABLE public.lesson_comments ENABLE ROW LEVEL SECURITY;
5+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.lesson_comments FROM anon;
6+
REVOKE TRUNCATE ON public.lesson_comments FROM authenticated;
7+
8+
CREATE POLICY "Authenticated users can view lesson comments"
9+
ON public.lesson_comments FOR SELECT TO authenticated
10+
USING (true);
11+
12+
CREATE POLICY "Users can create own lesson comments"
13+
ON public.lesson_comments FOR INSERT TO authenticated
14+
WITH CHECK (auth.uid() = user_id);
15+
16+
CREATE POLICY "Users can update own lesson comments"
17+
ON public.lesson_comments FOR UPDATE TO authenticated
18+
USING (auth.uid() = user_id)
19+
WITH CHECK (auth.uid() = user_id);
20+
21+
CREATE POLICY "Users can delete own lesson comments"
22+
ON public.lesson_comments FOR DELETE TO authenticated
23+
USING (auth.uid() = user_id);
24+
25+
CREATE POLICY "Admins can delete any lesson comment"
26+
ON public.lesson_comments FOR DELETE TO authenticated
27+
USING (get_tenant_role() = 'admin');
28+
29+
-- LESSON_PASSED
30+
ALTER TABLE public.lesson_passed ENABLE ROW LEVEL SECURITY;
31+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.lesson_passed FROM anon;
32+
REVOKE TRUNCATE ON public.lesson_passed FROM authenticated;
33+
34+
CREATE POLICY "Students can manage own lesson passed"
35+
ON public.lesson_passed FOR ALL TO authenticated
36+
USING (auth.uid() = user_id)
37+
WITH CHECK (auth.uid() = user_id);
38+
39+
CREATE POLICY "Teachers and admins can view all lesson passed"
40+
ON public.lesson_passed FOR SELECT TO authenticated
41+
USING (get_tenant_role() IN ('teacher', 'admin'));
42+
43+
-- LESSON_VIEWS
44+
ALTER TABLE public.lesson_views ENABLE ROW LEVEL SECURITY;
45+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.lesson_views FROM anon;
46+
REVOKE TRUNCATE ON public.lesson_views FROM authenticated;
47+
48+
CREATE POLICY "Students can manage own lesson views"
49+
ON public.lesson_views FOR ALL TO authenticated
50+
USING (auth.uid() = user_id)
51+
WITH CHECK (auth.uid() = user_id);
52+
53+
CREATE POLICY "Teachers and admins can view all lesson views"
54+
ON public.lesson_views FOR SELECT TO authenticated
55+
USING (get_tenant_role() IN ('teacher', 'admin'));
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
-- RLS for tickets, ticket_messages, submissions - Batch 10
2+
3+
-- TICKETS
4+
ALTER TABLE public.tickets ENABLE ROW LEVEL SECURITY;
5+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.tickets FROM anon;
6+
REVOKE TRUNCATE ON public.tickets FROM authenticated;
7+
8+
CREATE POLICY "Users can view own tickets"
9+
ON public.tickets FOR SELECT TO authenticated
10+
USING (auth.uid() = user_id);
11+
12+
CREATE POLICY "Users can create own tickets"
13+
ON public.tickets FOR INSERT TO authenticated
14+
WITH CHECK (auth.uid() = user_id);
15+
16+
CREATE POLICY "Users can update own tickets"
17+
ON public.tickets FOR UPDATE TO authenticated
18+
USING (auth.uid() = user_id);
19+
20+
CREATE POLICY "Admins can view all tickets"
21+
ON public.tickets FOR SELECT TO authenticated
22+
USING (get_tenant_role() = 'admin');
23+
24+
CREATE POLICY "Admins can update all tickets"
25+
ON public.tickets FOR UPDATE TO authenticated
26+
USING (get_tenant_role() = 'admin');
27+
28+
-- TICKET_MESSAGES
29+
ALTER TABLE public.ticket_messages ENABLE ROW LEVEL SECURITY;
30+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.ticket_messages FROM anon;
31+
REVOKE TRUNCATE ON public.ticket_messages FROM authenticated;
32+
33+
CREATE POLICY "Users can view messages on own tickets"
34+
ON public.ticket_messages FOR SELECT TO authenticated
35+
USING (auth.uid() = user_id OR EXISTS (
36+
SELECT 1 FROM tickets t WHERE t.ticket_id = ticket_messages.ticket_id AND t.user_id = auth.uid()
37+
));
38+
39+
CREATE POLICY "Users can create messages on own tickets"
40+
ON public.ticket_messages FOR INSERT TO authenticated
41+
WITH CHECK (auth.uid() = user_id);
42+
43+
CREATE POLICY "Admins can view all ticket messages"
44+
ON public.ticket_messages FOR SELECT TO authenticated
45+
USING (get_tenant_role() = 'admin');
46+
47+
CREATE POLICY "Admins can create ticket messages"
48+
ON public.ticket_messages FOR INSERT TO authenticated
49+
WITH CHECK (get_tenant_role() = 'admin');
50+
51+
-- SUBMISSIONS
52+
ALTER TABLE public.submissions ENABLE ROW LEVEL SECURITY;
53+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.submissions FROM anon;
54+
REVOKE TRUNCATE ON public.submissions FROM authenticated;
55+
56+
CREATE POLICY "Students can view own submissions"
57+
ON public.submissions FOR SELECT TO authenticated
58+
USING (auth.uid() = student_id);
59+
60+
CREATE POLICY "Students can create own submissions"
61+
ON public.submissions FOR INSERT TO authenticated
62+
WITH CHECK (auth.uid() = student_id);
63+
64+
CREATE POLICY "Teachers and admins can view all submissions"
65+
ON public.submissions FOR SELECT TO authenticated
66+
USING (get_tenant_role() IN ('teacher', 'admin'));
67+
68+
CREATE POLICY "Teachers and admins can update submissions"
69+
ON public.submissions FOR UPDATE TO authenticated
70+
USING (get_tenant_role() IN ('teacher', 'admin'));
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
-- RLS for chats, messages, comment_flags, comment_reactions - Batch 11
2+
3+
-- CHATS
4+
ALTER TABLE public.chats ENABLE ROW LEVEL SECURITY;
5+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.chats FROM anon;
6+
REVOKE TRUNCATE ON public.chats FROM authenticated;
7+
8+
CREATE POLICY "Users can manage own chats"
9+
ON public.chats FOR ALL TO authenticated
10+
USING (auth.uid() = user_id)
11+
WITH CHECK (auth.uid() = user_id);
12+
13+
CREATE POLICY "Admins can view all chats"
14+
ON public.chats FOR SELECT TO authenticated
15+
USING (get_tenant_role() = 'admin');
16+
17+
-- MESSAGES
18+
ALTER TABLE public.messages ENABLE ROW LEVEL SECURITY;
19+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.messages FROM anon;
20+
REVOKE TRUNCATE ON public.messages FROM authenticated;
21+
22+
CREATE POLICY "Authenticated users can create messages"
23+
ON public.messages FOR INSERT TO authenticated
24+
WITH CHECK (true);
25+
26+
CREATE POLICY "Admins can manage messages"
27+
ON public.messages FOR ALL TO authenticated
28+
USING (get_tenant_role() = 'admin')
29+
WITH CHECK (get_tenant_role() = 'admin');
30+
31+
-- COMMENT_FLAGS
32+
ALTER TABLE public.comment_flags ENABLE ROW LEVEL SECURITY;
33+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.comment_flags FROM anon;
34+
REVOKE TRUNCATE ON public.comment_flags FROM authenticated;
35+
36+
CREATE POLICY "Users can create own comment flags"
37+
ON public.comment_flags FOR INSERT TO authenticated
38+
WITH CHECK (auth.uid() = user_id);
39+
40+
CREATE POLICY "Users can view own comment flags"
41+
ON public.comment_flags FOR SELECT TO authenticated
42+
USING (auth.uid() = user_id);
43+
44+
CREATE POLICY "Admins can view all comment flags"
45+
ON public.comment_flags FOR SELECT TO authenticated
46+
USING (get_tenant_role() = 'admin');
47+
48+
CREATE POLICY "Admins can delete comment flags"
49+
ON public.comment_flags FOR DELETE TO authenticated
50+
USING (get_tenant_role() = 'admin');
51+
52+
-- COMMENT_REACTIONS
53+
ALTER TABLE public.comment_reactions ENABLE ROW LEVEL SECURITY;
54+
REVOKE TRUNCATE, DELETE, INSERT, UPDATE ON public.comment_reactions FROM anon;
55+
REVOKE TRUNCATE ON public.comment_reactions FROM authenticated;
56+
57+
CREATE POLICY "Authenticated users can view comment reactions"
58+
ON public.comment_reactions FOR SELECT TO authenticated
59+
USING (true);
60+
61+
CREATE POLICY "Users can create own comment reactions"
62+
ON public.comment_reactions FOR INSERT TO authenticated
63+
WITH CHECK (auth.uid() = user_id);
64+
65+
CREATE POLICY "Users can delete own comment reactions"
66+
ON public.comment_reactions FOR DELETE TO authenticated
67+
USING (auth.uid() = user_id);

0 commit comments

Comments
 (0)