107 lines
4.6 KiB
PL/PgSQL
107 lines
4.6 KiB
PL/PgSQL
-- Redemption-code management is an ordinary admin-console capability.
|
|
-- Keep actor verification, trusted request IDs and server-owned audit markers,
|
|
-- but do not reuse the narrower billing adjustment permission.
|
|
|
|
create or replace function public.require_admin_redemption_reason()
|
|
returns trigger
|
|
language plpgsql
|
|
set search_path = ''
|
|
as $$
|
|
declare
|
|
v_reason text := nullif(btrim(current_setting('app.admin_redemption_reason', true)), '');
|
|
begin
|
|
if new.action in ('redemption_code.create','redemption_code.update','redemption_code.revoke') then
|
|
if v_reason is null or char_length(v_reason) > 500 then
|
|
raise exception 'admin_reason_required' using errcode='22023';
|
|
end if;
|
|
new.permission_used := 'admin.access';
|
|
new.reason := v_reason;
|
|
end if;
|
|
return new;
|
|
end;
|
|
$$;
|
|
|
|
revoke all on function public.require_admin_redemption_reason()
|
|
from public, anon, authenticated, service_role;
|
|
|
|
create or replace function public.admin_create_redemption_codes(
|
|
p_actor_user_id uuid,p_actor_email text,p_actor_role text,p_request_id text,p_codes jsonb,p_reason text
|
|
)
|
|
returns table(id uuid,code_mask text,credits integer,expires_at timestamptz,note text,created_at timestamptz,
|
|
redeemed_by uuid,redeemed_email text,redeemed_at timestamptz,revoked_by uuid,revoked_at timestamptz)
|
|
language plpgsql security definer set search_path = ''
|
|
as $$
|
|
begin
|
|
if not public.admin_has_permission(p_actor_user_id,'admin.access') then
|
|
raise exception 'admin_permission_denied' using errcode='42501';
|
|
end if;
|
|
if char_length(btrim(coalesce(p_reason,''))) not between 1 and 500 then
|
|
raise exception 'admin_reason_required' using errcode='22023';
|
|
end if;
|
|
perform set_config('app.admin_redemption_reason',btrim(p_reason),true);
|
|
return query select * from public.admin_create_redemption_codes(
|
|
p_actor_user_id,p_actor_email,p_actor_role,p_request_id,p_codes
|
|
);
|
|
end;
|
|
$$;
|
|
|
|
create or replace function public.admin_update_redemption_code(
|
|
p_actor_user_id uuid,p_actor_email text,p_actor_role text,p_request_id text,p_code_id uuid,
|
|
p_set_note boolean,p_note text,p_set_expires_at boolean,p_expires_at timestamptz,p_reason text
|
|
)
|
|
returns table(id uuid,code_mask text,credits integer,expires_at timestamptz,note text,created_at timestamptz,
|
|
redeemed_by uuid,redeemed_email text,redeemed_at timestamptz,revoked_by uuid,revoked_at timestamptz)
|
|
language plpgsql security definer set search_path = ''
|
|
as $$
|
|
begin
|
|
if not public.admin_has_permission(p_actor_user_id,'admin.access') then
|
|
raise exception 'admin_permission_denied' using errcode='42501';
|
|
end if;
|
|
if char_length(btrim(coalesce(p_reason,''))) not between 1 and 500 then
|
|
raise exception 'admin_reason_required' using errcode='22023';
|
|
end if;
|
|
perform set_config('app.admin_redemption_reason',btrim(p_reason),true);
|
|
return query select * from public.admin_update_redemption_code(
|
|
p_actor_user_id,p_actor_email,p_actor_role,p_request_id,p_code_id,
|
|
p_set_note,p_note,p_set_expires_at,p_expires_at
|
|
);
|
|
end;
|
|
$$;
|
|
|
|
create or replace function public.admin_revoke_redemption_code(
|
|
p_actor_user_id uuid,p_actor_email text,p_actor_role text,p_request_id text,p_code_id uuid,p_reason text
|
|
)
|
|
returns table(id uuid,code_mask text,credits integer,expires_at timestamptz,note text,created_at timestamptz,
|
|
redeemed_by uuid,redeemed_email text,redeemed_at timestamptz,revoked_by uuid,revoked_at timestamptz)
|
|
language plpgsql security definer set search_path = ''
|
|
as $$
|
|
begin
|
|
if not public.admin_has_permission(p_actor_user_id,'admin.access') then
|
|
raise exception 'admin_permission_denied' using errcode='42501';
|
|
end if;
|
|
if char_length(btrim(coalesce(p_reason,''))) not between 1 and 500 then
|
|
raise exception 'admin_reason_required' using errcode='22023';
|
|
end if;
|
|
perform set_config('app.admin_redemption_reason',btrim(p_reason),true);
|
|
return query select * from public.admin_revoke_redemption_code(
|
|
p_actor_user_id,p_actor_email,p_actor_role,p_request_id,p_code_id
|
|
);
|
|
end;
|
|
$$;
|
|
|
|
revoke all on function public.admin_create_redemption_codes(uuid,text,text,text,jsonb,text),
|
|
public.admin_update_redemption_code(uuid,text,text,text,uuid,boolean,text,boolean,timestamptz,text),
|
|
public.admin_revoke_redemption_code(uuid,text,text,text,uuid,text)
|
|
from public, anon, authenticated, service_role;
|
|
|
|
do $$
|
|
begin
|
|
if exists(select 1 from pg_roles where rolname='admin_runtime') then
|
|
grant execute on function public.admin_create_redemption_codes(uuid,text,text,text,jsonb,text),
|
|
public.admin_update_redemption_code(uuid,text,text,text,uuid,boolean,text,boolean,timestamptz,text),
|
|
public.admin_revoke_redemption_code(uuid,text,text,text,uuid,text)
|
|
to admin_runtime;
|
|
end if;
|
|
end
|
|
$$;
|