gaurv007 commited on
Commit
49131bb
·
verified ·
1 Parent(s): 99d2fd0

fix(rls): infinite recursion in profiles policy — use SECURITY DEFINER is_admin() function

Browse files
Files changed (1) hide show
  1. web/lib/supabase/schema.sql +18 -7
web/lib/supabase/schema.sql CHANGED
@@ -128,24 +128,35 @@ ALTER TABLE public.api_keys ENABLE ROW LEVEL SECURITY;
128
  ALTER TABLE public.custom_rules ENABLE ROW LEVEL SECURITY;
129
  ALTER TABLE public.admin_logs ENABLE ROW LEVEL SECURITY;
130
 
 
 
 
 
 
 
 
 
 
 
 
131
  -- Profiles
132
  CREATE POLICY "Users see own profile" ON public.profiles FOR SELECT USING (auth.uid() = id);
133
  CREATE POLICY "Users update own profile" ON public.profiles FOR UPDATE USING (auth.uid() = id);
134
- CREATE POLICY "Admins read all profiles" ON public.profiles FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
135
- CREATE POLICY "Admins update all profiles" ON public.profiles FOR UPDATE USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
136
 
137
  -- Analyses
138
  CREATE POLICY "Users see own analyses" ON public.analyses FOR SELECT
139
  USING (auth.uid() = user_id OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
140
  CREATE POLICY "Users insert analyses" ON public.analyses FOR INSERT WITH CHECK (auth.uid() = user_id);
141
  CREATE POLICY "Users delete own analyses" ON public.analyses FOR DELETE USING (auth.uid() = user_id);
142
- CREATE POLICY "Admins read all analyses" ON public.analyses FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
143
 
144
  -- Teams
145
  CREATE POLICY "Team members can view" ON public.teams FOR SELECT
146
  USING (id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()) OR owner_id = auth.uid());
147
  CREATE POLICY "Owner can update team" ON public.teams FOR UPDATE USING (owner_id = auth.uid());
148
- CREATE POLICY "Admins read all teams" ON public.teams FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
149
 
150
  -- Team invites
151
  CREATE POLICY "Members see team invites" ON public.team_invites FOR SELECT
@@ -156,17 +167,17 @@ CREATE POLICY "Users can invite" ON public.team_invites FOR INSERT WITH CHECK (i
156
  CREATE POLICY "Users see own API keys" ON public.api_keys FOR SELECT
157
  USING (user_id = auth.uid() OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
158
  CREATE POLICY "Users manage own API keys" ON public.api_keys FOR ALL USING (user_id = auth.uid());
159
- CREATE POLICY "Admins read all api_keys" ON public.api_keys FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
160
 
161
  -- Custom Rules
162
  CREATE POLICY "Users see own rules" ON public.custom_rules FOR SELECT
163
  USING (user_id = auth.uid() OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
164
  CREATE POLICY "Users manage own rules" ON public.custom_rules FOR ALL USING (user_id = auth.uid());
165
- CREATE POLICY "Admins read all rules" ON public.custom_rules FOR SELECT USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
166
 
167
  -- Admin Logs
168
  CREATE POLICY "Admins manage logs" ON public.admin_logs FOR ALL
169
- USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'admin'));
170
 
171
  -- ─── Auto-create profile on signup ───
172
  CREATE OR REPLACE FUNCTION public.handle_new_user()
 
128
  ALTER TABLE public.custom_rules ENABLE ROW LEVEL SECURITY;
129
  ALTER TABLE public.admin_logs ENABLE ROW LEVEL SECURITY;
130
 
131
+ -- ─── FIX v4.3: SECURITY DEFINER function to check admin role ───
132
+ -- Querying profiles FROM a profiles policy causes infinite recursion (42P17).
133
+ -- SECURITY DEFINER bypasses RLS, breaking the cycle.
134
+ CREATE OR REPLACE FUNCTION public.is_admin()
135
+ RETURNS boolean AS $$
136
+ SELECT EXISTS (
137
+ SELECT 1 FROM public.profiles
138
+ WHERE id = auth.uid() AND role = 'admin'
139
+ );
140
+ $$ LANGUAGE sql SECURITY DEFINER STABLE;
141
+
142
  -- Profiles
143
  CREATE POLICY "Users see own profile" ON public.profiles FOR SELECT USING (auth.uid() = id);
144
  CREATE POLICY "Users update own profile" ON public.profiles FOR UPDATE USING (auth.uid() = id);
145
+ CREATE POLICY "Admins read all profiles" ON public.profiles FOR SELECT USING (public.is_admin());
146
+ CREATE POLICY "Admins update all profiles" ON public.profiles FOR UPDATE USING (public.is_admin());
147
 
148
  -- Analyses
149
  CREATE POLICY "Users see own analyses" ON public.analyses FOR SELECT
150
  USING (auth.uid() = user_id OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
151
  CREATE POLICY "Users insert analyses" ON public.analyses FOR INSERT WITH CHECK (auth.uid() = user_id);
152
  CREATE POLICY "Users delete own analyses" ON public.analyses FOR DELETE USING (auth.uid() = user_id);
153
+ CREATE POLICY "Admins read all analyses" ON public.analyses FOR SELECT USING (public.is_admin());
154
 
155
  -- Teams
156
  CREATE POLICY "Team members can view" ON public.teams FOR SELECT
157
  USING (id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()) OR owner_id = auth.uid());
158
  CREATE POLICY "Owner can update team" ON public.teams FOR UPDATE USING (owner_id = auth.uid());
159
+ CREATE POLICY "Admins read all teams" ON public.teams FOR SELECT USING (public.is_admin());
160
 
161
  -- Team invites
162
  CREATE POLICY "Members see team invites" ON public.team_invites FOR SELECT
 
167
  CREATE POLICY "Users see own API keys" ON public.api_keys FOR SELECT
168
  USING (user_id = auth.uid() OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
169
  CREATE POLICY "Users manage own API keys" ON public.api_keys FOR ALL USING (user_id = auth.uid());
170
+ CREATE POLICY "Admins read all api_keys" ON public.api_keys FOR SELECT USING (public.is_admin());
171
 
172
  -- Custom Rules
173
  CREATE POLICY "Users see own rules" ON public.custom_rules FOR SELECT
174
  USING (user_id = auth.uid() OR team_id IN (SELECT team_id FROM public.profiles WHERE id = auth.uid()));
175
  CREATE POLICY "Users manage own rules" ON public.custom_rules FOR ALL USING (user_id = auth.uid());
176
+ CREATE POLICY "Admins read all rules" ON public.custom_rules FOR SELECT USING (public.is_admin());
177
 
178
  -- Admin Logs
179
  CREATE POLICY "Admins manage logs" ON public.admin_logs FOR ALL
180
+ USING (public.is_admin());
181
 
182
  -- ─── Auto-create profile on signup ───
183
  CREATE OR REPLACE FUNCTION public.handle_new_user()