I have a permission structure so that a specific permission only allows to edit 2 out of 5 fields in my table. I have RLS in my entire system so I need to execute the above inside the policy.
At first I thought of writing a function that checks if the user updated fields they don't have permissions updating, and using it's return value inside the policy. But I couldn't find a way to use the return value inside the policy without having to define a variable, which obviously you can't inside a policy.
Here's the said function:
CREATE OR REPLACE FUNCTION is_user_updating_non_permitted_fields(id uuid, fieldA integer, fieldB text...)
.....
DECLARE
old_row MY_TABLE
BEGIN
SELECT * FROM MY_TABLE m WHERE id = m.id INTO old_row;
IF (fieldA != old_row.fieldA OR fieldB != old_row.fieldB)
THEN RETURN 1;
ELSE RETURN 0;
ENDIF;
END;
....
And the policy will be something like:
CREATE POLICY my_table_update ON MY_TABLE FOR UPDATE
WITH CHECK (
(SELECT CASE WHEN (
''use function here''
) = 1 THEN false ELSE true END;
)
)
As a last resort, I thought of doing a trigger before update and using ROLLBACK TRANSACTION
but I really don't wanna go that way.
restricted_field_*
that cannot beNULL
. If they wereNULL
before, and theUPDATE
does not change it, your function still prevents theUPDATE
due toNULL = NULL
beingfalse
. Solution: useIS NOT DISTINCT FROM
instead of=
. (But then also make sure the function returnstrue
only whenEXISTS(SELECT COUNT(*) FROM original_row)
, otherwise circumventing the check by changingid
becomes possible.) – Filipino