Search code examples
graphqlaws-appsyncaws-amplify

AWS Amplify GraphQL filter by dynamic Cognito User Group


Given the following AWS Amplify GraphQL Schema (schema.graphql):

type Organization
  @model
  @auth(rules: [
    { allow: groups, groups: ["Full-Access-Admin"], mutations: [create, update, delete], queries: [list, get] },
    { allow: owner },
    { allow: groups, groupsField: "orgAdminsCognitoGroup", mutations: null, queries: [list, get] }
  ]) {
    id: ID!
    name: String!
    address: String!
    industry: [String]!
    owner: String
    orgAdminsCognitoGroup: String
  }

I can filter out all organizations except the ones that belong to the current authenticated user via the following:

        res = await API.graphql(graphqlOperation(listOrganizations, {
            // todo: filter by owner OR by is org admin
            filter: {
                owner: {
                    eq: this.props.currentUser.username
                }
            }
        }));

but is there anyway to also filter by the orgAdminsCognitGroup which is a dynamic group in Cognito belonging to the organization? I have not found any success trying to use an additional @model to help with the @auth rules to protect each entity.


Solution

  • So, the question is wanting to filter groups that the user is either the owner of, or in the 'orgAdminsCognitoGroup'?

    I think it's possible, though I don't think the best way is what you had in mind. Instead, I might recommend you set up a response mapping template that does some server side filtering for you.

    Specifically, you would first get the groups from the current user's auth token:

    #set($claimPermissions = $ctx.identity.claims.get("cognito:groups"))
    

    Then you could iterate over every organization in the results. If any have an owner that is the current user, add them to a response list. If they aren't, continue to check the orgAdminsCognitoGroup. You'd do that by checking whether or not $claimPermissions contains the group that the orgAdmin is set to for that organization. If it is contained, add it to the response list. If not, ignore it and continue iterating.

    It would be possible, theoretically, to do this client side with the token the user has signed in with. Much in the same way the response mapping template did it, the groups the user is in are inside the token. If you crack it open and pull out the groups, you could apply the filtering there. I would recommend not doing this for security reasons, though it is possible.