Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Owner auth API provisioned with CLI 4.22.1 without read operation do not require owner input on subscription API #699

Closed
lawmicha opened this issue Aug 5, 2020 · 3 comments
Labels
bug Something isn't working GraphQL API Related to the API (GraphQL) category/plugins pending-release Code has been merged but pending release

Comments

@lawmicha
Copy link
Contributor

lawmicha commented Aug 5, 2020

Describe the bug
When I provision an API with the following schema for DataStore by following these steps

  • schema is
type SocialNote
    @model
    @auth(rules: [
        { allow: owner, ownerField: "owner", operations: [create, update, delete] },
    ]) {
    id: ID!
    content: String!
    owner: String
}
  • The schema has owner auth with operations: [create, update, delete]. I have not restricted read permissions so all users can read each others data. The resulting subscription operations no longer require owner field as input.
  • amplify update api and choose enabled for DataStore

The provisioned API have subscription operations that do not require owner field
image

This code is no longer correct as it will add the owner field on the subscription request and fail to create subscriptions to the API.

Previous logic that is incorrect:

  • if "create" operation, require owner field onCreate subscription
  • if "update" operation, require owner field onUpdate subscription
  • if "delete" operation, require owner field onDelete subscription

Now:

  • if "read" operation, require owner field on all subscriptions. (This logic needs to be confirmed)

Expected behavior
DataStore sync to cloud should construct the correct requests to API based on my schema. when i have a schema containing owner auth and certain operations set then it should know which subscription operations requires owner field and which do not.

Additional context
Amplify CLI related change released in 4.22.1 aws-amplify/amplify-cli#4182
iOS Issue: aws-amplify/amplify-swift#691
Android Issue: #699
JS issue: https://github.com/aws-amplify/amplify-js/issues/6507

@richardmcclellan
Copy link
Contributor

Possibly resolved by: #779

@richardmcclellan
Copy link
Contributor

I've done some testing with the schema.graphql below. This schema contains 15 models, with each of the various combinations of operations protected with owner auth. The actual model names map directly to the protected operations, so that we can easily match up the generated operations, from AppSync. For example, the CreRea model protects the create and read operations.

type Cre @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create] } ]) { id: ID! title: String! }
type Rea @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [read] } ]) { id: ID! title: String! }
type Upd @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [update] } ]) { id: ID! title: String! }
type Del @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [delete] } ]) { id: ID! title: String! }
type CreRea @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create, read] } ]) { id: ID! title: String! }
type CreUpd @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create, update] } ]) { id: ID! title: String! }
type CreDel @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create, delete] } ]) { id: ID! title: String! }
type ReaUpd @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [read, update] } ]) { id: ID! title: String! }
type ReaDel @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [read, delete] } ]) { id: ID! title: String! }
type UpdDel @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [update, delete] } ]) { id: ID! title: String! }
type CreUpdDel @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create, update, delete] } ]) { id: ID! title: String! }
type CreUpdRea @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create, update, read] } ]) { id: ID! title: String! }
type CreDelRea @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create, delete, read] } ]) { id: ID! title: String! }
type UpdDelRea @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [update, delete, read] } ]) { id: ID! title: String! }
type CreUpdDelRea @model @auth(rules: [ { allow: owner, ownerField: "theOwner", operations: [create, update, delete, read] } ]) { id: ID! title: String! }

This generates the following subscription operations within AppSync:

type Subscription {
  onCreateCre: Cre @aws_subscribe(mutations : ["createCre"])
  onCreateCreDel: CreDel @aws_subscribe(mutations : ["createCreDel"])
  onCreateCreDelRea(theOwner: String!): CreDelRea @aws_subscribe(mutations : ["createCreDelRea"])
  onCreateCreRea(theOwner: String!): CreRea @aws_subscribe(mutations : ["createCreRea"])
  onCreateCreUpd: CreUpd @aws_subscribe(mutations : ["createCreUpd"])
  onCreateCreUpdDel: CreUpdDel @aws_subscribe(mutations : ["createCreUpdDel"])
  onCreateCreUpdDelRea(theOwner: String!): CreUpdDelRea @aws_subscribe(mutations : ["createCreUpdDelRea"])
  onCreateCreUpdRea(theOwner: String!): CreUpdRea @aws_subscribe(mutations : ["createCreUpdRea"])
  onCreateDel: Del @aws_subscribe(mutations : ["createDel"])
  onCreateRea(theOwner: String!): Rea @aws_subscribe(mutations : ["createRea"])
  onCreateReaDel(theOwner: String!): ReaDel @aws_subscribe(mutations : ["createReaDel"])
  onCreateReaUpd(theOwner: String!): ReaUpd @aws_subscribe(mutations : ["createReaUpd"])
  onCreateTodo: Todo @aws_subscribe(mutations : ["createTodo"])
  onCreateUpd: Upd @aws_subscribe(mutations : ["createUpd"])
  onCreateUpdDel: UpdDel @aws_subscribe(mutations : ["createUpdDel"])
  onCreateUpdDelRea(theOwner: String!): UpdDelRea @aws_subscribe(mutations : ["createUpdDelRea"])
  onDeleteCre: Cre @aws_subscribe(mutations : ["deleteCre"])
  onDeleteCreDel: CreDel @aws_subscribe(mutations : ["deleteCreDel"])
  onDeleteCreDelRea(theOwner: String!): CreDelRea @aws_subscribe(mutations : ["deleteCreDelRea"])
  onDeleteCreRea(theOwner: String!): CreRea @aws_subscribe(mutations : ["deleteCreRea"])
  onDeleteCreUpd: CreUpd @aws_subscribe(mutations : ["deleteCreUpd"])
  onDeleteCreUpdDel: CreUpdDel @aws_subscribe(mutations : ["deleteCreUpdDel"])
  onDeleteCreUpdDelRea(theOwner: String!): CreUpdDelRea @aws_subscribe(mutations : ["deleteCreUpdDelRea"])
  onDeleteCreUpdRea(theOwner: String!): CreUpdRea @aws_subscribe(mutations : ["deleteCreUpdRea"])
  onDeleteDel: Del @aws_subscribe(mutations : ["deleteDel"])
  onDeleteRea(theOwner: String!): Rea @aws_subscribe(mutations : ["deleteRea"])
  onDeleteReaDel(theOwner: String!): ReaDel @aws_subscribe(mutations : ["deleteReaDel"])
  onDeleteReaUpd(theOwner: String!): ReaUpd @aws_subscribe(mutations : ["deleteReaUpd"])
  onDeleteTodo: Todo @aws_subscribe(mutations : ["deleteTodo"])
  onDeleteUpd: Upd @aws_subscribe(mutations : ["deleteUpd"])
  onDeleteUpdDel: UpdDel @aws_subscribe(mutations : ["deleteUpdDel"])
  onDeleteUpdDelRea(theOwner: String!): UpdDelRea @aws_subscribe(mutations : ["deleteUpdDelRea"])
  onUpdateCre: Cre @aws_subscribe(mutations : ["updateCre"])
  onUpdateCreDel: CreDel @aws_subscribe(mutations : ["updateCreDel"])
  onUpdateCreDelRea(theOwner: String!): CreDelRea @aws_subscribe(mutations : ["updateCreDelRea"])
  onUpdateCreRea(theOwner: String!): CreRea @aws_subscribe(mutations : ["updateCreRea"])
  onUpdateCreUpd: CreUpd @aws_subscribe(mutations : ["updateCreUpd"])
  onUpdateCreUpdDel: CreUpdDel @aws_subscribe(mutations : ["updateCreUpdDel"])
  onUpdateCreUpdDelRea(theOwner: String!): CreUpdDelRea @aws_subscribe(mutations : ["updateCreUpdDelRea"])
  onUpdateCreUpdRea(theOwner: String!): CreUpdRea @aws_subscribe(mutations : ["updateCreUpdRea"])
  onUpdateDel: Del @aws_subscribe(mutations : ["updateDel"])
  onUpdateRea(theOwner: String!): Rea @aws_subscribe(mutations : ["updateRea"])
  onUpdateReaDel(theOwner: String!): ReaDel @aws_subscribe(mutations : ["updateReaDel"])
  onUpdateReaUpd(theOwner: String!): ReaUpd @aws_subscribe(mutations : ["updateReaUpd"])
  onUpdateTodo: Todo @aws_subscribe(mutations : ["updateTodo"])
  onUpdateUpd: Upd @aws_subscribe(mutations : ["updateUpd"])
  onUpdateUpdDel: UpdDel @aws_subscribe(mutations : ["updateUpdDel"])
  onUpdateUpdDelRea(theOwner: String!): UpdDelRea @aws_subscribe(mutations : ["updateUpdDelRea"])
}

As we can see, the theOwner field is only needed for the models where the read operation is protected (that is, the model name itself contains Rea. This validates that we should proceed with the behavior change suggested by this issue.

@jamesonwilliams
Copy link
Contributor

#807 went out in 1.3.2. Please give this latest version a try, and let us know if the issue persists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working GraphQL API Related to the API (GraphQL) category/plugins pending-release Code has been merged but pending release
Projects
None yet
Development

No branches or pull requests

4 participants