Role based authentication in Supabase - supabase

I am trying to make policy in supabase where a user with admin role can only get list of employees whose role are "agent"
There is a "users" table and I am trying to add following policy
"(auth.email() in (select users.email from users where users.role = 'admin')) and (role = 'agent')
User table has following columns
firstname | lastname | role | email | password
However I am getting Infinite recursion on users table mesage.
How can I create a role based policy here?
Thanks in advance!

This is a known issue when doing a query on a table that the RLS will be set on because the policy lookup is subject to the policy too. You will need to move the query into a security definer function and call the function in the policy instead to avoid infinite recursion.
CREATE OR REPLACE FUNCTION admin_only(email string)
returns boolean AS
$$
EXISTS (select users.email from users
where users.role = 'admin'
and users.email = email)
$$ stable language sql security definer;
Then in your policy add
admin_only(auth.email())
I am a little confused by the policy you are trying to apply as you are checking if the users.role is admin but at the same time you are checking if the role is agent too, does this mean a user can be assigned multiple roles?

Related

GRANT SELECT ON view TO user using script on SQL developer, than SELECT * FROM that view in SQL Plus

My script on SQL dev:
**CREATE USER C##DG IDENTIFIED BY abc123;**
**CREATE VIEW DG1_VIEW**
AS SELECT m_pms.MaPMS, m_pms.MaDG, m_pms.SoLuong, m_s.MaSach, m_s.TenSach, m_ctpm.SL
FROM PhieuMuonSach m_pms, ChiTietPhieuMuon m_ctpm, Sach m_s
WHERE m_pms.MaDG = 1 AND m_pms.MaPMS = m_ctpm.Ma_PMS AND m_ctpm.Ma_Sach = m_s.MaSach**;**
**GRANT CREATE SESSION TO C##DG;
GRANT SELECT ON DG1_VIEW TO C##DG;**
On Sql Plus, i logged in as C##DG, typed '''SQL> SELECT * FROM DG1_VIEW;'''
and received 'ORA-00942: table or view does not exists'. But this view already had data.
What is my problem and how to fix it? I'd love to hear from you guys.
You need to either specify schema this view has been created in
select * from system.dg1_view;
or you may login as system again and create a public synonym for that view in order to make it available without specifying schema

Field Authorization level with Postgraphile

Currently, I'm working with Postgraphile and I need to enforce permissions at data/field level.
For example, I have a carmodel table, with my query is something like:
{
carmodel
{
id
name
description
}
}
Well, in this table I have ids (1 = AUDI, 2 = GM, 3 = BMW)
The current user (on roles/claims) has permission only to see (1=AUDI/3=BMW)
There is a way to enforce permissions based on field data? And return only data filtered on the user permissions?
Yes; row-level security can define this declaratively. Something like:
create policy audi_bmw on carmodel for select using (
id in (1, 3)
);
I'm guessing this permission comes from another table though; so it might be more like:
create policy audi_bmw on carmodel for select using (
id in (
select car_model_id
from user_carmodel_permissions
where user_id = current_user_id()
)
);
assuming you already have a current_user_id function, something like:
create function current_user_id() returns int as $$
select nullif(current_setting('jwt.claims.user_id', true), '')::int;
$$ language sql stable;
Check out our row level security cheatsheet.

Oracle: How to drop role, which has no owner with admin option

I have a role in oracle database. The role was created by some user (unknown), but currently no user has admin option on the role.
I know that the role exists:
SELECT * FROM DBA_ROLES WHERE ROLE = 'roleName';
The query returns the role.
No user has admin option
SELECT rp.grantee, rp.granted_role, rp.admin_option
FROM dba_role_privs rp
JOIN dba_users u
ON rp.grantee = u.username
WHERE admin_option = 'YES'
AND rp.granted_role = 'roleName'
ORDER BY grantee, granted_role;
The query returns nothing
I need drop the role.
I don't know, how this situation appeared, because for all other roles, some user with admin option exists. Could someone help me?
Thanks

Checking for specific permissions of Oracle users

Problem: I am working on a query that will produce a list of all Oracle users. I wish to determine in the query if they have the specific grant permissions for CONNECT and APPUSER and show them in a single table.
What I have tried: I am using one table, DBA_ROLE_PRIVS. This table shows all the information I need, but am failing to query it correctly. I can show all users who have permission to Connect with:
SELECT GRANTEE as "User Name", granted_role as "Connect"
FROM DBA_ROLE_PRIVS
WHERE GRANTED_ROLE='CONNECT';
I can also show users who have permission to APPUSER, simply by replacing CONNECT with APPUSER.
My problem is showing both permissions in one query. I have tried using different JOINs. However, using that seems to require two tables or more. I have researched a "self-join", but do not understand how to use two WHERE clauses. I have tried things like:
SELECT grantee as "User Name", t1.granted_role as "Connect", t2.granted_role as "APPUSER"
FROM t1.DBA_ROLE_PRIVS join t2.DBA_ROLE_PRIVS on t1.GRANTEE = t2.GRANTEE
WHERE t1.GRANTED_ROLE='CONNECT' and t2.GRANTED_ROLE='APP_USER';
I want my final query to show something like:
User Name Connect App User
---------- ---------- ----------
Bob CONNECT APPUSER
Sue APPUSER
Nick CONNECT APPUSER
Rob CONNECT
SELECT GRANTEE as "User Name", granted_role from DBA_ROLE_PRIVS where GRANTED_ROLE in ('CONNECT','APPUSER');
if you need one row for each user and two column for each access, you can use this
select c.GRANTEE as "User Name", a.granted_role as "Connect", c.granted_role as "APPUSER"
FROM
(SELECT GRANTEE, granted_role from DBA_ROLE_PRIVS where GRANTED_ROLE = 'CONNECT') a,
FULL OUTER JOIN
(SELECT GRANTEE, granted_role from DBA_ROLE_PRIVS where GRANTED_ROLE = 'APPUSER') c
on a.GRANTEE = c.GRANTEE;

Oracle update query ignore primary constraint

I have a table AreaUser like below.
area user
------------
area2 user1
area2 user2
area3 user1
(area,user) is a pk
I execute a query like below
update areatable
set user = 'user2'
where user = 'user1'
Primary key constraint error thrown for the first row update and the third row is not updated. How do i ignore the first row error and keep going with the updating the third row
or
how can i find if the (area,user) combination is already there in table just before updating that row.
Hope i stated the question clearly with this example. Thanks in advance for the help.
You need a NOT EXISTS, E.g.
Update AreaTable
Set User = 'user2'
Where User = 'user1'
And Not Exists (Select 1
From AreaTable CheckAreaTable
Where CheckAreaTable.Area = AreaTable.Area
And CheckAreaTable.User = 'user2')

Resources