caterium-app/ops/sql/SUPABASE-FRESH-FINAL-GUARDS.sql

53 lines
4.0 KiB
PL/PgSQL

-- Explicit API grants, with RLS on every application table.
do $$ declare f record;begin
for f in select p.oid::regprocedure as signature from pg_proc p join pg_namespace n on n.oid=p.pronamespace
where n.nspname='public' and (p.proname like 'sun_%' or p.proname like 'caterium_%') loop
execute format('revoke execute on function %s from public,anon',f.signature);
end loop;
end $$;
grant execute on function public.caterium_trial_promo_preview(text,text),public.sun_invite_preview_v27(uuid) to anon,authenticated;
grant execute on function public.sun_v17_log_error(uuid,text,text,text,text,text,jsonb) to authenticated;
-- No direct full-state writes/reads: retain the subscription/permission checks.
revoke all on public.sun_app_state from anon,authenticated;
-- Enforce MFA even if a caller uses an older public platform RPC name.
do $$ declare f record;definition text;begin
for f in select p.oid from pg_proc p join pg_namespace n on n.oid=p.pronamespace
where n.nspname='public' and p.proname like 'sun_platform_%' and p.prosrc like '%if not public.sun_is_platform_admin() then raise exception ''Platform administrator required''; end if;%' loop
definition:=replace(pg_get_functiondef(f.oid),'if not public.sun_is_platform_admin() then raise exception ''Platform administrator required''; end if;','perform public.sun_require_platform_admin_aal2();');
execute definition;
end loop;
end $$;
create or replace function public.sun_v17_entity_snapshot(p_workspace uuid)
returns jsonb language plpgsql stable security definer set search_path=public as $$
declare is_admin boolean:=public.sun_is_platform_admin();
begin
if is_admin then perform public.sun_require_platform_admin_aal2();
elsif public.sun_member_role(p_workspace) is null then raise exception 'Access denied'; end if;
if not is_admin and public.sun_subscription_access_mode(p_workspace)='blocked' then raise exception 'Подписка закончилась'; end if;
return jsonb_build_object(
'orders',case when is_admin or (public.sun_has_permission(p_workspace,'orders.view') and public.sun_workspace_has_feature(p_workspace,'orders')) then coalesce((select jsonb_agg(jsonb_build_object('id',order_id,'version',version,'data',data,'updated_at',updated_at) order by order_id) from public.sun_v17_orders where workspace_id=p_workspace),'[]') else '[]'::jsonb end,
'catalog',case when is_admin or (public.sun_has_permission(p_workspace,'catalog.view') and public.sun_workspace_has_feature(p_workspace,'catalog_view')) then coalesce((select jsonb_agg(jsonb_build_object('id',item_id,'version',version,'data',data,'updated_at',updated_at) order by item_id) from public.sun_v17_catalog_items where workspace_id=p_workspace),'[]') else '[]'::jsonb end,
'meta',coalesce((select to_jsonb(m) from public.sun_v17_workspace_meta m where workspace_id=p_workspace),'{}'));
end $$;
-- Authenticated roles can invoke public API guards but cannot invoke snapshot internals.
grant execute on function public.sun_v17_entity_snapshot(uuid) to authenticated;
revoke all on function public.sun_v17_build_snapshot(uuid),public.sun_require_platform_admin_aal2() from public,anon,authenticated;
-- Keep owner-registration metadata in the same typed format as the sync client.
do $$declare definition text;begin
definition:=pg_get_functiondef('public.sun_create_workspace(text)'::regprocedure);
definition:=replace(definition,'''sunCompanyProfileV1'',v_profile::text','''sunCompanyProfileV1'',jsonb_build_object(''t'',''j'',''v'',v_profile)');
execute definition;
end $$;
-- Match client visibility to the same granular permission as state reads.
do $$declare definition text;begin
definition:=pg_get_functiondef('public.sun_v17_clients_snapshot_v1773(uuid)'::regprocedure);
definition:=replace(definition,'if not public.sun_workspace_has_feature(p_workspace,''clients'') then','if not public.sun_has_permission(p_workspace,''clients.view'') or public.sun_subscription_access_mode(p_workspace)=''blocked'' or not public.sun_workspace_has_feature(p_workspace,''clients'') then');
execute definition;
end $$;