feat: expose row-level can_edit/can_delete on select *
Compute per-row editability and deletability from a table's row-level security policies and return them as synthetic columns so clients can hide edit/delete affordances for rows the user cannot change. - Introspect pg_policies and relrowsecurity at schema-cache load and combine the UPDATE/DELETE USING qualifiers per table (permissive OR, restrictive AND). - Store the combined qualifiers on Table and inject can_edit/can_delete as computed select fields when expanding `select *`, only for RLS-enabled tables with a matching policy (COALESCE'd to a boolean). - Keep the computed columns out of the OpenAPI spec so they are not rendered as regular fields. - Add a cfExpression field to CoercibleField to carry raw SQL expressions through the planner to SqlFragment.
This commit is contained in:
@@ -268,3 +268,34 @@ $$ language sql;
|
||||
create or replace function get_work_mem() returns text as $$
|
||||
select current_setting('work_mem', true);
|
||||
$$ language sql;
|
||||
|
||||
-- RLS fixtures for testing can_edit/can_delete computed fields
|
||||
create table rls_items(
|
||||
id int primary key,
|
||||
account_id bigint,
|
||||
name text
|
||||
);
|
||||
|
||||
alter table rls_items enable row level security;
|
||||
|
||||
create policy rls_items_select on rls_items for select
|
||||
using (
|
||||
account_id is null
|
||||
or (current_setting('request.jwt.claims', true)::json ->> 'account_id')::bigint = account_id
|
||||
);
|
||||
|
||||
create policy rls_items_update on rls_items for update
|
||||
using ((current_setting('request.jwt.claims', true)::json ->> 'account_id')::bigint = account_id);
|
||||
|
||||
create policy rls_items_delete on rls_items for delete
|
||||
using ((current_setting('request.jwt.claims', true)::json ->> 'account_id')::bigint = account_id);
|
||||
|
||||
insert into rls_items(id, account_id, name) values (1, 1, 'own'), (2, null, 'public'), (3, 2, 'other');
|
||||
|
||||
-- no RLS at all: can_edit/can_delete must be omitted
|
||||
create table no_rls_items(
|
||||
id int primary key,
|
||||
name text
|
||||
);
|
||||
|
||||
insert into no_rls_items(id, name) values (1, 'a'), (2, 'b');
|
||||
|
||||
Reference in New Issue
Block a user