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 79 forks source link

Owners may reassign ownership #1451

Closed afern247 closed 1 year ago

afern247 commented 1 year ago

Amplify CLI Version

11.1.1

Question

I'm getting the following warning:

⚠️ WARNING: owners may reassign ownership for the following model(s) and role(s): User: [owner], UserSettings: [owner], Social: [owner], Portfolio: [owner], Wallet: [owner], ManualTransaction: [owner], Blockchain: [owner], Exchange: [owner], ExchangeTransaction: [owner], WalletAnalytics: [owner], PortfolioAnalytics: [owner], Followers: [owner]. If this is not intentional, you may want to apply field-level authorization rules to these fields. To read more: https://docs.amplify.aws/cli/graphql/authorization-rules/#per-user--owner-based-data-access.

Here are 2 of my models:

type User @model @auth(rules: [{ allow: owner }, { allow: private, operations: [read] }]) {
  id: ID!
  age: Int
  email: String
  createdAt: String
  premiumUntil: AWSDateTime
  socialMedia: Social @hasOne
  portfolios: [Portfolio] @hasMany
  userSettings: UserSettings @hasOne
}

type Social @model @auth(rules: [
  { allow: private, operations: [read] },
  { allow: owner }
]) {
  id: ID!
  profileImage: String
  displayName: String
  bio: String
  location: String
  twitter: String
  facebook: String
  instagram: String
  linkedIn: String
  followers: [Followers] @hasMany
  following: [Followers] @hasMany
}

I want to be able to share what's on Social to any auth. user, and I think that's what private read operation does no? Why am I still getting that warning? Also how can I fix the User so it doesn't display that warning, what am I missing?

josefaidt commented 1 year ago

Hey @afern247 :wave: the messaging here is referring to adding field-level auth rules to the auto-generated owner fields, in which we will want to declare manually in order to appease this warning:

image

Applying the field-level auth rule will ensure owners are able to CREATE and READ their owner field, but not UPDATE or DELETE as this will allow the owner to relinquish their ownership of that record. Sometimes this behavior is desirable, and if that is the case here then this warning is safe to ignore.

On your model this will look something like:

type User @model @auth(rules: [{ allow: owner }, { allow: private, operations: [read] }]) {
  id: ID!
  age: Int
  email: String
  createdAt: String
  owner: String! @auth(rules: [{ allow: owner, operations: [create,read] }, { allow: private, operations: [read] }])
  premiumUntil: AWSDateTime
  socialMedia: Social @hasOne
  portfolios: [Portfolio] @hasMany
  userSettings: UserSettings @hasOne
}
afern247 commented 1 year ago

So if I wanted to let the user create it once they sign up, but also update the fields such as email, portfolios etc but not allow the user to re-assign the field to another user, so the data is not transferable, how should I have it? Also does that apply to other fields? The user should be able to update them but not assign them to other users. @josefaidt

josefaidt commented 1 year ago

So if I wanted to let the user create it once they sign up, but also update the fields such as email, portfolios etc but not allow the user to re-assign the field to another user, so the data is not transferable, how should I have it?

The model-level auth rules you have are sufficient, and the field-level auth rule from the example above will just prevent the owner from reassigning the record.

Also does that apply to other fields?

With the current snippet, no, however if you were to allow UPDATE permissions for private (i.e. "logged in") users you would want to apply field-level auth rules to prohibit these updates where necessary.

afern247 commented 1 year ago

With the current snippet, no, however if you were to allow UPDATE permissions for private (i.e. "logged in") users you would want to apply field-level auth rules to prohibit these updates where necessary.

I didn't understand this part. This is the acceptance criteria of what I want:

type Social @model @auth(rules: [
  { allow: private, operations: [read] },
  { allow: owner }
]) {
  id: ID!
  profileImage: String
  displayName: String
  bio: String
  location: String
  twitter: String
  facebook: String
  instagram: String
  linkedIn: String
  followers: [Followers] @hasMany
  following: [Followers] @hasMany
}

type Followers @model @auth(rules: [{ allow: owner }, { allow: private, operations: [read] }]) {
  id: ID!
  followOnDate: String!
  user: User! @hasOne
}

@josefaidt

josefaidt commented 1 year ago

Hey @afern247 given the acceptance criteria the schema will look like:

type Social @model @auth(rules: [
  { allow: private, operations: [read] },
  { allow: owner }
]) {
  id: ID!
  profileImage: String
  displayName: String
  bio: String
  location: String
  # add an owner field manually here
  owner: String! @auth(rules: [{ allow: owner, operations: [create,read] }, { allow: private, operations: [read] }])
  twitter: String
  facebook: String
  instagram: String
  linkedIn: String
  followers: [Followers] @hasMany
  following: [Followers] @hasMany
}

type Followers @model @auth(rules: [{ allow: owner }, { allow: private, operations: [read] }]) {
  id: ID!
  followOnDate: String!
  user: User! @hasOne
  # add an owner field manually here
  owner: String! @auth(rules: [{ allow: owner, operations: [create,read] }, { allow: private, operations: [read] }])
}

This will allow the owner to perform any action on the models fields with the exception of updating or deleting the value for owner

afern247 commented 1 year ago

Ohh interesting! Thanks jose!