import 'package:flutter/material.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:tugas_akhir_supabase/utils/fix_users_policy.dart'; import 'package:tugas_akhir_supabase/utils/fix_user_roles_policy.dart'; /// Utility class to fix all database policies class FixDatabasePoliciesUtil { /// Fix all database policies to prevent infinite recursion static Future fixAllPolicies(BuildContext context) async { try { // Show loading dialog showDialog( context: context, barrierDismissible: false, builder: (context) => const AlertDialog( content: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('Memperbaiki semua kebijakan database...'), ], ), ), ); final client = Supabase.instance.client; // Step 1: Fix users policy try { // Drop the problematic policy await client.rpc( 'execute_sql', params: { 'sql_statement': 'DROP POLICY IF EXISTS users_policy ON auth.users;', }, ); print('Dropped users policy'); // Create a new policy without recursion await client.rpc( 'execute_sql', params: { 'sql_statement': ''' CREATE POLICY users_policy ON auth.users FOR SELECT USING ( auth.uid() = id OR EXISTS ( SELECT 1 FROM public.user_roles WHERE user_id = auth.uid() AND role = 'admin' ) ); ''', }, ); print('Created new users policy'); // Grant necessary permissions await client.rpc( 'execute_sql', params: { 'sql_statement': 'GRANT SELECT ON auth.users TO authenticated; GRANT SELECT ON auth.users TO anon;', }, ); print('Granted permissions for users'); } catch (e) { print('Error fixing users policy: $e'); } // Step 2: Fix user_roles policy try { // Drop ALL existing policies await client.rpc( 'execute_sql', params: { 'sql_statement': ''' DROP POLICY IF EXISTS "Users can view their own roles" ON public.user_roles; DROP POLICY IF EXISTS "Admins can manage all roles" ON public.user_roles; DROP POLICY IF EXISTS "Users can manage their own roles" ON public.user_roles; DROP POLICY IF EXISTS "Admins can view all roles" ON public.user_roles; DROP POLICY IF EXISTS "All users can view roles" ON public.user_roles; DROP POLICY IF EXISTS "Users can view own role" ON public.user_roles; DROP POLICY IF EXISTS "Users can view their roles" ON public.user_roles; DROP POLICY IF EXISTS "Admins can manage roles" ON public.user_roles; ''', }, ); print('Dropped all user_roles policies'); // Create new clean policies await client.rpc( 'execute_sql', params: { 'sql_statement': ''' -- Policy for users to manage their own roles CREATE POLICY "user_roles_self_management" ON public.user_roles FOR ALL USING (auth.uid() = user_id); -- Policy for admins to see all roles (without recursion) CREATE POLICY "user_roles_view_all" ON public.user_roles FOR SELECT TO authenticated USING (true); ''', }, ); print('Created new user_roles policies'); // Grant necessary permissions await client.rpc( 'execute_sql', params: { 'sql_statement': 'GRANT SELECT ON public.user_roles TO authenticated; GRANT SELECT ON public.user_roles TO anon;', }, ); print('Granted permissions for user_roles'); } catch (e) { print('Error fixing user_roles policy: $e'); } // Step 3: Ensure current user is admin try { final userId = client.auth.currentUser?.id; if (userId != null) { await client.rpc( 'execute_sql', params: { 'sql_statement': ''' INSERT INTO public.user_roles (user_id, role) SELECT '$userId', 'admin' WHERE NOT EXISTS ( SELECT 1 FROM public.user_roles WHERE user_id = '$userId' AND role = 'admin' ); ''', }, ); print('Ensured current user is admin'); } } catch (e) { print('Error ensuring admin status: $e'); } // Close the dialog Navigator.pop(context); // Show success message ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Semua kebijakan database berhasil diperbaiki'), backgroundColor: Colors.green, ), ); } catch (e) { print('Error fixing database policies: $e'); // Close the dialog if it's open Navigator.pop(context); // Show error message ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Gagal memperbaiki kebijakan database: ${e.toString()}'), backgroundColor: Colors.red, ), ); } } }