Background:
This is similar to the model definition from the amplify documentation on the @auth directive:
type Draft @model
@auth(rules: [
# Defaults to use the "owner" field.
{ allow: owner },
# Authorize the update mutation and both queries.
{ allow: owner, ownerField: "editors", operations: [update, read] }
]) {
id: ID!
title: String!
content: String
owner: String
editors: [String]
}
Instead, I’d like to do authorization based on a @connected model’s field, similar to the following:
type Draft @model
@auth(rules: [
{ allow: owner },
{ allow: owner, ownerField: "editors.id", operations: [update, read] }
]) {
id: ID!
title: String!
content: String
owner: String
editors: [editor] @connection
}
type editor @model {
id: ID!
}
Solution:
It seems a workaround by adding a join model (it is called DraftLink in my lab) to encode the relationship between Draft and editor.
Step 1: Create the schema and provision it. Please see details below.
type Draft @model
{
id: ID!
title: String!
content: String
owner: String
editors: [DraftLink] @connection(name: "DraftLink_Draft")
}
type editor @model {
id: ID!
drafts: [DraftLink] @connection(name: "DraftLink_editor")
}
type DraftLink @model
@auth(rules: [
{ allow: owner, ownerField: "draftLinkEditorId", operations: [update, read] }
])
{
id: ID!
editor: editor! @connection(name: "DraftLink_editor")
draft: Draft! @connection(name: "DraftLink_Draft")
}
Please note the ownerField “draftLinkEditorId” in DraftLink is generated automatically by Amplify.

Step 2: Add test data including 2 drafts, 3 editors/users and the many-to-many relationship between them (user1->draft1; user2->draft1&draft2; user3->draft2)
# create 2 drafts
mutation createDraft {
createDraft(input: {
id: "draft-1"
title: "Draft 1"
}) {
id
title
}
}
mutation createDraft {
createDraft(input: {
id: "draft-2"
title: "Draft 2"
}) {
id
title
}
}
# create 3 editors/users
mutation createEditor {
createEditor(input: {
id: "user1"
}) {
id
}
}
mutation createEditor {
createEditor(input: {
id: "user2"
}) {
id
}
}
mutation createEditor {
createEditor(input: {
id: "user3"
}) {
id
}
}
# add relationship [user1->draft1; user2->draft1&draft2; user3->draft2]
mutation createDraftLink {
createDraftLink(input: {
draftLinkEditorId: "user1",
draftLinkDraftId: "draft-1"
}) {
id
}
}
mutation createDraftLink {
createDraftLink(input: {
draftLinkEditorId: "user2",
draftLinkDraftId: "draft-1"
}) {
id
}
}
mutation createDraftLink {
createDraftLink(input: {
draftLinkEditorId: "user2",
draftLinkDraftId: "draft-2"
}) {
id
}
}
mutation createDraftLink {
createDraftLink(input: {
draftLinkEditorId: "user3",
draftLinkDraftId: "draft-2"
}) {
id
}
}
Step 3: Retrieve data with different users. The query results depend on the query user. For example:
# user1: return draft-1


# user2: return draft-1 and draft-2


# update Auth to user3: return draft-2

query list {
listDraftLinks {
items {
id
editor {
id
}
draft {
id
title
}
}
}
}
I also would like to share this post https://github.com/aws-amplify/amplify-cli/issues/630 for further reference.
No Comments