Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const groupsAttributeName = `groupsAttribute${ruleNumber}`
const groupName = `group${ruleNumber}`
groupAuthorizationExpressions = groupAuthorizationExpressions.concat(
comment(`Authorization rule${fieldMention}: { allow: ${rule.allow}, groupsField: "${groupsAttribute}" }`),
// Add the new auth expression and values
forEach(ref('userGroup'), ref('userGroups'), [
raw(`$util.qr($groupAuthExpressions.add("contains(#${groupsAttributeName}, :${groupName}$foreach.count)"))`),
raw(`$util.qr($groupAuthExpressionValues.put(":${groupName}$foreach.count", { "S": $userGroup }))`),
]),
iff(raw('$userGroups.size() > 0'), raw(`$util.qr($groupAuthExpressionNames.put("#${groupsAttributeName}", "${groupsAttribute}"))`)),
)
ruleNumber++
}
return block('Dynamic group authorization checks', [
this.setUserGroups(),
set(ref('groupAuthExpressions'), list([])),
set(ref('groupAuthExpressionValues'), obj({})),
set(ref('groupAuthExpressionNames'), obj({})),
...groupAuthorizationExpressions,
])
}
expressionNames: obj({
'#id': str('id'),
}),
})
)
)
),
iff(
ref(ResourceConstants.SNIPPETS.VersionedCondition),
compoundExpression([
// tslint:disable-next-line
qref(
`$condition.put("expression", "($condition.expression) AND $${ResourceConstants.SNIPPETS.VersionedCondition}.expression")`
),
qref(`$condition.expressionNames.putAll($${ResourceConstants.SNIPPETS.VersionedCondition}.expressionNames)`),
set(ref('expressionValues'), raw('$util.defaultIfNull($condition.expressionValues, {})')),
qref(`$expressionValues.putAll($${ResourceConstants.SNIPPETS.VersionedCondition}.expressionValues)`),
set(ref('condition.expressionValues'), ref('expressionValues')),
])
),
iff(
ref('context.args.condition'),
compoundExpression([
set(
ref('conditionFilterExpressions'),
raw('$util.parseJson($util.transform.toDynamoDBConditionExpression($context.args.condition))')
),
// tslint:disable-next-line
qref(`$condition.put("expression", "($condition.expression) AND $conditionFilterExpressions.expression")`),
qref(`$condition.expressionNames.putAll($conditionFilterExpressions.expressionNames)`),
set(ref('conditionExpressionValues'), raw('$util.defaultIfNull($condition.expressionValues, {})')),
qref(`$conditionExpressionValues.putAll($conditionFilterExpressions.expressionValues)`),
iff(
and([
raw(`$util.isNull($${allowedOwnersVariable})`),
parens(raw(`! $${variableToCheck}.containsKey("${ownerAttribute}")`)),
]),
compoundExpression([
qref(`$${variableToCheck}.put("${ownerAttribute}", ["$identityValue"])`),
set(ref(variableToSet), raw('true'))
])
)
)
}
ruleNumber++
}
return compoundExpression([
set(ref(variableToSet), raw(`false`)),
...ownershipAuthorizationExpressions,
]);
}
function makeQueryRelationResolver(
type: string,
field: string,
relatedType: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode,
connectionAttributes: string[],
keySchema: KeySchema[],
indexName: string
) {
const defaultPageLimit = 10
const setup: Expression[] = [
set(ref('limit'), ref(`util.defaultIfNull($context.args.limit, ${defaultPageLimit})`)),
set(ref('query'), makeExpression(keySchema, connectionAttributes))
];
if (keySchema[1] && !connectionAttributes[1]) {
let sortKeyType = relatedType.fields.find(f => f.name.value === keySchema[1].AttributeName).type;
let sortKeyAttType = attributeTypeFromScalar(sortKeyType);
setup.push(applyKeyConditionExpression(keySchema[1].AttributeName, sortKeyAttType, 'query'));
}
var queryArguments : { query, filter, scanIndexForward, limit, nextToken, index? } = {
query: raw('$util.toJson($query)'),
scanIndexForward: ifElse(
ref('context.args.sortDirection'),
ifElse(
equals(ref('context.args.sortDirection'), str('ASC')),
bool(true),
bool(false)
selectSql = `SELECT * FROM ${type} WHERE ${this.typePrimaryKeyMap.get(type)}=\'$ctx.args.update${toUpper(
type
)}Input.${this.typePrimaryKeyMap.get(type)}\'`;
} else {
selectSql = `SELECT * FROM ${type} WHERE ${this.typePrimaryKeyMap.get(type)}=$ctx.args.update${toUpper(
type
)}Input.${this.typePrimaryKeyMap.get(type)}`;
}
const reqFileName = `${mutationTypeName}.${fieldName}.req.vtl`;
const resFileName = `${mutationTypeName}.${fieldName}.res.vtl`;
const reqTemplate = print(
compoundExpression([
set(ref('updateList'), obj({})),
forEach(ref('entry'), ref(`ctx.args.update${toUpper(type)}Input.keySet()`), [
set(ref('discard'), ref(`updateList.put($entry, "'$ctx.args.update${toUpper(type)}Input[$entry]'")`)),
]),
set(ref('update'), ref(`updateList.toString().replace("{","").replace("}","")`)),
RelationalDBMappingTemplate.rdsQuery({
statements: list([str(updateSql), str(selectSql)]),
}),
])
);
const resTemplate = print(ref('utils.toJson($utils.parseJson($utils.rds.toJsonString($ctx.result))[1][0])'));
fs.writeFileSync(`${this.resolverFilePath}/${reqFileName}`, reqTemplate, 'utf8');
fs.writeFileSync(`${this.resolverFilePath}/${resFileName}`, resTemplate, 'utf8');
let resolver = new AppSync.Resolver({
ApiId: Fn.Ref(ResourceConstants.PARAMETERS.AppSyncApiId),
DataSourceName: Fn.GetAtt(ResourceConstants.RESOURCES.RelationalDatabaseDataSource, 'Name'),
query: raw('$util.toJson($query)'),
scanIndexForward: ifElse(
ref('context.args.sortDirection'),
ifElse(
equals(ref('context.args.sortDirection'), str('ASC')),
bool(true),
bool(false)
),
bool(true)
),
filter: ifElse(
ref('context.args.filter'),
ref('util.transform.toDynamoDBFilterExpression($ctx.args.filter)'),
nul()
),
limit: ref('limit'),
nextToken: ifElse(
ref('context.args.nextToken'),
str('$context.args.nextToken'),
nul()
)
}
if (indexName) {
let indexArg = "index";
queryArguments[indexArg] = str(indexName);
}
return new Resolver({
ApiId: Fn.GetAtt(ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
DataSourceName: ModelResourceIDs.ModelTableResourceID(relatedType.name.value),
FieldName: field,
TypeName: type,
FieldName: field,
TypeName: type,
RequestMappingTemplate: this.replaceEnv(
print(
compoundExpression([
nonNullArgs.length > 0 ? this.makeNonNullChecks(nonNullArgs) : null,
set(ref('headers'), ref('utils.http.copyHeaders($ctx.request.headers)')),
qref('$headers.put("Content-Type", "application/json")'),
qref('$headers.put("accept-encoding", "application/json")'),
...parsedHeaders,
HttpMappingTemplate.putRequest({
resourcePath: path,
params: obj({
body: ref('util.toJson($ctx.args.body)'),
query: ref('util.toJson($ctx.args.query)'),
headers: ref('util.toJson($headers)'),
}),
}),
])
)
),
ResponseMappingTemplate: print(
ifElse(
raw('$ctx.result.statusCode == 200 || $ctx.result.statusCode == 201'),
ifElse(
ref('ctx.result.headers.get("Content-Type").toLowerCase().contains("xml")'),
ref('utils.xml.toJsonString($ctx.result.body)'),
ref('ctx.result.body')
),
ref('util.qr($util.appendError($ctx.result.body, $ctx.result.statusCode))')
)
),
)}Input.${this.typePrimaryKeyMap.get(type)}\'`;
} else {
selectSql = `SELECT * FROM ${type} WHERE ${this.typePrimaryKeyMap.get(type)}=$ctx.args.update${toUpper(
type
)}Input.${this.typePrimaryKeyMap.get(type)}`;
}
const reqFileName = `${mutationTypeName}.${fieldName}.req.vtl`;
const resFileName = `${mutationTypeName}.${fieldName}.res.vtl`;
const reqTemplate = print(
compoundExpression([
set(ref('updateList'), obj({})),
forEach(ref('entry'), ref(`ctx.args.update${toUpper(type)}Input.keySet()`), [
set(ref('discard'), ref(`updateList.put($entry, "'$ctx.args.update${toUpper(type)}Input[$entry]'")`)),
]),
set(ref('update'), ref(`updateList.toString().replace("{","").replace("}","")`)),
RelationalDBMappingTemplate.rdsQuery({
statements: list([str(updateSql), str(selectSql)]),
}),
])
);
const resTemplate = print(ref('utils.toJson($utils.parseJson($utils.rds.toJsonString($ctx.result))[1][0])'));
fs.writeFileSync(`${this.resolverFilePath}/${reqFileName}`, reqTemplate, 'utf8');
fs.writeFileSync(`${this.resolverFilePath}/${resFileName}`, resTemplate, 'utf8');
let resolver = new AppSync.Resolver({
ApiId: Fn.Ref(ResourceConstants.PARAMETERS.AppSyncApiId),
DataSourceName: Fn.GetAtt(ResourceConstants.RESOURCES.RelationalDatabaseDataSource, 'Name'),
TypeName: mutationTypeName,
FieldName: fieldName,