The object that will be changed by a mutation contains a permissions
array that contains user
objects that consist of a userId
and a write
permission boolean. If a user's userId
is present in the list, the user has read permission on the object. If write
is set to true, the user also has write permission.
This makes modifying the object easier from a mutation perspective, but it makes handling subscriptions much more difficult, since I don't have access to the object being updated at subscription creation. Thus, I am unable to ensure that user's will only get updates to the object if they have the appropriate permissions.
I don't think it makes a difference (since I can't handle this on the client-side securely), but I'm building a React web client.
Is there any feasible way around this?
One possible solution would be to setup a server-side job which subscribes to all new mutations. This server-side listener would receive every new mutation, look into the permissions list, and publish to the authorized user using a None datasource resolver. The users will only be allowed to subscribe to a subscription with their user id.
The schema would look something like this:
type Object {
permissions: [User]
//.. Other fields
}
type User {
userId: ID!
write: Boolean
}
// The server listener will populate this
type PublishPayload {
userId: ID!
objectToPublish: Object
}
type Mutation {
// The original mutation
updateObject(): Object
// The server-side listener will use this to publish. Attach a None Resolver to it.
publishToUser(userId: ID!): PublishPayload
}
type Subscription {
// This subscription is used by the server to listen to all updateObject mutations
serverSubscription(): Object
@aws_subscribe(mutations:["updateObject"])
// This subscription is used by the users.
// You would add a resolver to it that fails authorization if they try to subscribe to a different user.
userSubscription(userId: ID!): PublishPayload
@aws_subscribe(mutations:["publishToUser"])
//.. More schema
Hope this helps!