You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
actual behavior: Use PATCH call fails without Prefer header (permission denied) to update table even when UPDATA right is granted. When Prefer header is added, PATCH call returns 404 while the table is updated.
Expected behavior :
404 should not be returned if the table is updated.
Without Prefer header, the PATCH call will return permission denied response. (Not sure this is expected behavior or not.)
How to reproduce
run the following SQL script in the postgres database to set up the basic schema and roles.
NOTE: There are table drop & role drop in the script. check before you run
-- setup databasedropschema if exists test_issue_api cascade;
drop role if exists anno_user;
create role anno_user;
createschematest_issue_api;
grant usage on schema test_issue_api to anno_user;
createtableif not exists test_issue_api.users (
id serialnot null,
email character varying(4096) unique not null,
password character varying(1024) not null
);
altertabletest_issue_api.users enable row level security;
create policy anno_user_can_insert ontest_issue_api.usersas permissive for insert to anno_user with check(true);
create policy anno_user_can_update ontest_issue_api.usersas permissive
for update
to anno_user
using (true)
with check(true);
create policy anno_user_can_select ontest_issue_api.usersas permissive
for select
to anno_user
using (true);
revoke all on table test_issue_api.usersfrom public;
grantselect(id, email) on table test_issue_api.users to anno_user;
grantupdate(email) on table test_issue_api.users to anno_user;
grant insert on table test_issue_api.users to anno_user;
grant usage on sequence test_issue_api.users_id_seq to anno_user;
-- insert dataset role anno_user;
select id, email fromtest_issue_api.users;
-- should be successful but return nothinginsert intotest_issue_api.users (email, "password") values('test@123.com','password');
-- should be successfulselect id, email fromtest_issue_api.users;
-- should be successful and return 1 row with id=1 && email=test@123.comupdatetest_issue_api.usersset email='ab234.com'where id =1;
select id, email fromtest_issue_api.users;
-- should be successful and return 1 row with id=1 && email=ab234.comselect*fromtest_issue_api.userswhere id=1;
-- should return permission deneied
use the postgrest configure file as below.
change the connection string as you need. save as a conf file and run postgrest xxx.conf in terminal.
use the following postman script to test the restful api.
Run GET, POST request first. It works fine.
The PATCH users.email [successful] request is the one working without using Prefer:return=minimal header.
The PATCH users.email [BUGGY] request is the one that has a potential bug. This request contains the Prefer header as well as query string to do filtering, but it returns 404. However, it still updates the users table successfully. So I believe this is a bug
The PATCH without Prefer[Permission denied] is the request that does not have Prefer header, which returns the permission denied. I am not sure whether this is the expected behavior. But I am wondering if postgrest can figure this out automatically.
Let's focus first on the PATCH without Prefer and select, this does seem to be a bug.
This is the query that pgrst generates in that case:
WITH
pgrst_payload AS (SELECT $1::json AS json_data),
pgrst_body AS ( SELECT CASE WHEN json_typeof(json_data) ='array' THEN json_data ELSE json_build_array(json_data) END AS val FROM pgrst_payload)
UPDATE"test"."users"SET"email"= _."email"FROM (SELECT*FROM json_populate_recordset (null:: "test"."users" , (SELECT val FROM pgrst_body))) _
WHERE"test"."users"."id"='1'::unknown
RETURNING "test"."users".*;
The RETURNING * at the last part seems to be the culprit of the error.
(I recalled this bug was fixed before, but it was related to INSERTs #417, we need to do the same for UPDATE now)
Actually with POST(INSERT) the semantics are the same, it needs Prefer: return=minimal to succeed.
Though it does result in 201 Created and PATCH returns 404(I see your point now).
Since by default POST/PATCH return nothing is strange to me why this choice was made, I think it should work without Prefer: return=minimal. I'll have to think this through, maybe it can be solved with a simple RETURNING 1.
Environment
Description of issue
actual behavior: Use PATCH call fails without
Prefer
header (permission denied) to update table even whenUPDATA
right is granted. WhenPrefer
header is added, PATCH call returns404
while the table is updated.Expected behavior :
404
should not be returned if the table is updated.Prefer
header, thePATCH
call will returnpermission denied
response. (Not sure this is expected behavior or not.)How to reproduce
NOTE: There are table drop & role drop in the script. check before you run
change the connection string as you need. save as a conf file and run
postgrest xxx.conf
in terminal.Run GET, POST request first. It works fine.
The
PATCH users.email [successful]
request is the one working without usingPrefer:return=minimal
header.The
PATCH users.email [BUGGY]
request is the one that has a potential bug. This request contains thePrefer
header as well as query string to do filtering, but it returns404
. However, it still updates the users table successfully. So I believe this is a bugThe
PATCH without Prefer[Permission denied]
is the request that does not havePrefer
header, which returns thepermission denied
. I am not sure whether this is the expected behavior. But I am wondering if postgrest can figure this out automatically.The text was updated successfully, but these errors were encountered: