Skip to content

Commit

Permalink
Support remote relationship in permission filter (#904)
Browse files Browse the repository at this point in the history
<!-- The PR description should answer 2 (maybe 3) important questions:
-->
Closes:
https://linear.app/hasura/issue/APIPG-397/support-remote-relationship-predicates-in-permission-filters

### What

<!-- What is this PR trying to accomplish (and why, if it's not
obvious)? -->

<!-- Consider: do we need to add a changelog entry? -->
Allow defining permission filters with remote relationships in their
predicates.

### How

<!-- How is it trying to accomplish it (what are the implementation
steps)? -->
- Lift metadata resolve restriction for remote relationships in
permission predicates
- Abstract out the remote relationship resolving logic, in query filter,
into a new function and re-use it while resolving permission filters.
- Tests:
- A metadata build test to check the presence of essential equal
operator on source fields in relationship mapping.
- Ported all `select_many/relationship_predicate/`* tests to a new
`select_many/remote_relationship_predicate/*` with appropriate metadata
changes.

---------

Co-authored-by: Anon Ray <ecthiender@users.noreply.github.com>
V3_GIT_ORIGIN_REV_ID: 9c496ecdc9829ed626354ef85e776e1afcb0dfc7
2 people authored and hasura-bot committed Jul 31, 2024
1 parent 736def0 commit 7177a42
Showing 46 changed files with 10,935 additions and 245 deletions.
32 changes: 32 additions & 0 deletions v3/changelog.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,38 @@

### Added

#### Remote Relationships Predicates

We have significantly enhanced our permission capabilities to support remote
relationships in filter predicates. It is important to note that the
relationship source and target models should be from the same subgraph.

**Example:** API traces are stored in a separate database. Users should only be
able to view traces of their own API requests.

```yaml
kind: ModelPermissions
version: v1
definition:
modelName: traces
permissions:
- role: user
select:
filter:
relationship:
name: User
predicate:
fieldComparison:
field: user_id
operator: _eq
value:
sessionVariable: x-hasura-user-id
```
In the above configuration, a permission filter is defined on the `traces`
model. The filter predicate employs the `User` remote relationship, ensuring the
`user_id` field is equal to the `x-hasura-user-id` session variable.

- New `NoAuth` mode in auth config can be used to provide a static role and
session variables to use whilst running the engine, to make getting started
easier.
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
[
{
"data": {
"Album": [
{
"AlbumId": 1,
"Tracks": [
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 1,
"Title": "For Those About To Rock We Salute You"
}
]
}
]
},
{
"AlbumId": 2,
"Tracks": [
{
"TrackAlbums": [
{
"AlbumId": 2,
"Title": "Balls to the Wall"
}
]
}
]
}
],
"AlbumWithFilterAndPredicate": [
{
"AlbumId": 3,
"Tracks": [
{
"TrackAlbums": [
{
"AlbumId": 3,
"Title": "Restless and Wild"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 3,
"Title": "Restless and Wild"
}
]
},
{
"TrackAlbums": [
{
"AlbumId": 3,
"Title": "Restless and Wild"
}
]
}
]
}
]
}
},
{
"data": {
"Album": [
{
"AlbumId": 2,
"Tracks": [
{
"TrackAlbums": [
{
"AlbumId": 2,
"Title": "Balls to the Wall"
}
]
}
]
}
],
"AlbumWithFilterAndPredicate": []
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
"version": "v2",
"subgraphs": [
{
"name": "default",
"objects": [
{
"definition": {
"modelName": "Albums",
"permissions": [
{
"role": "admin",
"select": {
"filter": null
}
},
{
"role": "user",
"select": {
"filter": {
"relationship": {
"name": "Tracks",
"predicate": {
"relationship": {
"name": "TrackAlbumsRemote",
"predicate": {
"fieldComparison": {
"field": "AlbumId",
"operator": "_eq",
"value": {
"sessionVariable": "x-hasura-user-id"
}
}
}
}
}
}
}
}
}
]
},
"version": "v1",
"kind": "ModelPermissions"
},
{
"definition": {
"modelName": "Tracks",
"permissions": [
{
"role": "admin",
"select": {
"filter": null
}
},
{
"role": "user",
"select": {
"filter": null
}
}
]
},
"version": "v1",
"kind": "ModelPermissions"
},
{
"definition": {
"modelName": "Artist",
"permissions": [
{
"role": "admin",
"select": {
"filter": null
}
},
{
"role": "user",
"select": {
"filter": null
}
}
]
},
"version": "v1",
"kind": "ModelPermissions"
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
query MyQuery {
Album(limit: 2) {
AlbumId
Tracks {
TrackAlbums {
AlbumId
Title
}
}
}
AlbumWithFilterAndPredicate: Album(
limit: 2
where: { Tracks: { TrackId: { _eq: 3 } } }
) {
AlbumId
Tracks {
TrackAlbums {
AlbumId
Title
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"x-hasura-role": "admin"
},
{
"x-hasura-role": "user",
"x-hasura-user-id": "2"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[
{
"data": {
"Artist": [
{
"Name": "AC/DC"
}
]
}
},
{
"data": {
"Artist": [
{
"Name": "AC/DC"
},
{
"Name": "The Rolling Stones"
}
]
}
}
]
Loading

0 comments on commit 7177a42

Please sign in to comment.