Primeiro commit
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
-- Perfis
|
||||
CREATE TABLE public.perfis (
|
||||
id uuid PRIMARY KEY,
|
||||
email text NOT NULL,
|
||||
aprovado boolean NOT NULL DEFAULT false,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
GRANT SELECT, INSERT, UPDATE ON public.perfis TO authenticated;
|
||||
GRANT ALL ON public.perfis TO service_role;
|
||||
ALTER TABLE public.perfis ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- Papeis
|
||||
CREATE TYPE public.app_role AS ENUM ('admin', 'user');
|
||||
|
||||
CREATE TABLE public.papeis_usuario (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL,
|
||||
role public.app_role NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (user_id, role)
|
||||
);
|
||||
|
||||
GRANT SELECT ON public.papeis_usuario TO authenticated;
|
||||
GRANT ALL ON public.papeis_usuario TO service_role;
|
||||
ALTER TABLE public.papeis_usuario ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.has_role(_user_id uuid, _role public.app_role)
|
||||
RETURNS boolean
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM public.papeis_usuario WHERE user_id = _user_id AND role = _role
|
||||
)
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.is_aprovado(_user_id uuid)
|
||||
RETURNS boolean
|
||||
LANGUAGE sql
|
||||
STABLE
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM public.perfis WHERE id = _user_id AND aprovado = true
|
||||
)
|
||||
$$;
|
||||
|
||||
-- Policies perfis
|
||||
CREATE POLICY "Ver proprio perfil" ON public.perfis
|
||||
FOR SELECT TO authenticated USING (id = auth.uid());
|
||||
CREATE POLICY "Admins veem todos os perfis" ON public.perfis
|
||||
FOR SELECT TO authenticated USING (public.has_role(auth.uid(), 'admin'));
|
||||
CREATE POLICY "Criar proprio perfil" ON public.perfis
|
||||
FOR INSERT TO authenticated WITH CHECK (id = auth.uid());
|
||||
CREATE POLICY "Admins atualizam perfis" ON public.perfis
|
||||
FOR UPDATE TO authenticated
|
||||
USING (public.has_role(auth.uid(), 'admin'))
|
||||
WITH CHECK (public.has_role(auth.uid(), 'admin'));
|
||||
|
||||
-- Policies papeis
|
||||
CREATE POLICY "Ver proprios papeis" ON public.papeis_usuario
|
||||
FOR SELECT TO authenticated USING (user_id = auth.uid());
|
||||
CREATE POLICY "Admins veem todos os papeis" ON public.papeis_usuario
|
||||
FOR SELECT TO authenticated USING (public.has_role(auth.uid(), 'admin'));
|
||||
|
||||
-- Registro de perfil: primeiro usuario vira admin aprovado
|
||||
CREATE OR REPLACE FUNCTION public.registrar_perfil()
|
||||
RETURNS public.perfis
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
DECLARE
|
||||
v_uid uuid := auth.uid();
|
||||
v_email text;
|
||||
v_primeiro boolean;
|
||||
v_perfil public.perfis;
|
||||
BEGIN
|
||||
IF v_uid IS NULL THEN
|
||||
RAISE EXCEPTION 'Nao autenticado';
|
||||
END IF;
|
||||
|
||||
SELECT * INTO v_perfil FROM public.perfis WHERE id = v_uid;
|
||||
IF FOUND THEN
|
||||
RETURN v_perfil;
|
||||
END IF;
|
||||
|
||||
SELECT email INTO v_email FROM auth.users WHERE id = v_uid;
|
||||
SELECT NOT EXISTS (SELECT 1 FROM public.perfis) INTO v_primeiro;
|
||||
|
||||
INSERT INTO public.perfis (id, email, aprovado)
|
||||
VALUES (v_uid, coalesce(v_email, ''), v_primeiro)
|
||||
RETURNING * INTO v_perfil;
|
||||
|
||||
IF v_primeiro THEN
|
||||
INSERT INTO public.papeis_usuario (user_id, role) VALUES (v_uid, 'admin')
|
||||
ON CONFLICT DO NOTHING;
|
||||
END IF;
|
||||
|
||||
RETURN v_perfil;
|
||||
END;
|
||||
$$;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION public.registrar_perfil() TO authenticated;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.set_updated_at()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql
|
||||
SET search_path = public
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = now();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE TRIGGER perfis_updated_at BEFORE UPDATE ON public.perfis
|
||||
FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();
|
||||
|
||||
-- Coletas: apenas usuarios logados e aprovados
|
||||
DROP POLICY IF EXISTS "Coletas sao visiveis publicamente" ON public.coletas;
|
||||
DROP POLICY IF EXISTS "Qualquer um pode atualizar coleta" ON public.coletas;
|
||||
DROP POLICY IF EXISTS "Qualquer um pode criar coleta" ON public.coletas;
|
||||
|
||||
REVOKE ALL ON public.coletas FROM anon;
|
||||
GRANT SELECT, INSERT, UPDATE ON public.coletas TO authenticated;
|
||||
GRANT ALL ON public.coletas TO service_role;
|
||||
|
||||
CREATE POLICY "Aprovados veem coletas" ON public.coletas
|
||||
FOR SELECT TO authenticated USING (public.is_aprovado(auth.uid()));
|
||||
CREATE POLICY "Aprovados criam coletas" ON public.coletas
|
||||
FOR INSERT TO authenticated WITH CHECK (public.is_aprovado(auth.uid()));
|
||||
CREATE POLICY "Aprovados atualizam coletas" ON public.coletas
|
||||
FOR UPDATE TO authenticated
|
||||
USING (public.is_aprovado(auth.uid()))
|
||||
WITH CHECK (public.is_aprovado(auth.uid()));
|
||||
Reference in New Issue
Block a user