question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add Permission Rules For Checking the New (or Incoming, or Next) Value of a Field

See original GitHub issue

Problem:

Currently, it is possible to add row permission rules for checking the existing value of a column field.

However, per my research, it’s not possible to add control logics into row permission rules for checking the incoming (or new, or next) value of a field. In other words, this will ultimately result in a custom check constraint that is applied BEFORE a mutation.

This could be related to “actions” feature that is still under progress. If so, when will the actions become ready to use?

To illustrate:

This is a one way relationship table. I took my time and tried to represent the exact same situation that we are going to use in production.

Let the column fields be: (Simplified)

id_Doer   |   id_Target   |   followState

followState is a String field and may have 3 values => "false", "requested", and "true".

Let UserTarget has a private profile. So any other user can only request following UserTarget or if they already requested, they can cancel request.

So here is an example situation: (Simplified)

  • The below code blocks are connected with an _or operator.

  • Let UserA = UserDoer and UserB = UserTarget .

  • This row represents the relationship of UserA over UserB.

Code Block 1: UserA is the logged in user who is trying to perform mutations on the same row.

_and: [
 id_Doer = X-Hasura-Id, (UserDoer is the logged in user. I can do this, no problem.),
 UserTarget = private,  (I can also check this since there are array & object relations. No problem)
    _or: [
      _and: [
       existing_value_of_followState = "false",  (UserDoer not yet requested)
       incoming_value_of_followState = "requested",    (UserDoer can request following)
     ],

      _and: [
       existing_value_of_followState = "requested",  (If UserDoer requested following)
       incoming_value_of_followState = "false",    (UserTarget can cancel the request)
     ], 

      _and: [
       existing_value_of_followState = "true",  (If UserDoer is following UserTarget)
       incoming_value_of_followState = "false",    (UserDoer can unfollow UserTarget)
     ],  
 ],

Code Block 2: UserB is the logged in user who is trying to perform mutations on the same row.

_and: [
 id_Target = X-Hasura-Id, (UserTarget is the logged in user. I can do this, no problem.),
 UserTarget = private,  (I can also check this since there are array & object relations. No problem)

    _or: [ 

      _and: [
      existing_value_of_followState = "requested",  (Request already made by UserDoer before)
      incoming_value_of_followState = "false",    (UserTarget can decline the request)
     ],

      _and: [
      existing_value_of_followState = "requested",  (Request already made by UserDoer before)
      incoming_value_of_followState = "true",    (UserTarget can accept the request)
     ],

      _and: [
      existing_value_of_followState = "true",  (UserDoer already following UserTarget)
      incoming_value_of_followState = "false", (UserTarget can remove UserDoer from its followers)
     ],
 ],

What does it mean :

  • So if UserTarget has a private profile, followState can be set to false or requested by UserDoer.

  • UserDoer can unfollow UserTarget.

  • However, followState can not be set to true by UserDoer (or anybody else except UserTarget)

  • If request already made by UserDoer before, UserTarget can decline the request.

  • If request already made by UserDoer before, UserTarget can accept the request.

  • If UserDoer already following UserTarget, UserTarget can remove UserDoer from its followers.

  • However, UserTarget can not change followState field to true if the existing value of followState is not requested.

But… I couldn’t find a way to apply rules on the incoming (or new, or next) value of a field.

Is it a breaking change or very hard to implement? This can save a lot of complex stuff, really.

I’m in love with Hasura and I really think this feature should be added.

PS: I my not know if there is already a solution **exactly

** for what I’m trying to do. If so, sorry for the hustle 😄

User Relationship Diagram

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:5
  • Comments:13 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
tirumaraiselvancommented, Jan 17, 2020

@paf31 @0x777 Could you pls post your thoughts here on the technical feasibility of this feature?

Also, instead of this exact interface, is there something else we can build so that the use-case of checking “before” and “after” values can be modelled by the permission system?

1reaction
0x777commented, Jan 21, 2020

Hi @yasinarik, please take a look at https://github.com/hasura/graphql-engine/pull/3750, we are planning to allow adding a check condition on the updated row (the update will fail if this condition does not meet this condition). Once we have that, your requirement can be represented as follows:

  1. The filter condition (the rows that can be updated) will be as follows:

    {
      "_or": [
        { "id_Doer": "x-hasura-id"},
        { "id_Target": "x-hasura-id"}
      ]
    }
    

    i.e, you can update only those rows where you are the ‘doer’ or the ‘target’.

  2. The allowed columns to be updated are only followState.

  3. The row which has been updated has to hold the following condition (check):

    {
      "_or": [
        {
          "id_Doer" : "x-hasura-id",
          "followState": {"_in": ["false", "requested"]}
        },
        {
          "id_Target" : "x-hasura-id",
          "followState": {"_in": ["false", "true"]}
        }
      ]
    }
    

    The above condition states that, after the update,

    1. If the user is a ‘doer’, the followState can only be set to false or requested, i.e, the ‘doer’ can only request to follow or stop following the ‘target’.
    2. If the user is a ‘target’, the followState can only be set to false or true, i.e, the ‘target’ can only approve or reject a request.

Note that once a ‘doer’ sets the followState to false, the target shouldn’t be able to set it to true, so the filter has to be tightened as follows:

{
  "_or": [
    { "id_Doer": "x-hasura-id"},
    { 
      "id_Target": "x-hasura-id", 
      "followState": { "_in": ["true", "requested"] }
    }
  ]
}

This still allows one transition which you may not want to allow: a ‘doer’ can change the followState from true to requested, but that is a transition that can anyways be achieved as follows: true to false to requested.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Configuring permission rules | Hasura GraphQL Docs
Permission rules are defined for each role, table, operation (insert, select, update, delete) by using the Console or the metadata APIs for permissions....
Read more >
Manage mail flow rules in Exchange Online - Microsoft Learn
Admins can learn how to view, create, modify, remove enable or disable, and import or export mail flow rules in Exchange Online.
Read more >
Establishing Windows File and Folder Level Permissions
To do this, you would first need to create a new folder on the W: drive. By default, the new folder will have...
Read more >
3. Adding a resource permission check - Backstage.io
We have created a new isOwner rule, which is going to be automatically used by the permission framework whenever a conditional response is...
Read more >
Handling User Permissions in JavaScript - CSS-Tricks
The key is to return the role (or permission, if you prefer that name) of the currently logged-in user when fetching some data....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found