🚀 Initial commit: Versão atual do TrackSteel APP
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
|
||||
-- Criar enum para níveis de permissão
|
||||
CREATE TYPE public.permission_level AS ENUM (
|
||||
'can_admin',
|
||||
'can_create_update_delete',
|
||||
'can_create_only',
|
||||
'can_view_only',
|
||||
'no_access'
|
||||
);
|
||||
|
||||
-- Criar tabela para permissões específicas por usuário e recurso
|
||||
CREATE TABLE public.user_interface_permissions (
|
||||
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
resource_key TEXT NOT NULL REFERENCES public.interface_resources(resource_key) ON DELETE CASCADE,
|
||||
permission public.permission_level NOT NULL DEFAULT 'no_access',
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (user_id, resource_key)
|
||||
);
|
||||
|
||||
-- Criar índice para busca por resource_key
|
||||
CREATE INDEX idx_user_interface_permissions_resource_key ON public.user_interface_permissions(resource_key);
|
||||
|
||||
-- Habilitar RLS
|
||||
ALTER TABLE public.user_interface_permissions ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Política para SELECT: usuário pode ver suas próprias permissões, admin pode ver todas
|
||||
CREATE POLICY "Users can view own permissions, admins can view all"
|
||||
ON public.user_interface_permissions
|
||||
FOR SELECT
|
||||
USING (
|
||||
auth.uid() = user_id OR
|
||||
public.has_role(auth.uid(), 'admin'::app_role)
|
||||
);
|
||||
|
||||
-- Política para INSERT/UPDATE/DELETE: apenas admin
|
||||
CREATE POLICY "Only admins can manage user permissions"
|
||||
ON public.user_interface_permissions
|
||||
FOR ALL
|
||||
USING (public.has_role(auth.uid(), 'admin'::app_role))
|
||||
WITH CHECK (public.has_role(auth.uid(), 'admin'::app_role));
|
||||
|
||||
-- Trigger para atualizar updated_at
|
||||
CREATE OR REPLACE FUNCTION public.update_user_permissions_updated_at()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER update_user_interface_permissions_updated_at
|
||||
BEFORE UPDATE ON public.user_interface_permissions
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION public.update_user_permissions_updated_at();
|
||||
|
||||
-- Função RPC para obter permissão efetiva de um usuário para um recurso específico
|
||||
CREATE OR REPLACE FUNCTION public.get_effective_permission_for_resource(
|
||||
_user_id UUID,
|
||||
_resource_key TEXT
|
||||
)
|
||||
RETURNS public.permission_level
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
user_permission public.permission_level;
|
||||
user_privileges RECORD;
|
||||
BEGIN
|
||||
-- Se é admin, sempre retorna can_admin
|
||||
IF public.has_role(_user_id, 'admin'::app_role) THEN
|
||||
RETURN 'can_admin'::permission_level;
|
||||
END IF;
|
||||
|
||||
-- Verificar se existe override específico para este usuário e recurso
|
||||
SELECT permission INTO user_permission
|
||||
FROM public.user_interface_permissions
|
||||
WHERE user_id = _user_id AND resource_key = _resource_key;
|
||||
|
||||
-- Se existe override, retornar ele
|
||||
IF user_permission IS NOT NULL THEN
|
||||
RETURN user_permission;
|
||||
END IF;
|
||||
|
||||
-- Caso contrário, usar permissões funcionais do privilégio do usuário
|
||||
SELECT p.permissions INTO user_privileges
|
||||
FROM public.profiles pr
|
||||
JOIN public.privileges p ON pr.privilege_id = p.id
|
||||
WHERE pr.id = _user_id;
|
||||
|
||||
-- Se não tem privilégio definido, sem acesso
|
||||
IF user_privileges.permissions IS NULL THEN
|
||||
RETURN 'no_access'::permission_level;
|
||||
END IF;
|
||||
|
||||
-- Converter permissões funcionais para permission_level (maior nível disponível)
|
||||
IF (user_privileges.permissions->>'can_admin')::boolean = true THEN
|
||||
RETURN 'can_admin'::permission_level;
|
||||
ELSIF (user_privileges.permissions->>'can_create_update_delete')::boolean = true THEN
|
||||
RETURN 'can_create_update_delete'::permission_level;
|
||||
ELSIF (user_privileges.permissions->>'can_create_only')::boolean = true THEN
|
||||
RETURN 'can_create_only'::permission_level;
|
||||
ELSIF (user_privileges.permissions->>'can_view_only')::boolean = true THEN
|
||||
RETURN 'can_view_only'::permission_level;
|
||||
ELSE
|
||||
RETURN 'no_access'::permission_level;
|
||||
END IF;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- Função RPC para obter todas as permissões efetivas de um usuário
|
||||
CREATE OR REPLACE FUNCTION public.get_effective_permissions_for_user(_user_id UUID)
|
||||
RETURNS TABLE(resource_key TEXT, permission public.permission_level)
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
ir.resource_key,
|
||||
public.get_effective_permission_for_resource(_user_id, ir.resource_key) as permission
|
||||
FROM public.interface_resources ir
|
||||
ORDER BY ir.resource_key;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- Habilitar realtime para a tabela user_interface_permissions
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE public.user_interface_permissions;
|
||||
|
||||
-- Definir REPLICA IDENTITY FULL para payloads completos no realtime
|
||||
ALTER TABLE public.user_interface_permissions REPLICA IDENTITY FULL;
|
||||
Reference in New Issue
Block a user