aws-amplify / amplify-category-api

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development. This plugin provides functionality for the API category, allowing for the creation and management of GraphQL and REST based backends for your amplify project.
https://docs.amplify.aws/
Apache License 2.0
89 stars 75 forks source link

unable to run update* mutations when using multi-user data access pattern (non-standard "owner" field) #966

Open josefaidt opened 1 year ago

josefaidt commented 1 year ago

Before opening, please confirm:

How did you install the Amplify CLI?

pnpm

If applicable, what version of Node.js are you using?

18

Amplify CLI Version

10.4.0

What operating system are you using?

mac

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

n/a

Amplify Categories

api

Amplify Commands

Not applicable

Describe the bug

Unable to run update* mutations when logged into a user that has limited access and the owner field is an array of owners (as described in the documentation for multi-user data access)

This occurs when the id field is not manually included in the model, and we instead lean on @model to generate this field.

Using this schema:

type Todo
  @model(subscriptions: null)
  @auth(
    rules: [
      { allow: owner }
      { allow: owner, ownerField: "editors", operations: [read, update] }
    ]
  ) {
  name: String!
  description: String
  editors: [ID]
    @auth(
      rules: [
        { allow: owner }
        { allow: owner, ownerField: "editors", operations: [read] }
      ]
    )
}

And the following operations (you can run this in AppSync to verify)

# 1. run this as "josef"
mutation CREATE {
  createTodo(input: {
    name:"hello my first todo",
    editors:["5314d28f-8e18-4015-83cd-3b781ce790f6::user"]
  }) {
    id
    owner
    editors
  }
}

# 2. log in as "user" and run the update
mutation UPDATE {
  updateTodo(input:{
    id: "8f70078d-d1e0-4cfd-9a20-be2612af7432",
    name:"edited todo name"
  }) {
    id
    name
  }
}

we are receiving the following error:

{
  "data": {
    "updateTodo": null
  },
  "errors": [
    {
      "path": [
        "updateTodo"
      ],
      "data": null,
      "errorType": "Unauthorized",
      "errorInfo": null,
      "locations": [
        {
          "line": 15,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Unauthorized on [id]"
    }
  ]
}

Expected behavior

users that have access via non-standard "owner" field should be able to update the fields they have access to as defined in the graphql schema

Reproduction steps

  1. amplify init -y
  2. amplify add api > GraphQL > choose Cognito User Pools
  3. amplify push -y
  4. amplify console auth > create two separate users (note sub::username for second user)
  5. amplify console api > run the operations noted in the description
    1. log in as the first user "josef" and run:
      mutation CREATE {
        createTodo(input: {
          name:"hello my first todo",
          editors:["5314d28f-8e18-4015-83cd-3b781ce790f6::user"]
        }) {
          id
          owner
          editors
        }
      }
    2. log in as second user "user" and run:
      mutation UPDATE {
        updateTodo(input:{
          id: "8f70078d-d1e0-4cfd-9a20-be2612af7432",
          name:"edited todo name"
        }) {
          id
          name
        }
      }
  6. observe error

GraphQL schema(s)

```graphql # Put schemas below this line type Todo @model(subscriptions: null) @auth( rules: [ { allow: owner } { allow: owner, ownerField: "editors", operations: [read, update] } ] ) { name: String! description: String editors: [ID] @auth( rules: [ { allow: owner } { allow: owner, ownerField: "editors", operations: [read] } ] ) } ```

Log output

``` # Put your logs below this line ```

Additional information

project id 02f796c6f2e9e7c5a53d44ad88500b67

josefaidt commented 1 year ago

To mitigate, include the ID field on the model itself. From there we are able to execute updates as expected

type Todo
  @model(subscriptions: null)
  @auth(
    rules: [
      { allow: owner }
      { allow: owner, ownerField: "editors", operations: [read, update] }
    ]
  ) {
+ id: ID!
  name: String!
  description: String
  editors: [ID]
    @auth(
      rules: [
        { allow: owner }
        { allow: owner, ownerField: "editors", operations: [read] }
      ]
    )
}
image
AnilMaktala commented 1 year ago

Hey Josef, I can reproduce the issue using steps provided above.

image
sundersc commented 3 months ago

Duplicate of https://github.com/aws-amplify/amplify-category-api/issues/630.