Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Group field as part of secondary index correct generation of auth rules using @hasMany directive linking parent to child where GSI is also auth groupField 1`] = `
"## [Start] Authorization Steps. **
$util.qr($ctx.stash.put(\\"hasAuth\\", true))
#set( $isAuthorized = false )
#if( $util.authType() == \\"User Pool Authorization\\" )
#if( !$isAuthorized )
#set( $primaryRole0 = $util.defaultIfNull($ctx.identity.claims.get(\\"cognito:groups\\"), null) )
#if( !$util.isNull($primaryRole0) )

#set( $ownerClaimsList0 = [] )
#if( $util.isString($primaryRole0) )
#if( $util.isList($util.parseJson($primaryRole0)) )
#set( $ownerClaimsList0 = $util.parseJson($primaryRole0) )
#else
#set( $ownerClaimsList0 = [$primaryRole0] )
#end
#else
#set( $ownerClaimsList0 = $primaryRole0 )
#end
#if( (!$util.isNull($ctx.source.id)) && (($ctx.source.id == $primaryRole0) || $ownerClaimsList0.contains($ctx.source.id)) )
#set( $isAuthorized = true )
$util.qr($ctx.stash.put(\\"authFilter\\", null))
#else
#if( !$isAuthorized && $util.isNull($ctx.stash.authFilter) )
$util.qr($ctx.stash.connectionAttributes.put(\\"id\\", $primaryRole0))
#set( $isAuthorized = true )
#end
#end
#end
#end
#end
#if( !$isAuthorized && $util.isNull($ctx.stash.authFilter) )
$util.unauthorized()
#end
$util.toJson({\\"version\\":\\"2018-05-29\\",\\"payload\\":{}})
## [End] Authorization Steps. **"
`;

exports[`Group field as part of secondary index group field as GSI field 1`] = `
"## [Start] Authorization Steps. **
$util.qr($ctx.stash.put(\\"hasAuth\\", true))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { IndexTransformer, PrimaryKeyTransformer } from '@aws-amplify/graphql-in
import { testTransform } from '@aws-amplify/graphql-transformer-test-utils';
import { ResourceConstants } from 'graphql-transformer-common';
import { AppSyncAuthConfiguration } from '@aws-amplify/graphql-transformer-interfaces';
import { HasManyTransformer } from '@aws-amplify/graphql-relational-transformer';
import { AuthTransformer } from '../graphql-auth-transformer';

test('happy case with static groups', () => {
Expand Down Expand Up @@ -448,4 +449,50 @@ describe('Group field as part of secondary index', () => {
expect(out).toBeDefined();
expect(out.resolvers['Query.notesByGroup.auth.1.req.vtl']).toMatchSnapshot();
});
/**
* This test case validates that linking between models using the @hasMany directive while the parent
* model's primary key is used as the groupsField value in the child model's @auth directive works
* correctly. This fixes a previous issue where the authorisation logic was not parsing the cognito:groups
* claim correctly, resulting in the database query failing, followed by an incorrect response to AppSync,
* throwing an error because the result did not match the schema.
*/
test('correct generation of auth rules using @hasMany directive linking parent to child where GSI is also auth groupField', () => {
const authConfig: AppSyncAuthConfiguration = {
defaultAuthentication: {
authenticationType: 'AMAZON_COGNITO_USER_POOLS',
},
additionalAuthenticationProviders: [],
};
const validSchema = `
type Tenant @model
@auth(rules: [{allow: groups, groupsField: "id"}])
{
id: ID!
name: String!
notes: [Note] @hasMany(indexName: "byTenantId", fields: ["id"])
}

type Note @model
@auth(rules: [{allow: groups, groupsField: "tenantId"}])
{
id: ID!
tenantId: ID! @index(name: "byTenantId")
noteType: String!
}
`;
const out = testTransform({
schema: validSchema,
authConfig,
transformers: [
new ModelTransformer(),
new AuthTransformer(),
new PrimaryKeyTransformer(),
new IndexTransformer(),
new HasManyTransformer(),
],
});

expect(out).toBeDefined();
expect(out.resolvers['Tenant.notes.auth.1.req.vtl']).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ const generateAuthOnRelationalModelQueryExpression = (
compoundExpression([
generateOwnerMultiClaimExpression(role.claim!, `primaryRole${idx}`),
generateOwnerClaimListExpression(role.claim!, `ownerClaimsList${idx}`),
ifElse(
methodCall(ref('util.isString'), ref(`primaryRole${idx}`)),
ifElse(
methodCall(ref('util.isList'), methodCall(ref('util.parseJson'), ref(`primaryRole${idx}`))),
set(ref(`ownerClaimsList${idx}`), methodCall(ref('util.parseJson'), ref(`primaryRole${idx}`))),
set(ref(`ownerClaimsList${idx}`), list([ref(`primaryRole${idx}`)])),
),
set(ref(`ownerClaimsList${idx}`), ref(`primaryRole${idx}`)),
),
ifElse(
and([
parens(not(ref(`util.isNull($ctx.${claim}.${field})`))),
Expand Down