Hey! I'm new to Supabase and I'm using for a side ...
# sql
m
Hey! I'm new to Supabase and I'm using for a side project. That project let users review their day (like a journal). So I have a reviews table and RLS policies were easy to implement (users can only read/write their own reviews). But now I'd like users to be able to become a member of a group. Once in a group, everybody can view each other's reviews. The problem I have is to write the RLS policy so that group members can only view each other's reviews. I followed this example https://supabase.io/docs/guides/auth#policies-with-joins, but when I tried my policy, a user could access all reviews (even from other group). Could somebody share a minimal demo of that RLS policy, in the same fashion as in that doc example?
s
I'm confused about what is not working, can you show what you have along with your table schemas?
m
here's my reviews table:
my members table
and my groups table
for the reviews table, I wasn't sure if I needed to include a foreign key relation (group_id) to the groups table.
s
And your RLS policy?
Also what does
user_id
in the reviews table represent? is that the user who created the review or the user who can view that review?
m
the user who created the review
here's my SELECT policy for the review table:
( uid() IN ( SELECT members.user_id FROM members WHERE (members.group_id = members.id) ) )
s
A suggestion would be to rename
user_id
in the reviews table to
created_by
to not confuse you later on
m
ah yes, good idea. done.
s
That's not the full policy
Its missing the
create policy
part
Which table is this policy being created on?
m
does this help?
s
Yeah that helps
m
I think my policy is missing something because there's no reference to the reviews table
s
Try this
Copy code
sql
(
  auth.uid() IN (
    SELECT user_id
    FROM members
    WHERE reviews.group_id = members.group_id
  )
)
m
okay, I'll try it
s
So in mine the
group_id
should be from the
reviews
table or maybe we need to make it explicit because you have a
group_id
on the members table too
Actually that isn't correct
Updated it with explicit table names in the where clause
m
it's working! 😃
thanks!
s
Ok I'll send my PayPal over to you now
😆
m
💰
s
Happy to hear its working, just post on here if you have anymore questions
m
ah btw: if I want to validate the rating for the review (a number between 1 and 10), I also need to use RLS for this?
s
You could use a function with a trigger
m
okay, I'll look into it
s
It's probably best to use a function with a trigger
m
you mean a custom function? there's no built-in functions for this?
s
Yeah a custom function
I really need to start writing about these things
So many ideas, not enough time
m
I think that Supabase docs are already great and I like the YouTube videos, especially the newest one about RLS policies 😄
s
Yeah @User did an awesome job on that, he will be producing more content like that in the future too.
w
@User to use policies with joins is a good starting point for me too, but our use cases are more complex than @User 's example above. Yes, we have tables like user profiles (easy, just add a column
user_id
), but also more complex. For example
suppliers
table: - John must view all records, but only be able to create/update records where
suppliers.country
is "Italy" - Anna must be able to view/create/update/delete all
suppliers
- ... And we have a few such tables. So you can imagine it will be a nightmare to maintain a many-to-many table like
user_suppliers
for each individual user / supplier combo and different level of permissions. We need a proper RBAC basically. I guess it is more of a question of how I design all these roles/permissions tables. I hope the
auth.uid
will be enough and I can somehow join my way through to the user's role privileges without needing to create hundreds of policies or maintain thousands of many-to-many tables just for RBAC. Btw, I've been developing ERP projects for 10 years and the RBAC system there was insane. Sometimes I was setting up roles for months. I mean not design the RBAC system itself, but actually setting up what you call "policies" here. Anyways, I will try to make it work just with
auth.uid()
. If you guys are interested, I can share how I've done it / what I struggled with and maybe there is something you could add to Supabase to make it easier to design a bit more sophisticated RBAC compared to the simple user/team, user/review cases.
I'm not sure I'd want to, but I understand I can't use Postgres' roles/users to do something like this:
Copy code
CREATE POLICY supplier_managers_it ON supplier TO managers_italy
...
because for that I'd need one Postgres user per my app user and assign him to Postgres role
managers_italy
in this example, but it's always the`postgres` user my users will log in as, isn't it? The actual user is stored in JWT
s
yeah
Copy code
create or replace function auth.uid() returns uuid as $$
  select nullif(current_setting('request.jwt.claim.sub', true), '')::uuid;
$$ language sql stable;