* Which Category is your question related to? *
API, GraphQL and @auth directive
* What AWS Services are you utilizing? *
API, Storage, Auth, Hosting
* Provide additional details e.g. code snippets *
I am not sure if this is a bug or If I am doing something wrong, I am probably doing something wrong, so I decided to open this as a question.
This is my current GraphQL Schema:
type Chat
@model
@auth(
rules: [
{ allow: groups, groups: ["admins"] }
{ allow: groups, groups: ["users"], operations: [read] }
]
) {
id: ID!
name: String!
messages: [Message]
@connection(name: "ChatMessages", sortField: "createdAt", limit: 100)
createdAt: AWSDateTime!
}
type Message
@model
@auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["users"], operations: [read] }
]
) {
id: ID!
text: String
image: String
owner: String
chat: Chat @connection(name: "ChatMessages")
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
}
Pretty simple. The issue I am having is that the generated subscription for Messages, onCreateMessage isn't firing for messages that aren't created by the logged in user, even though the user is part of the group users specified in the @auth rules.
I feel like I am doing something wrong, but I can't say. The subscription fires for the current logged user, so it's not something on the client.
Appreciate any kind of help. I can make my repo public if necessary, just let me know.
Hello @marlonmarcello
Those in the users groups are only allowed to read meaning they are only able to execute get and list operations.
To allow them to subscribe they would need to be tied into the create operation.
...
@auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["users"], operations: [read create] } # to allow oncreate subscriptions
]
) {
...
If you are looking at only allowing that group to be allowed to subscribe to OnCreateMessage you can add the following change into the schema and change in VTL Template.
type Subscription {
onCreateMessage(owner: String): Message @aws_subscribe(mutations: ["createMessage"]) @aws_cognito_user_pools
}
Taking the resolver Subscription.onCreateMessge.res.vtl
from the build
folder and adding it into the resolver folder outside will override it. The addition here is a cognito user group check.
## [Start] Determine request authentication mode **
#if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) )
#set( $authMode = "userPools" )
#end
## [End] Determine request authentication mode **
## [Start] Check authMode and execute owner/group checks **
#if( $authMode == "userPools" )
## [Start] Static Group Authorization Checks **
#set($isStaticGroupAuthorized = $util.defaultIfNull(
$isStaticGroupAuthorized, false))
## Authorization rule: { allow: groups, groups: ["users"], groupClaim: "cognito:groups" } **
#set( $userGroups = $util.defaultIfNull($ctx.identity.claims.get("cognito:groups"), []) )
#set( $allowedGroups = ["users"] )
#foreach( $userGroup in $userGroups )
#if( $allowedGroups.contains($userGroup) )
#set( $isStaticGroupAuthorized = true )
#break
#end
#end
## [End] Static Group Authorization Checks **
## [Start] Owner Authorization Checks **
## the rest of the vtl template ....
This should allow you to let those in the users group see the subscription and not be able to do a mutation.
As a takeaway what we can implement is a listen enum in the operations list. For example what might be best fit here is something like this
@auth(
rules: [
{ allow: owner }
# allows those in user group to do query operations and subscription operations
{ allow: groups, groups: ["users"], operations: [read listen] }
]
)
Hi @SwaySway, it would be perfect to add "listen"!
I have a situation as below:
schema:
{ allow: owner, operations: [create, read, update] }
{ allow: groups, groups: ["Admin"] }
Scenario 1: When the owner does onUpdate (on its owned data) subscription fires and updates the data. The owner sees the update immediately, but Admins doesn't get the update.
Scenario 2: When Admin makes an update, the owner gets the update, but Admin still doesn't, even though should be subscribed per my understanding.
API.graphql(
graphqlOperation(onUpdateUser, **{
owner: props.user.username
}**)
).subscribe({
next: userData => {
As per documentation below, understood that the group should get the updates on records, which member of the group OWNS. Could we have an option that the group can receive ALL changes that other owners perform? Similar to { level: public }, but available only to a dedicated group, for example Admins?
If you don鈥檛 pass the user in, but are a member of an allowed group, the subscription will notify you of records added.
If you don鈥檛 pass the user in, but are NOT a member of an allowed group, the subscription will fail to connect.
If you pass the user in who IS the owner but is NOT a member of a group, the subscription will notify you of records added of which you are the owner.
If you pass the user in who is NOT the owner and is NOT a member of a group, the subscription will not notify you of anything as there are no records for which you own
A listen
enum would be beautiful.
How complex do you categorize this update @SwaySway ?
Agreed, a listen
enum would resolve a lot of issues I am having developing one of my projects.
Most helpful comment
Hello @marlonmarcello
Those in the users groups are only allowed to read meaning they are only able to execute get and list operations.
To allow them to subscribe they would need to be tied into the create operation.
If you are looking at only allowing that group to be allowed to subscribe to OnCreateMessage you can add the following change into the schema and change in VTL Template.
Taking the resolver
Subscription.onCreateMessge.res.vtl
from thebuild
folder and adding it into the resolver folder outside will override it. The addition here is a cognito user group check.This should allow you to let those in the users group see the subscription and not be able to do a mutation.
As a takeaway what we can implement is a listen enum in the operations list. For example what might be best fit here is something like this