0

Here is a description of my tables

event {
    id 
    organization__id
}

user {
    id
}

organization {
    id
} 

organization_user {
    user__id
    organization__id
}

How can I restrict a user in order to allow him to insert/update event with only organization__id he belongs (through table organization_user)?

spatialaustin
  • 582
  • 4
  • 21
Nicolas Bourdin
  • 323
  • 1
  • 3
  • 7

2 Answers2

1

You definitely do not need to add any token session variable values other than an X-Hasura-User-Id which I assume you have already implemented.

Using Hasura correctly is all about making the proper relationships between your different tables.

It is important to remember, Hasura can use both object and array relationships for row level permissions lookups.

I am going to assume that the following relationships exist (if they do not, you can create them easily).

event => organization
organization => orgUsers (organization_user array relation)
organization_user => user

Event then has a direct lookup path to user.id and you can check that it equals the X-Hasura-User-Id. Although this is an _eq check, remember: the orgUsers array lookup in that path makes sure that if any orgUser.user.id matches, they will have row level access.

Comment if you need clarification of any of these points.

Abraham Labkovsky
  • 1,771
  • 6
  • 12
  • I see how this works for select and update, but does it also work for inserts? as far as I know you can only use headers in your checks, not data from the payload (entity to insert). Or am I missing something? – Notalifeform Jan 21 '23 at 16:13
  • Insert row level permissions work the same. You wouldn't be referencing the payload, rather the data is is trying to insert. If it fails the check, the record will not save. (Even though the payload only carries an org_id, you can still validate looking up through that relationship.) – Abraham Labkovsky Jan 23 '23 at 15:12
  • with 'payload' I mean the data I am trying to insert - I am not ware of a way to refer it in a permission rule. Maybe you can update your answer with an example how to do that? – Notalifeform Jan 24 '23 at 16:47
  • You can read my previous comment again as I address this very question. There is no need to reference any data in the payload. The payload is simply data to be inserted into the DB. If OP wants to ensure that a user cannot submit an event to an org they don't belong to, they would perform the same check in the permissions. Since an event contains a (required) ord_id, and the relationship is configured in Hasura, a user will be prevented from inserting the event if they are not part of the org. It is that simple. There is nothing to update in my answer. – Abraham Labkovsky Jan 24 '23 at 17:29
0

It's hard to say without knowing you permissions and authentication scheme, but you can accomplish this by using session variables in your row-permissions settings (docs).

First, you'll need your users to have a value in their session token that maps to the organization__id column in your database. For example, suppose your session tokens have a property called X-Hasura-Organization-Id.

Next, disable insert and update permissions on the organization__id column in the event table.

For insert permissions, configure a column preset which sets the organization__id value based on the user's session token value for X-Hasura-Organization-Id.

And, finally, to prevent users from updating records outside of their organization, you can configure a row-level permission rule which checks that the X-Hasura-Organization-Id in the user's session token matches the organization__id of the row they wish to update.

spatialaustin
  • 582
  • 4
  • 21
  • Thanks ! And if my user belongs to multiple organization, with different role in each? the session variables way can be complex or limited in this case no ? – Nicolas Bourdin Dec 27 '22 at 15:29
  • I've never tried, but if your session variable were an array of organization IDs, it should be possible to use the `_in` operator in your rule configuration to test if the row's organization ID is in the user session's array of organization IDs. see [here](https://hasura.io/docs/latest/queries/postgres/query-filters/#list-based-search-operators-_in-_nin) for details about that filter operator. – spatialaustin Dec 28 '22 at 01:02
  • Please see my answer below. This answer is incorrect – Abraham Labkovsky Jan 09 '23 at 15:42