edelacruz
07/20/2022, 7:34 AMcreate or replace function test_function()
RETURNS text
LANGUAGE plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid()
return user_role;
end
$$;
When I call this function from within my js app it returns null
const {data, error} = await supabase.rpc('test_function')
When I replace auth.uid() with the id of an existing user it still returns null in my code
but when I run select * from test_function()
in Supabase Studio's SQL Editor I do get the role I assigned to my user
Why is there a difference between calling a function from code and calling it from the SQL Editor?
And why is auth.uid() not working?
To be clear; there is an authenticated user in the code that I'm calling from.Scott P
07/20/2022, 1:17 PMsecurity invoker
instead of security definer
.
If you're creating the function via the SQL editor in the dashboard, security definer
means it will be running as the dashboard user (e.g. supabase_admin
I think), whereas security invoker
will run it as the user which calls the function.Waldemar
07/20/2022, 6:22 PMauth.uid()
is changed to just uid()
.
Maybe it is somehow related.jaitaiwan
07/21/2022, 6:10 AMselect raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid()
return user_role;
in the sql editor (replacing auth.uid() with the uid that your user has?jaitaiwan
07/21/2022, 6:10 AMWaldemar
07/21/2022, 8:57 AMjaitaiwan
07/21/2022, 10:09 AMjaitaiwan
07/21/2022, 10:10 AMedelacruz
07/21/2022, 10:48 AMcreate or replace function test_function()
RETURNS text
LANGUAGE plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = 'f32fc3d5-b9a5-4b62-a5d1-d4e59ed6e6ea';
return user_role;
end
$$;
I will see the correct role in both the SQL Editor when running select * from test_function()
But when I change to security invoker
I will still get a correct answer in the SQL editor but null in my Javacript.edelacruz
07/21/2022, 10:49 AMjaitaiwan
07/21/2022, 10:53 AMedelacruz
07/21/2022, 10:55 AMjaitaiwan
07/21/2022, 10:55 AMedelacruz
07/21/2022, 10:56 AMjaitaiwan
07/21/2022, 10:56 AMjaitaiwan
07/21/2022, 10:58 AMedelacruz
07/21/2022, 10:58 AMjaitaiwan
07/21/2022, 10:59 AMedelacruz
07/21/2022, 10:59 AMedelacruz
07/21/2022, 10:59 AMjaitaiwan
07/21/2022, 10:59 AMedelacruz
07/21/2022, 11:00 AMedelacruz
07/21/2022, 11:00 AMjaitaiwan
07/21/2022, 11:00 AMedelacruz
07/21/2022, 11:01 AMcreate or replace function test_function()
RETURNS text
LANGUAGE plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid()
return user_role;
end
$$;
jaitaiwan
07/21/2022, 11:02 AMedelacruz
07/21/2022, 11:02 AMedelacruz
07/21/2022, 11:03 AMjaitaiwan
07/21/2022, 11:04 AMedelacruz
07/21/2022, 11:04 AMedelacruz
07/21/2022, 11:04 AMedelacruz
07/21/2022, 11:05 AMjaitaiwan
07/21/2022, 11:05 AMjaitaiwan
07/21/2022, 11:05 AMjaitaiwan
07/21/2022, 11:05 AMedelacruz
07/21/2022, 11:06 AMjaitaiwan
07/21/2022, 11:06 AMedelacruz
07/21/2022, 11:08 AMedelacruz
07/21/2022, 11:08 AMjaitaiwan
07/21/2022, 11:09 AMjaitaiwan
07/21/2022, 11:09 AMjaitaiwan
07/21/2022, 11:10 AMedelacruz
07/21/2022, 11:13 AMedelacruz
07/21/2022, 11:14 AMedelacruz
07/21/2022, 11:15 AMcreate or replace function users_by_tenant_id(tenant_id_input text) RETURNS TABLE (
user_id uuid,
user_email varchar,
user_name text,
user_role text,
user_alias text,
user_tenant_id text
) LANGUAGE plpgsql security definer
set search_path = auth as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users into user_role
where id = auth.uid();
if user_role != 'admin' then raise notice 'Not allowed';
else return query
select u.id,
u.email,
u.raw_user_meta_data->>'name' as name,
u.raw_user_meta_data->>'role' as role,
u.raw_user_meta_data->>'alias' as alias,
u.raw_user_meta_data->>'tenant_id' as tenant_id
from auth.users u
where u.raw_user_meta_data->>'tenant_id' = $1;
end if;
end $$;
edelacruz
07/21/2022, 11:16 AMjaitaiwan
07/21/2022, 1:44 PMjaitaiwan
07/21/2022, 1:44 PMjaitaiwan
07/21/2022, 1:48 PMselect proname,prosrc from pg_proc where proname= 'uid';
Do you get:
select
coalesce(
nullif(current_setting('request.jwt.claim.sub', true), ''),
(nullif(current_setting('request.jwt.claims', true), '')::jsonb ->> 'sub')
)::uuid
?garyaustin
07/21/2022, 2:11 PMgaryaustin
07/21/2022, 2:29 PMdeclare myid uuid;
begin
select id from auth.users where id = auth.uid() into myid;
return myid;
end
And works fine, returning the user's id to the client.Waldemar
07/22/2022, 6:48 AMedelacruz
07/22/2022, 8:01 AM-- A function to return all users from the auth.users table
-- but only if the requestor has an admin role in raw_user_meta_data.role
create or replace function get_all_users()
returns table (
user_email varchar,
user_name text,
user_role text
)
language plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid();
if user_role <> 'admin' then
return;
else
return query
select
email,
raw_user_meta_data->>'name',
raw_user_meta_data->>'role'
from auth.users;
end if;
end $$;
edelacruz
07/22/2022, 8:06 AMjaitaiwan
07/22/2022, 8:49 AMedelacruz
07/22/2022, 8:53 AM