since3-portal/lib/supabase/migrations/20260929120000_allow_client_write_credentials.sql
2026-09-28 20:17:33 +02:00

39 lines
1.7 KiB
PL/PgSQL

-- Clients dürfen eigene Credentials anlegen und bearbeiten (nicht löschen).
-- Löschen bleibt exklusiv Admin (siehe RLS-Policy credentials_admin_delete).
create or replace function public.create_credential(
p_client_id uuid, p_service text, p_username text, p_password text
) returns uuid language plpgsql security definer set search_path = '' as $$
declare v_secret uuid; v_id uuid;
begin
if not (public.is_admin() or p_client_id = public.current_client_id()) then
raise exception 'forbidden' using errcode = '42501';
end if;
v_secret := vault.create_secret(p_password, 'cred_' || gen_random_uuid()::text, p_service);
insert into public.credentials (client_id, service, username, vault_secret_id, updated_by)
values (p_client_id, p_service, p_username, v_secret, auth.uid())
returning id into v_id;
return v_id;
end $$;
-- p_password = NULL -> Passwort bleibt unverändert
create or replace function public.update_credential(
p_id uuid, p_service text, p_username text, p_password text default null
) returns void language plpgsql security definer set search_path = '' as $$
declare v_secret uuid; v_client uuid;
begin
select client_id, vault_secret_id into v_client, v_secret
from public.credentials where id = p_id;
if not found then raise exception 'credential not found'; end if;
if not (public.is_admin() or v_client = public.current_client_id()) then
raise exception 'forbidden' using errcode = '42501';
end if;
update public.credentials
set service = p_service, username = p_username, updated_by = auth.uid()
where id = p_id;
if p_password is not null and p_password <> '' then
perform vault.update_secret(v_secret, p_password);
end if;
end $$;