Skip to content

Commit

Permalink
fix: break dependency cycle
Browse files Browse the repository at this point in the history
This commit moves several tests from the @auth v2 package to the
relational v2 package to break a dependency cycle.
  • Loading branch information
cjihrig-aws committed Oct 15, 2021
1 parent c372871 commit 3113acc
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 127 deletions.
1 change: 0 additions & 1 deletion packages/amplify-graphql-auth-transformer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
},
"devDependencies": {
"@aws-amplify/graphql-index-transformer": "0.4.0",
"@aws-amplify/graphql-relational-transformer": "0.3.1",
"@aws-amplify/graphql-searchable-transformer": "0.6.3",
"@types/fs-extra": "^8.0.1",
"@aws-cdk/assert": "~1.124.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AuthTransformer } from '@aws-amplify/graphql-auth-transformer';
import { ModelTransformer } from '@aws-amplify/graphql-model-transformer';
import { HasManyTransformer } from '@aws-amplify/graphql-relational-transformer';
import { GraphQLTransform } from '@aws-amplify/graphql-transformer-core';
import { ResourceConstants } from 'graphql-transformer-common';
import { AppSyncAuthConfiguration } from '@aws-amplify/graphql-transformer-interfaces';
Expand Down Expand Up @@ -28,7 +27,6 @@ test('subscriptions are only generated if the respective mutation operation exis
authConfig,
transformers: [
new ModelTransformer(),
new HasManyTransformer(),
new AuthTransformer({
authConfig,
addAwsIamAuthInOutputSchema: false,
Expand All @@ -48,43 +46,6 @@ test('subscriptions are only generated if the respective mutation operation exis
expect(out.pipelineFunctions['Mutation.deleteSalary.res.vtl']).toContain('$util.qr($ctx.result.put("__operation", "Mutation"))');
});

test('per-field auth on relational field', () => {
const validSchema = `
type Post @model @auth(rules: [ { allow: groups, groups: ["admin"] }, { allow: groups, groups: ["viewer"], operations: [read] } ]){
id: ID!
title: String!
comments: [Comment] @hasMany @auth(rules: [ { allow: groups, groups: ["admin"] } ])
}
type Comment @model {
id: ID!
content: String
}`;
const authConfig: AppSyncAuthConfiguration = {
defaultAuthentication: {
authenticationType: 'AMAZON_COGNITO_USER_POOLS',
},
additionalAuthenticationProviders: [{ authenticationType: 'AWS_IAM' }],
};
const transformer = new GraphQLTransform({
authConfig,
transformers: [
new ModelTransformer(),
new HasManyTransformer(),
new AuthTransformer({
authConfig,
addAwsIamAuthInOutputSchema: false,
}),
],
});
const out = transformer.transform(validSchema);
expect(out).toBeDefined();

expect(out.pipelineFunctions['Post.comments.auth.1.req.vtl']).toContain(
'#set( $staticGroupRoles = [{"claim":"cognito:groups","entity":"admin"}] )',
);
});

test('per-field @auth without @model', () => {
const validSchema = `
type Query {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { AuthTransformer } from '@aws-amplify/graphql-auth-transformer';
import { ModelTransformer } from '@aws-amplify/graphql-model-transformer';
import { IndexTransformer } from '@aws-amplify/graphql-index-transformer';
import { HasManyTransformer, HasOneTransformer, BelongsToTransformer } from '@aws-amplify/graphql-relational-transformer';
import { GraphQLTransform } from '@aws-amplify/graphql-transformer-core';
import { AppSyncAuthConfiguration, AppSyncAuthConfigurationOIDCEntry, AppSyncAuthMode } from '@aws-amplify/graphql-transformer-interfaces';
import { DocumentNode, ObjectTypeDefinitionNode, Kind, FieldDefinitionNode, parse, InputValueDefinitionNode } from 'graphql';
Expand Down Expand Up @@ -170,10 +168,6 @@ const getTransformer = (authConfig: AppSyncAuthConfiguration) =>
authConfig,
transformers: [
new ModelTransformer(),
new IndexTransformer(),
new HasManyTransformer(),
new HasOneTransformer(),
new BelongsToTransformer(),
new AuthTransformer({
authConfig,
addAwsIamAuthInOutputSchema: false,
Expand Down Expand Up @@ -604,80 +598,4 @@ describe('schema generation directive tests', () => {
expect(expectedDireciveNameCount).toEqual(addressType.directives.length);
}
});

test(`ModelXConnection type is getting the directives added, when a field has @hasMany but one fo the types has no queries defined`, () => {
const validSchema = `
type User @model
@auth(rules: [
{ allow: private, provider: iam, operations: [read] }
{ allow: groups, groups: ["group"], operations: [read, update, delete] },
]) {
id: ID!
posts: [Post!] @hasMany(indexName: "byUser", fields: ["id"])
}
type Post @model(queries: null)
@auth(rules: [
{ allow: private, provider: iam, operations: [read] },
{ allow: groups, groups: ["group"], operations: [read, update, delete] }
]) {
id: ID!
postUserId: ID! @index(name: "byUser")
message: String
}`;
const transformer = getTransformer(withAuthModes(iamDefaultConfig, ['AMAZON_COGNITO_USER_POOLS']));
const out = transformer.transform(validSchema);
const schemaDoc = parse(out.schema);
const queryType = getObjectType(schemaDoc, 'Query');
const mutationType = getObjectType(schemaDoc, 'Mutation');

expectTwo(getField(queryType, 'getUser'), ['aws_iam', 'aws_cognito_user_pools']);
expectTwo(getField(queryType, 'listUsers'), ['aws_iam', 'aws_cognito_user_pools']);

expectNone(getField(mutationType, 'createUser'));
expectOne(getField(mutationType, 'updateUser'), 'aws_cognito_user_pools');
expectOne(getField(mutationType, 'deleteUser'), 'aws_cognito_user_pools');

const userType = getObjectType(schemaDoc, 'User');
expectTwo(userType, ['aws_iam', 'aws_cognito_user_pools']);
expectNone(getField(userType, 'posts'));

const modelPostConnectionType = getObjectType(schemaDoc, 'ModelPostConnection');
expect(modelPostConnectionType).toBeDefined();
expectTwo(modelPostConnectionType, ['aws_iam', 'aws_cognito_user_pools']);
});

test(`ModelXConnection type is getting the directives added, when a field has @connection but one of the types has no queries defined. Many to Many`, () => {
const schema = `
type Post @model @auth(rules: [{ allow: owner }]) {
id: ID!
title: String!
editors: [PostEditor] @hasMany(indexName: "byPost", fields: ["id"])
}
# Create a join model and disable queries as you don't need them
# and can query through Post.editors and User.posts
type PostEditor
@model(queries: null)
@auth(rules: [{ allow: owner }]) {
id: ID!
postID: ID! @index(name: "byPost", sortKeyFields: ["editorID"])
editorID: ID! @index(name: "byEditor", sortKeyFields: ["postID"])
post: Post! @belongsTo(fields: ["postID"])
editor: User! @belongsTo(fields: ["editorID"])
}
type User @model @auth(rules: [{ allow: owner }]) {
id: ID!
username: String!
posts: [PostEditor] @hasMany(indexName: "byEditor", fields: ["id"])
}`;

const transformer = getTransformer(withAuthModes(apiKeyDefaultConfig, ['AMAZON_COGNITO_USER_POOLS']));
const out = transformer.transform(schema);
const schemaDoc = parse(out.schema);

const modelPostEditorConnectionType = getObjectType(schemaDoc, 'ModelPostEditorConnection');
expect(modelPostEditorConnectionType).toBeDefined();
// since we have resolver level auth to deny providers the default is added here to ensure the access is granted if the default type is not applied on the parent
// therefore we just need to make sure that the access is at least granted on the schema level
expect(modelPostEditorConnectionType.directives.some(dir => dir.name.value === 'aws_cognito_user_pools')).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`join table inherits auth from both tables 1`] = `
"## [Start] Authorization Steps. **
$util.qr($ctx.stash.put(\\"hasAuth\\", true))
#set( $isAuthorized = false )
#set( $primaryFieldMap = {} )
#if( $util.authType() == \\"API Key Authorization\\" )
#set( $isAuthorized = true )
#end
Expand All @@ -14,7 +15,7 @@ $util.qr($ctx.stash.put(\\"hasAuth\\", true))
#end
#end
#end
#if( !$isAuthorized && $util.isNullOrEmpty($ctx.stash.get(\\"authFilter\\")) )
#if( !$isAuthorized && $util.isNull($ctx.stash.authFilter) && $primaryFieldMap.isEmpty() )
$util.unauthorized()
#end
$util.toJson({\\"version\\":\\"2018-05-29\\",\\"payload\\":{}})
Expand Down Expand Up @@ -50,6 +51,7 @@ exports[`join table inherits auth from both tables 4`] = `
"## [Start] Authorization Steps. **
$util.qr($ctx.stash.put(\\"hasAuth\\", true))
#set( $isAuthorized = false )
#set( $primaryFieldMap = {} )
#if( $util.authType() == \\"API Key Authorization\\" )
#set( $isAuthorized = true )
#end
Expand All @@ -60,7 +62,7 @@ $util.qr($ctx.stash.put(\\"hasAuth\\", true))
#end
#end
#end
#if( !$isAuthorized && $util.isNullOrEmpty($ctx.stash.get(\\"authFilter\\")) )
#if( !$isAuthorized && $util.isNull($ctx.stash.authFilter) && $primaryFieldMap.isEmpty() )
$util.unauthorized()
#end
$util.toJson({\\"version\\":\\"2018-05-29\\",\\"payload\\":{}})
Expand Down Expand Up @@ -147,7 +149,9 @@ $util.qr($ctx.stash.put(\\"hasAuth\\", true))
#set( $isAuthorized = true )
#end
#if( $util.authType() == \\"IAM Authorization\\" )
#if( $ctx.identity.userArn == $ctx.stash.unauthRole )
#set( $isAuthorized = true )
#end
#end
#if( !$isAuthorized )
$util.unauthorized()
Expand Down Expand Up @@ -269,14 +273,16 @@ $util.qr($ctx.stash.put(\\"hasAuth\\", true))
#set( $isAuthorized = true )
#end
#if( $util.authType() == \\"IAM Authorization\\" )
#if( $ctx.identity.userArn == $ctx.stash.unauthRole )
#set( $isAuthorized = true )
#end
#end
#if( !$isAuthorized && $allowedFields.isEmpty() && $nullAllowedFields.isEmpty() )
$util.unauthorized()
#end
#if( !$isAuthorized )
#foreach( $entry in $util.map.copyAndRetainAllKeys($ctx.args.input, $inputFields).entrySet() )
#if( $util.isNull($entry.value) && !$nullAllowedFields.contains($entry.value) )
#if( $util.isNull($entry.value) && !$nullAllowedFields.contains($entry.key) )
$util.qr($deniedFields.put($entry.key, \\"\\"))
#end
#end
Expand Down
Loading

0 comments on commit 3113acc

Please sign in to comment.