@aws-amplify/graphql-auth-transformer
Advanced tools
Comparing version 0.1.1-beta.0 to 0.1.1-ext10.0
@@ -6,3 +6,3 @@ # Change Log | ||
## 0.1.1-beta.0 (2021-10-20) | ||
## 0.1.1-ext10.0 (2021-11-02) | ||
@@ -15,2 +15,5 @@ | ||
* add [@manytomany](https://github.com/manytomany) join table auth ([#8460](https://github.com/aws-amplify/amplify-cli/issues/8460)) ([424bbda](https://github.com/aws-amplify/amplify-cli/commit/424bbda410fbab100d475d37fa9ab291bfd05317)) | ||
* add field auth on aggregation queries ([#8508](https://github.com/aws-amplify/amplify-cli/issues/8508)) ([c0fa85a](https://github.com/aws-amplify/amplify-cli/commit/c0fa85a87230d631ffaf376f18f4fc3c4ec9a1f9)) | ||
* add schema directives for sync operation when conflict resolution is enabled ([#8521](https://github.com/aws-amplify/amplify-cli/issues/8521)) ([e3299e5](https://github.com/aws-amplify/amplify-cli/commit/e3299e5c09884218d486d4a488f343972674a417)) | ||
* auth on getting related model name and searchablevNext e2e ([#8455](https://github.com/aws-amplify/amplify-cli/issues/8455)) ([8536dd3](https://github.com/aws-amplify/amplify-cli/commit/8536dd3eb4cffc14602d80eea82b8b62b8227485)) | ||
* auth vnext validation fixes ([#8551](https://github.com/aws-amplify/amplify-cli/issues/8551)) ([2cfe6ce](https://github.com/aws-amplify/amplify-cli/commit/2cfe6ce15e9adb1e5824e3d011deb9e4d5cf5d4d)) |
declare type ACMConfig = { | ||
resources: string[]; | ||
operations: string[]; | ||
name: string; | ||
}; | ||
@@ -11,2 +12,3 @@ declare type SetRoleInput = { | ||
export declare class AccessControlMatrix { | ||
private name; | ||
private roles; | ||
@@ -13,0 +15,0 @@ private operations; |
@@ -8,4 +8,6 @@ "use strict"; | ||
const assert_1 = __importDefault(require("assert")); | ||
const graphql_transformer_core_1 = require("@aws-amplify/graphql-transformer-core"); | ||
class AccessControlMatrix { | ||
constructor(config) { | ||
this.name = config.name; | ||
this.operations = config.operations; | ||
@@ -26,3 +28,3 @@ this.resources = config.resources; | ||
} | ||
else { | ||
else if (this.roles.includes(role) && resource) { | ||
allowedVector = this.getResourceOperationMatrix({ operations, resource, role }); | ||
@@ -32,2 +34,5 @@ const roleIndex = this.roles.indexOf(role); | ||
} | ||
else { | ||
throw new graphql_transformer_core_1.InvalidDirectiveError(`@auth ${role} already exists for ${this.name}`); | ||
} | ||
} | ||
@@ -97,6 +102,6 @@ hasRole(role) { | ||
if (input.resource && !this.resources.includes(input.resource)) { | ||
throw Error(`Resource: ${input.resource} is not configued in the ACM`); | ||
throw new graphql_transformer_core_1.TransformerContractError(`Resource: ${input.resource} is not configued in the ACM`); | ||
} | ||
if (input.role && !this.roles.includes(input.role)) { | ||
throw Error(`Role: ${input.role} does not exist in ACM.`); | ||
throw new graphql_transformer_core_1.TransformerContractError(`Role: ${input.role} does not exist in ACM.`); | ||
} | ||
@@ -106,3 +111,3 @@ if (input.operations) { | ||
if (this.operations.indexOf(operation) === -1) | ||
throw Error(`Operation: ${operation} does not exist in the ACM.`); | ||
throw new graphql_transformer_core_1.TransformerContractError(`Operation: ${operation} does not exist in the ACM.`); | ||
}); | ||
@@ -109,0 +114,0 @@ } |
@@ -18,3 +18,3 @@ import { TransformerAuthBase } from '@aws-amplify/graphql-transformer-core'; | ||
private unauthPolicyResources; | ||
constructor(config: AuthTransformerConfig); | ||
constructor(config?: AuthTransformerConfig); | ||
before: (context: TransformerBeforeStepContextProvider) => void; | ||
@@ -21,0 +21,0 @@ object: (def: ObjectTypeDefinitionNode, directive: DirectiveNode, context: TransformerSchemaVisitStepContextProvider) => void; |
@@ -36,3 +36,3 @@ "use strict"; | ||
class AuthTransformer extends graphql_transformer_core_1.TransformerAuthBase { | ||
constructor(config) { | ||
constructor(config = { addAwsIamAuthInOutputSchema: false }) { | ||
super('amplify-auth-transformer', utils_1.authDirectiveDefinition); | ||
@@ -55,4 +55,5 @@ this.authPolicyResources = new Set(); | ||
utils_1.ensureAuthRuleDefaults(rules); | ||
utils_1.validateRules(rules, this.configuredAuthProviders); | ||
utils_1.validateRules(rules, this.configuredAuthProviders, def.name.value); | ||
const acm = new accesscontrol_1.AccessControlMatrix({ | ||
name: def.name.value, | ||
operations: utils_1.MODEL_OPERATIONS, | ||
@@ -87,3 +88,3 @@ resources: utils_1.collectFieldNames(def), | ||
utils_1.ensureAuthRuleDefaults(rules); | ||
utils_1.validateFieldRules(rules, isParentTypeBuiltinType, modelDirective !== undefined, this.configuredAuthProviders); | ||
utils_1.validateFieldRules(rules, isParentTypeBuiltinType, modelDirective !== undefined, this.configuredAuthProviders, field.name.value); | ||
this.setAuthPolicyFlag(rules); | ||
@@ -97,2 +98,3 @@ this.setUnauthPolicyFlag(rules); | ||
acm = new accesscontrol_1.AccessControlMatrix({ | ||
name: parent.name.value, | ||
operations: utils_1.MODEL_OPERATIONS, | ||
@@ -113,2 +115,3 @@ resources: utils_1.collectFieldNames(parent), | ||
const acm = new accesscontrol_1.AccessControlMatrix({ | ||
name: typeFieldName, | ||
operations: ['read'], | ||
@@ -122,2 +125,3 @@ resources: [typeFieldName], | ||
this.transformSchema = (context) => { | ||
const searchableAggregateServiceDirectives = new Set(); | ||
const getOwnerFields = (acm) => { | ||
@@ -132,5 +136,9 @@ return acm.getRoles().reduce((prev, role) => { | ||
const def = context.output.getObject(modelName); | ||
const modelHasSearchable = def.directives.some(dir => dir.name.value === 'searchable'); | ||
this.addFieldsToObject(context, modelName, getOwnerFields(acm)); | ||
const providers = this.getAuthProviders(acm.getRoles()); | ||
const directives = this.getServiceDirectives(providers, providers.length === 0 ? this.shouldAddDefaultServiceDirective() : false); | ||
if (modelHasSearchable) { | ||
providers.forEach(p => searchableAggregateServiceDirectives.add(p)); | ||
} | ||
if (directives.length > 0) { | ||
@@ -150,2 +158,8 @@ utils_1.extendTypeWithDirectives(context, modelName, directives); | ||
} | ||
if (searchableAggregateServiceDirectives.size > 0) { | ||
const serviceDirectives = this.getServiceDirectives(Array.from(searchableAggregateServiceDirectives), false); | ||
for (let aggType of utils_1.SEARCHABLE_AGGREGATE_TYPES) { | ||
utils_1.extendTypeWithDirectives(context, aggType, serviceDirectives); | ||
} | ||
} | ||
}; | ||
@@ -233,3 +247,3 @@ this.generateResolvers = (context) => { | ||
this.protectSchemaOperations = (ctx, def, acm) => { | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j; | ||
const modelConfig = this.modelDirectiveConfig.get(def.name.value); | ||
@@ -251,5 +265,6 @@ const indexKeyName = `${def.name.value}:indicies`; | ||
addServiceDirective(ctx.output.getQueryTypeName(), 'read', (_b = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.queries) === null || _b === void 0 ? void 0 : _b.list); | ||
addServiceDirective(ctx.output.getMutationTypeName(), 'create', (_c = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _c === void 0 ? void 0 : _c.create); | ||
addServiceDirective(ctx.output.getMutationTypeName(), 'update', (_d = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _d === void 0 ? void 0 : _d.update); | ||
addServiceDirective(ctx.output.getMutationTypeName(), 'delete', (_e = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _e === void 0 ? void 0 : _e.delete); | ||
addServiceDirective(ctx.output.getQueryTypeName(), 'read', (_c = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.queries) === null || _c === void 0 ? void 0 : _c.sync); | ||
addServiceDirective(ctx.output.getMutationTypeName(), 'create', (_d = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _d === void 0 ? void 0 : _d.create); | ||
addServiceDirective(ctx.output.getMutationTypeName(), 'update', (_e = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _e === void 0 ? void 0 : _e.update); | ||
addServiceDirective(ctx.output.getMutationTypeName(), 'delete', (_f = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _f === void 0 ? void 0 : _f.delete); | ||
if (ctx.metadata.has(indexKeyName)) { | ||
@@ -270,3 +285,3 @@ for (let index of ctx.metadata.get(indexKeyName).values()) { | ||
.filter(roleDef => { var _a; return roleDef.strategy === 'owner' && !utils_1.fieldIsList((_a = def.fields) !== null && _a !== void 0 ? _a : [], roleDef.entity); }); | ||
if (subscriptions.onCreate && ((_f = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _f === void 0 ? void 0 : _f.create)) { | ||
if (subscriptions.onCreate && ((_g = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _g === void 0 ? void 0 : _g.create)) { | ||
for (let onCreateSub of subscriptions.onCreate) { | ||
@@ -277,3 +292,3 @@ addServiceDirective(ctx.output.getSubscriptionTypeName(), 'read', onCreateSub); | ||
} | ||
if (subscriptions.onUpdate && ((_g = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _g === void 0 ? void 0 : _g.update)) { | ||
if (subscriptions.onUpdate && ((_h = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _h === void 0 ? void 0 : _h.update)) { | ||
for (let onUpdateSub of subscriptions.onUpdate) { | ||
@@ -284,3 +299,3 @@ addServiceDirective(ctx.output.getSubscriptionTypeName(), 'read', onUpdateSub); | ||
} | ||
if (subscriptions.onDelete && ((_h = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _h === void 0 ? void 0 : _h.delete)) { | ||
if (subscriptions.onDelete && ((_j = modelConfig === null || modelConfig === void 0 ? void 0 : modelConfig.mutations) === null || _j === void 0 ? void 0 : _j.delete)) { | ||
for (let onDeleteSub of subscriptions.onDelete) { | ||
@@ -363,5 +378,21 @@ addServiceDirective(ctx.output.getSubscriptionTypeName(), 'read', onDeleteSub); | ||
var _a; | ||
const acmFields = acm.getResources(); | ||
const modelFields = (_a = def.fields) !== null && _a !== void 0 ? _a : []; | ||
const allowedAggFields = modelFields.map(f => f.name.value).filter(f => !acmFields.includes(f)); | ||
let leastAllowedFields = acmFields; | ||
const resolver = ctx.resolvers.getResolver(typeName, fieldName); | ||
const roleDefinitions = acm.getRolesPerOperation('read').map(r => this.roleMap.get(r)); | ||
const authExpression = resolvers_1.generateAuthExpressionForSearchQueries(this.configuredAuthProviders, roleDefinitions, (_a = def.fields) !== null && _a !== void 0 ? _a : []); | ||
const readRoleDefinitions = acm.getRolesPerOperation('read').map(role => { | ||
const allowedFields = acmFields.filter(resource => acm.isAllowed(role, resource, 'read')); | ||
const roleDefinition = this.roleMap.get(role); | ||
if (allowedFields.length !== acmFields.length || !roleDefinition.static) { | ||
roleDefinition.allowedFields = allowedFields; | ||
leastAllowedFields = leastAllowedFields.filter(f => allowedFields.includes(f)); | ||
} | ||
else { | ||
roleDefinition.allowedFields = null; | ||
} | ||
return roleDefinition; | ||
}); | ||
allowedAggFields.push(...leastAllowedFields); | ||
const authExpression = resolvers_1.generateAuthExpressionForSearchQueries(this.configuredAuthProviders, readRoleDefinitions, modelFields, allowedAggFields); | ||
resolver.addToSlot('auth', graphql_transformer_core_1.MappingTemplate.s3MappingTemplateFromString(authExpression, `${typeName}.${fieldName}.{slotName}.{slotIndex}.req.vtl`)); | ||
@@ -368,0 +399,0 @@ }; |
@@ -29,8 +29,8 @@ "use strict"; | ||
graphql_mapping_template_1.set(graphql_mapping_template_1.ref(`groupEntity${idx}`), graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('util.defaultIfNull'), graphql_mapping_template_1.ref(`ctx.source.${role.entity}`), graphql_mapping_template_1.nul())), | ||
graphql_mapping_template_1.set(graphql_mapping_template_1.ref(`groupClaim${idx}`), helpers_1.getOwnerClaim(role.claim)), | ||
graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('userGroup'), graphql_mapping_template_1.ref('dynamicGroupClaim'), [ | ||
graphql_mapping_template_1.iff(entityIsList | ||
? graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref(`groupEntity${idx}.contains`), graphql_mapping_template_1.ref('userGroup')) | ||
: graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(`groupEntity${idx}`), graphql_mapping_template_1.ref('userGroup')), graphql_mapping_template_1.compoundExpression([graphql_mapping_template_1.set(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG), graphql_mapping_template_1.bool(true)), graphql_mapping_template_1.raw('#break')])), | ||
]), | ||
graphql_mapping_template_1.set(graphql_mapping_template_1.ref(`groupClaim${idx}`), helpers_1.getIdentityClaimExp(graphql_mapping_template_1.str(role.claim), graphql_mapping_template_1.list([]))), | ||
entityIsList | ||
? graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('userGroup'), graphql_mapping_template_1.ref(`groupClaim${idx}`), [ | ||
graphql_mapping_template_1.iff(graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref(`groupEntity${idx}.contains`), graphql_mapping_template_1.ref('userGroup')), graphql_mapping_template_1.compoundExpression([graphql_mapping_template_1.set(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG), graphql_mapping_template_1.bool(true)), graphql_mapping_template_1.raw('#break')])), | ||
]) | ||
: graphql_mapping_template_1.iff(graphql_mapping_template_1.ref(`groupClaim${idx}.contains($groupEntity${idx})`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG), graphql_mapping_template_1.bool(true))), | ||
]))); | ||
@@ -37,0 +37,0 @@ } |
@@ -1,2 +0,3 @@ | ||
export { generateAuthExpressionForQueries, generateAuthExpressionForSearchQueries, generateAuthExpressionForRelationQuery } from './query'; | ||
export { generateAuthExpressionForQueries, generateAuthExpressionForRelationQuery } from './query'; | ||
export { generateAuthExpressionForSearchQueries } from './search'; | ||
export { generateAuthExpressionForCreate } from './mutation.create'; | ||
@@ -3,0 +4,0 @@ export { generateAuthExpressionForUpdate } from './mutation.update'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.generateAuthRequestExpression = exports.generateAuthExpressionForSubscriptions = exports.setDeniedFieldFlag = exports.generateFieldAuthResponse = exports.generateAuthExpressionForField = exports.geneateAuthExpressionForDelete = exports.generateAuthExpressionForUpdate = exports.generateAuthExpressionForCreate = exports.generateAuthExpressionForRelationQuery = exports.generateAuthExpressionForSearchQueries = exports.generateAuthExpressionForQueries = void 0; | ||
exports.generateAuthRequestExpression = exports.generateAuthExpressionForSubscriptions = exports.setDeniedFieldFlag = exports.generateFieldAuthResponse = exports.generateAuthExpressionForField = exports.geneateAuthExpressionForDelete = exports.generateAuthExpressionForUpdate = exports.generateAuthExpressionForCreate = exports.generateAuthExpressionForSearchQueries = exports.generateAuthExpressionForRelationQuery = exports.generateAuthExpressionForQueries = void 0; | ||
var query_1 = require("./query"); | ||
Object.defineProperty(exports, "generateAuthExpressionForQueries", { enumerable: true, get: function () { return query_1.generateAuthExpressionForQueries; } }); | ||
Object.defineProperty(exports, "generateAuthExpressionForSearchQueries", { enumerable: true, get: function () { return query_1.generateAuthExpressionForSearchQueries; } }); | ||
Object.defineProperty(exports, "generateAuthExpressionForRelationQuery", { enumerable: true, get: function () { return query_1.generateAuthExpressionForRelationQuery; } }); | ||
var search_1 = require("./search"); | ||
Object.defineProperty(exports, "generateAuthExpressionForSearchQueries", { enumerable: true, get: function () { return search_1.generateAuthExpressionForSearchQueries; } }); | ||
var mutation_create_1 = require("./mutation.create"); | ||
@@ -9,0 +10,0 @@ Object.defineProperty(exports, "generateAuthExpressionForCreate", { enumerable: true, get: function () { return mutation_create_1.generateAuthExpressionForCreate; } }); |
import { FieldDefinitionNode } from 'graphql'; | ||
import { RoleDefinition, ConfiguredAuthProviders, RelationalPrimaryMapConfig } from '../utils'; | ||
export declare const generateAuthExpressionForQueries: (providers: ConfiguredAuthProviders, roles: Array<RoleDefinition>, fields: ReadonlyArray<FieldDefinitionNode>, primaryFields: Array<string>, isIndexQuery?: boolean) => string; | ||
export declare const generateAuthExpressionForSearchQueries: (providers: ConfiguredAuthProviders, roles: Array<RoleDefinition>, fields: ReadonlyArray<FieldDefinitionNode>) => string; | ||
export declare const generateAuthExpressionForRelationQuery: (providers: ConfiguredAuthProviders, roles: Array<RoleDefinition>, fields: ReadonlyArray<FieldDefinitionNode>, primaryFieldMap: RelationalPrimaryMapConfig) => string; | ||
//# sourceMappingURL=query.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.generateAuthExpressionForRelationQuery = exports.generateAuthExpressionForSearchQueries = exports.generateAuthExpressionForQueries = void 0; | ||
exports.generateAuthExpressionForRelationQuery = exports.generateAuthExpressionForQueries = void 0; | ||
const graphql_mapping_template_1 = require("graphql-mapping-template"); | ||
const helpers_1 = require("./helpers"); | ||
const utils_1 = require("../utils"); | ||
const graphql_transformer_core_1 = require("@aws-amplify/graphql-transformer-core"); | ||
const graphql_transformer_common_1 = require("graphql-transformer-common"); | ||
@@ -94,3 +93,3 @@ const generateStaticRoleExpression = (roles) => { | ||
}; | ||
const generateAuthFilter = (roles, fields, querySource) => { | ||
const generateAuthFilter = (roles, fields) => { | ||
const authFilter = new Array(); | ||
@@ -101,64 +100,32 @@ const groupMap = new Map(); | ||
return []; | ||
if (querySource === 'dynamodb') { | ||
for (let role of roles) { | ||
const entityIsList = utils_1.fieldIsList(fields, role.entity); | ||
if (role.strategy === 'owner') { | ||
const ownerCondition = entityIsList ? 'contains' : 'eq'; | ||
authFilter.push(graphql_mapping_template_1.obj({ [role.entity]: graphql_mapping_template_1.obj({ [ownerCondition]: helpers_1.getOwnerClaim(role.claim) }) })); | ||
} | ||
if (role.strategy === 'groups') { | ||
if (entityIsList) { | ||
if (groupMap.has(role.claim)) { | ||
groupMap.get(role.claim).push(role.entity); | ||
} | ||
else { | ||
groupMap.set(role.claim, [role.entity]); | ||
} | ||
for (let role of roles) { | ||
const entityIsList = utils_1.fieldIsList(fields, role.entity); | ||
if (role.strategy === 'owner') { | ||
const ownerCondition = entityIsList ? 'contains' : 'eq'; | ||
authFilter.push(graphql_mapping_template_1.obj({ [role.entity]: graphql_mapping_template_1.obj({ [ownerCondition]: helpers_1.getOwnerClaim(role.claim) }) })); | ||
} | ||
if (role.strategy === 'groups') { | ||
if (entityIsList) { | ||
if (groupMap.has(role.claim)) { | ||
groupMap.get(role.claim).push(role.entity); | ||
} | ||
else { | ||
authFilter.push(graphql_mapping_template_1.obj({ [role.entity]: graphql_mapping_template_1.obj({ in: helpers_1.getIdentityClaimExp(graphql_mapping_template_1.str(role.claim), graphql_mapping_template_1.list([graphql_mapping_template_1.str(graphql_transformer_common_1.NONE_VALUE)])) }) })); | ||
groupMap.set(role.claim, [role.entity]); | ||
} | ||
} | ||
} | ||
for (let [groupClaim, fieldList] of groupMap) { | ||
groupContainsExpression.push(graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('group'), graphql_mapping_template_1.ref(`util.defaultIfNull($ctx.identity.claims.get("${groupClaim}"), ["${graphql_transformer_common_1.NONE_VALUE}"])`), fieldList.map(field => graphql_mapping_template_1.qref(graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('authFilter.add'), graphql_mapping_template_1.raw(`{"${field}": { "contains": $group }}`)))))); | ||
} | ||
return [ | ||
graphql_mapping_template_1.iff(graphql_mapping_template_1.not(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG)), graphql_mapping_template_1.compoundExpression([ | ||
graphql_mapping_template_1.set(graphql_mapping_template_1.ref('authFilter'), graphql_mapping_template_1.list(authFilter)), | ||
...(groupContainsExpression.length > 0 ? groupContainsExpression : []), | ||
graphql_mapping_template_1.qref(graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('ctx.stash.put'), graphql_mapping_template_1.str('authFilter'), graphql_mapping_template_1.raw('{ "or": $authFilter }'))), | ||
])), | ||
]; | ||
} | ||
if (querySource === 'opensearch') { | ||
for (let role of roles) { | ||
const entityIsList = utils_1.fieldIsList(fields, role.entity); | ||
const roleKey = entityIsList ? role.entity : `${role.entity}.keyword`; | ||
if (role.strategy === 'owner') { | ||
authFilter.push(graphql_mapping_template_1.obj({ | ||
terms_set: graphql_mapping_template_1.obj({ | ||
[roleKey]: graphql_mapping_template_1.obj({ | ||
terms: graphql_mapping_template_1.list([helpers_1.getOwnerClaim(role.claim)]), | ||
minimum_should_match_script: graphql_mapping_template_1.obj({ source: graphql_mapping_template_1.str('1') }), | ||
}), | ||
}), | ||
})); | ||
else { | ||
authFilter.push(graphql_mapping_template_1.obj({ [role.entity]: graphql_mapping_template_1.obj({ in: helpers_1.getIdentityClaimExp(graphql_mapping_template_1.str(role.claim), graphql_mapping_template_1.list([graphql_mapping_template_1.str(graphql_transformer_common_1.NONE_VALUE)])) }) })); | ||
} | ||
else if (role.strategy === 'groups') { | ||
authFilter.push(graphql_mapping_template_1.obj({ | ||
terms_set: graphql_mapping_template_1.obj({ | ||
[roleKey]: graphql_mapping_template_1.obj({ | ||
terms: helpers_1.getIdentityClaimExp(graphql_mapping_template_1.str(role.claim), graphql_mapping_template_1.list([graphql_mapping_template_1.str(graphql_transformer_common_1.NONE_VALUE)])), | ||
minimum_should_match_script: graphql_mapping_template_1.obj({ source: graphql_mapping_template_1.str('1') }), | ||
}), | ||
}), | ||
})); | ||
} | ||
} | ||
return [ | ||
graphql_mapping_template_1.iff(graphql_mapping_template_1.not(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG)), graphql_mapping_template_1.qref(graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('ctx.stash.put'), graphql_mapping_template_1.str('authFilter'), graphql_mapping_template_1.obj({ bool: graphql_mapping_template_1.obj({ should: graphql_mapping_template_1.list(authFilter) }) })))), | ||
]; | ||
} | ||
throw new graphql_transformer_core_1.InvalidDirectiveError(`Could not generate an auth filter for a ${querySource} datasource.`); | ||
for (let [groupClaim, fieldList] of groupMap) { | ||
groupContainsExpression.push(graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('group'), graphql_mapping_template_1.ref(`util.defaultIfNull($ctx.identity.claims.get("${groupClaim}"), ["${graphql_transformer_common_1.NONE_VALUE}"])`), fieldList.map(field => graphql_mapping_template_1.qref(graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('authFilter.add'), graphql_mapping_template_1.raw(`{"${field}": { "contains": $group }}`)))))); | ||
} | ||
return [ | ||
graphql_mapping_template_1.iff(graphql_mapping_template_1.not(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG)), graphql_mapping_template_1.compoundExpression([ | ||
graphql_mapping_template_1.set(graphql_mapping_template_1.ref('authFilter'), graphql_mapping_template_1.list(authFilter)), | ||
...(groupContainsExpression.length > 0 ? groupContainsExpression : []), | ||
graphql_mapping_template_1.qref(graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('ctx.stash.put'), graphql_mapping_template_1.str('authFilter'), graphql_mapping_template_1.raw('{ "or": $authFilter }'))), | ||
])), | ||
]; | ||
}; | ||
@@ -182,3 +149,3 @@ const generateAuthExpressionForQueries = (providers, roles, fields, primaryFields, isIndexQuery = false) => { | ||
...generateStaticRoleExpression(cogntoStaticRoles), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(cognitoDynamicRoles), fields, 'dynamodb'), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(cognitoDynamicRoles), fields), | ||
...generateAuthOnModelQueryExpression(cognitoDynamicRoles, primaryFields, isIndexQuery), | ||
@@ -190,3 +157,3 @@ ]))); | ||
...generateStaticRoleExpression(oidcStaticRoles), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(oidcDynamicRoles), fields, 'dynamodb'), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(oidcDynamicRoles), fields), | ||
...generateAuthOnModelQueryExpression(oidcDynamicRoles, primaryFields, isIndexQuery), | ||
@@ -199,24 +166,2 @@ ]))); | ||
exports.generateAuthExpressionForQueries = generateAuthExpressionForQueries; | ||
const generateAuthExpressionForSearchQueries = (providers, roles, fields) => { | ||
const { cogntoStaticRoles, cognitoDynamicRoles, oidcStaticRoles, oidcDynamicRoles, apiKeyRoles, iamRoles } = utils_1.splitRoles(roles); | ||
const totalAuthExpressions = [helpers_1.setHasAuthExpression, graphql_mapping_template_1.set(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG), graphql_mapping_template_1.bool(false))]; | ||
if (providers.hasApiKey) { | ||
totalAuthExpressions.push(helpers_1.apiKeyExpression(apiKeyRoles)); | ||
} | ||
if (providers.hasIAM) { | ||
totalAuthExpressions.push(helpers_1.iamExpression(iamRoles, providers.hasAdminUIEnabled, providers.adminUserPoolID)); | ||
} | ||
if (providers.hasUserPools) { | ||
totalAuthExpressions.push(graphql_mapping_template_1.iff(graphql_mapping_template_1.equals(graphql_mapping_template_1.ref('util.authType()'), graphql_mapping_template_1.str(utils_1.COGNITO_AUTH_TYPE)), graphql_mapping_template_1.compoundExpression([ | ||
...generateStaticRoleExpression(cogntoStaticRoles), | ||
...generateAuthFilter(cognitoDynamicRoles, fields, 'opensearch'), | ||
]))); | ||
} | ||
if (providers.hasOIDC) { | ||
totalAuthExpressions.push(graphql_mapping_template_1.iff(graphql_mapping_template_1.equals(graphql_mapping_template_1.ref('util.authType()'), graphql_mapping_template_1.str(utils_1.OIDC_AUTH_TYPE)), graphql_mapping_template_1.compoundExpression([...generateStaticRoleExpression(oidcStaticRoles), ...generateAuthFilter(oidcDynamicRoles, [], 'opensearch')]))); | ||
} | ||
totalAuthExpressions.push(graphql_mapping_template_1.iff(graphql_mapping_template_1.and([graphql_mapping_template_1.not(graphql_mapping_template_1.ref(utils_1.IS_AUTHORIZED_FLAG)), graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('util.isNull'), graphql_mapping_template_1.ref('ctx.stash.authFilter'))]), graphql_mapping_template_1.ref('util.unauthorized()'))); | ||
return graphql_mapping_template_1.printBlock('Authorization Steps')(graphql_mapping_template_1.compoundExpression([...totalAuthExpressions, helpers_1.emptyPayload])); | ||
}; | ||
exports.generateAuthExpressionForSearchQueries = generateAuthExpressionForSearchQueries; | ||
const generateAuthExpressionForRelationQuery = (providers, roles, fields, primaryFieldMap) => { | ||
@@ -239,3 +184,3 @@ const { cogntoStaticRoles, cognitoDynamicRoles, oidcStaticRoles, oidcDynamicRoles, apiKeyRoles, iamRoles } = utils_1.splitRoles(roles); | ||
...generateStaticRoleExpression(cogntoStaticRoles), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(cognitoDynamicRoles), fields, 'dynamodb'), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(cognitoDynamicRoles), fields), | ||
...generateAuthOnRelationalModelQueryExpression(cognitoDynamicRoles, primaryFieldMap), | ||
@@ -247,3 +192,3 @@ ]))); | ||
...generateStaticRoleExpression(oidcStaticRoles), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(oidcDynamicRoles), fields, 'dynamodb'), | ||
...generateAuthFilter(getNonPrimaryFieldRoles(oidcDynamicRoles), fields), | ||
...generateAuthOnRelationalModelQueryExpression(oidcDynamicRoles, primaryFieldMap), | ||
@@ -250,0 +195,0 @@ ]))); |
@@ -25,2 +25,3 @@ import { AuthProvider, ModelOperation } from './definitions'; | ||
export declare const RELATIONAL_DIRECTIVES: string[]; | ||
export declare const SEARCHABLE_AGGREGATE_TYPES: string[]; | ||
//# sourceMappingURL=constants.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RELATIONAL_DIRECTIVES = exports.NONE_DS = exports.MANAGE_ROLE = exports.ADMIN_ROLE = exports.DENIED_FIELDS = exports.NULL_ALLOWED_FIELDS = exports.ALLOWED_FIELDS = exports.IS_AUTHORIZED_FLAG = exports.API_KEY_AUTH_TYPE = exports.IAM_AUTH_TYPE = exports.OIDC_AUTH_TYPE = exports.COGNITO_AUTH_TYPE = exports.AUTH_PROVIDER_DIRECTIVE_MAP = exports.MODEL_OPERATIONS = exports.AUTH_NON_MODEL_TYPES = exports.ON_DELETE_FIELD = exports.ON_UPDATE_FIELD = exports.ON_CREATE_FIELD = exports.DEFAULT_GROUP_CLAIM = exports.DEFAULT_COGNITO_IDENTITY_CLAIM = exports.DEFAULT_IDENTITY_CLAIM = exports.DEFAULT_GROUPS_FIELD = exports.DEFAULT_OWNER_FIELD = void 0; | ||
exports.SEARCHABLE_AGGREGATE_TYPES = exports.RELATIONAL_DIRECTIVES = exports.NONE_DS = exports.MANAGE_ROLE = exports.ADMIN_ROLE = exports.DENIED_FIELDS = exports.NULL_ALLOWED_FIELDS = exports.ALLOWED_FIELDS = exports.IS_AUTHORIZED_FLAG = exports.API_KEY_AUTH_TYPE = exports.IAM_AUTH_TYPE = exports.OIDC_AUTH_TYPE = exports.COGNITO_AUTH_TYPE = exports.AUTH_PROVIDER_DIRECTIVE_MAP = exports.MODEL_OPERATIONS = exports.AUTH_NON_MODEL_TYPES = exports.ON_DELETE_FIELD = exports.ON_UPDATE_FIELD = exports.ON_CREATE_FIELD = exports.DEFAULT_GROUP_CLAIM = exports.DEFAULT_COGNITO_IDENTITY_CLAIM = exports.DEFAULT_IDENTITY_CLAIM = exports.DEFAULT_GROUPS_FIELD = exports.DEFAULT_OWNER_FIELD = void 0; | ||
exports.DEFAULT_OWNER_FIELD = 'owner'; | ||
@@ -32,2 +32,8 @@ exports.DEFAULT_GROUPS_FIELD = 'groups'; | ||
exports.RELATIONAL_DIRECTIVES = ['hasOne', 'belongsTo', 'hasMany', 'manyToMany']; | ||
exports.SEARCHABLE_AGGREGATE_TYPES = [ | ||
'SearchableAggregateResult', | ||
'SearchableAggregateScalarResult', | ||
'SearchableAggregateBucketResult', | ||
'SearchableAggregateBucketResultItem', | ||
]; | ||
//# sourceMappingURL=constants.js.map |
@@ -7,3 +7,2 @@ import { AppSyncAuthConfiguration } from '@aws-amplify/graphql-transformer-interfaces'; | ||
export declare type ModelOperation = 'create' | 'update' | 'delete' | 'read'; | ||
export declare type QuerySource = 'dynamodb' | 'opensearch'; | ||
export declare type RelationalPrimaryMapConfig = Map<string, { | ||
@@ -10,0 +9,0 @@ claim: string; |
import { AuthRule, ConfiguredAuthProviders } from './definitions'; | ||
export declare const validateRuleAuthStrategy: (rule: AuthRule, configuredAuthProviders: ConfiguredAuthProviders) => void; | ||
export declare const validateRules: (rules: AuthRule[], configuredAuthProviders: ConfiguredAuthProviders) => void; | ||
export declare const validateFieldRules: (rules: AuthRule[], isParentTypeBuiltinType: boolean, parentHasModelDirective: boolean, authProviderConfig: ConfiguredAuthProviders) => void; | ||
export declare const validateRules: (rules: AuthRule[], configuredAuthProviders: ConfiguredAuthProviders, typeName: string) => void; | ||
export declare const validateFieldRules: (rules: AuthRule[], isParentTypeBuiltinType: boolean, parentHasModelDirective: boolean, authProviderConfig: ConfiguredAuthProviders, fieldName: string) => void; | ||
export declare const commonRuleValidation: (rule: AuthRule) => void; | ||
//# sourceMappingURL=validations.d.ts.map |
@@ -44,3 +44,6 @@ "use strict"; | ||
exports.validateRuleAuthStrategy = validateRuleAuthStrategy; | ||
const validateRules = (rules, configuredAuthProviders) => { | ||
const validateRules = (rules, configuredAuthProviders, typeName) => { | ||
if (rules.length === 0) { | ||
throw new graphql_transformer_core_1.InvalidDirectiveError(`@auth on ${typeName} does not have any auth rules.`); | ||
} | ||
for (const rule of rules) { | ||
@@ -52,3 +55,6 @@ exports.validateRuleAuthStrategy(rule, configuredAuthProviders); | ||
exports.validateRules = validateRules; | ||
const validateFieldRules = (rules, isParentTypeBuiltinType, parentHasModelDirective, authProviderConfig) => { | ||
const validateFieldRules = (rules, isParentTypeBuiltinType, parentHasModelDirective, authProviderConfig, fieldName) => { | ||
if (rules.length === 0) { | ||
throw new graphql_transformer_core_1.InvalidDirectiveError(`@auth on ${fieldName} does not have any auth rules.`); | ||
} | ||
for (const rule of rules) { | ||
@@ -81,4 +87,7 @@ exports.validateRuleAuthStrategy(rule, authProviderConfig); | ||
} | ||
if (allow === 'groups' && groups && groups.length < 1) { | ||
throw new graphql_transformer_core_1.InvalidDirectiveError('@auth rules using groups cannot have an empty list'); | ||
} | ||
}; | ||
exports.commonRuleValidation = commonRuleValidation; | ||
//# sourceMappingURL=validations.js.map |
{ | ||
"name": "@aws-amplify/graphql-auth-transformer", | ||
"version": "0.1.1-beta.0", | ||
"version": "0.1.1-ext10.0", | ||
"description": "Amplify GraphQL @auth Transformer", | ||
@@ -30,5 +30,5 @@ "repository": { | ||
"dependencies": { | ||
"@aws-amplify/graphql-model-transformer": "0.6.5-beta.0", | ||
"@aws-amplify/graphql-transformer-core": "0.9.3-beta.0", | ||
"@aws-amplify/graphql-transformer-interfaces": "1.10.1-beta.0", | ||
"@aws-amplify/graphql-model-transformer": "0.7.0-ext10.0", | ||
"@aws-amplify/graphql-transformer-core": "0.9.3-ext10.0", | ||
"@aws-amplify/graphql-transformer-interfaces": "1.10.1-ext10.0", | ||
"@aws-cdk/aws-appsync": "~1.124.0", | ||
@@ -40,9 +40,9 @@ "@aws-cdk/aws-dynamodb": "~1.124.0", | ||
"graphql": "^14.5.8", | ||
"graphql-mapping-template": "4.18.4-beta.0", | ||
"graphql-transformer-common": "4.19.11-beta.0", | ||
"graphql-mapping-template": "4.18.4-ext10.0", | ||
"graphql-transformer-common": "4.20.0-ext10.0", | ||
"lodash": "^4.17.21" | ||
}, | ||
"devDependencies": { | ||
"@aws-amplify/graphql-index-transformer": "0.4.1-beta.0", | ||
"@aws-amplify/graphql-searchable-transformer": "0.6.4-beta.0", | ||
"@aws-amplify/graphql-index-transformer": "0.5.0-ext10.0", | ||
"@aws-amplify/graphql-searchable-transformer": "0.7.0-ext10.0", | ||
"@aws-cdk/assert": "~1.124.0", | ||
@@ -68,3 +68,3 @@ "@types/fs-extra": "^8.0.1", | ||
}, | ||
"gitHead": "a330ea6e88e56a1b70b76c9162ffd498039e8180" | ||
"gitHead": "d5258768dd7273c00cfc233df082fa59896df03b" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
351240
79
2826
+ Added@aws-amplify/graphql-model-transformer@0.7.0-ext10.0(transitive)
+ Added@aws-amplify/graphql-transformer-core@0.9.3-ext10.0(transitive)
+ Added@aws-amplify/graphql-transformer-interfaces@1.10.1-ext10.0(transitive)
+ Addedgraphql-mapping-template@4.18.4-ext10.0(transitive)
+ Addedgraphql-transformer-common@4.20.0-ext10.0(transitive)
- Removed@aws-amplify/graphql-model-transformer@0.6.5-beta.0(transitive)
- Removed@aws-amplify/graphql-transformer-core@0.9.3-beta.0(transitive)
- Removed@aws-amplify/graphql-transformer-interfaces@1.10.1-beta.0(transitive)
- Removedgraphql-mapping-template@4.18.4-beta.0(transitive)
- Removedgraphql-transformer-common@4.19.11-beta.0(transitive)
Updated@aws-amplify/graphql-transformer-interfaces@1.10.1-ext10.0