How to provide access rights to different users (Part 2)

In the previous post, we have seen the first scenario to provide Resource Based Permission.

Let’s move on to the second scenario now.

Scenario 2:

User2 creates a resource and wants to link it with the resource created by User1.

In the previous post, User1 sends a text Message to User2 and User2 can read the message because the system admin has granted him the permission to query the resource.

Now, User2 replies with a text Message. So he has to connect the newly created Message object with the User1 Message object. Let’s say a Message object has a replies field. So, the reply of User2 would go under the replies field of the previously created User1 Message object.

type Message {
  text: String
  replies: [Message!]
}

Here are the steps to create access right.

  1. System admin creates an Access Right for User2 to insert data into the Message object created by User1.

Again, User1 cannot provide necessary access rights. Only System admin can do that. System Admin needs to set resource owner id while creating the Access Right. The Resource Owner is the one who created the resource.

mutation {
  upsert(
    values: {
      AccessRight: [
        {
          resource: "01G29XT20KV82KACE8T6HE3DHN"
          resourceType: "Message"
          operationType: "Mutation"
          operation: "*"
          resourceOwnerId: "01G1TH09DPVGFPP8W5ZYC1AC81"
          permissionType: RBP
          approved: true
          members: { hypi: { id: "01G1TH9D0PY4GG7RJDMDTXAG5F" } }
        }
      ]
    }
  ) {
    id
  }
}
  1. User2 replies to the text from the Message object.
mutation {
  upsert(
    values: {
      Message: [
        {
          hypi: { id: "01G29XT20KV82KACE8T6HE3DHN" }
          replies: { text: "How are you?" }
        }
      ]
    }
  ) {
    id
  }
}

  1. User1 executes the query to read the reply.
{
  find(type: Message, arcql: "*") {
    edges {
      node {
        ... on Message {
          text
          replies {
            text
          }
        }
      }
      cursor
    }
  }
}

#result
{
  "data": {
    "find": {
      "edges": [
        {
          "node": {
            "text": "Hi!",
            "replies": [
              {
                "text": "How are you?"
              }
            ]
          },
          "cursor": "01G29XT20KV82KACE8T6HE3DHN"
        }
      ]
    }
  }
}

Please note that User1 has access to the Message object created by him and he can read the reply by executing a query through the parent object. He can’t read the child object directly as it is an independent resource created by User2.

In other words, our permission system grants read access to an object, if the object is accessed via a parent which the user has access to.

Check below find query by User2. He has access to the reply resource created by him. The same object is missing in the previous query by User1.

{
  find(type: Message, arcql: "*") {
    edges {
      node {
        ... on Message {
          text
          replies {
            text
          }
        }
      }
      cursor
    }
  }
}
#result
{
  "data": {
    "find": {
      "edges": [
        {
          "node": {
            "text": "Hi!",
            "replies": [
              {
                "text": "How are you?"
              }
            ]
          },
          "cursor": "01G29XT20KV82KACE8T6HE3DHN"
        },
        {
          "node": {
            "text": "How are you?",
            "replies": null
          },
          "cursor": "01G2CMTNFXXH2CKZZEHQ1E2FDZ"
        }
      ]
    }
  }
}