1 | "use strict";
|
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3 | if (k2 === undefined) k2 = k;
|
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5 | }) : (function(o, m, k, k2) {
|
6 | if (k2 === undefined) k2 = k;
|
7 | o[k2] = m[k];
|
8 | }));
|
9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11 | }) : function(o, v) {
|
12 | o["default"] = v;
|
13 | });
|
14 | var __importStar = (this && this.__importStar) || function (mod) {
|
15 | if (mod && mod.__esModule) return mod;
|
16 | var result = {};
|
17 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18 | __setModuleDefault(result, mod);
|
19 | return result;
|
20 | };
|
21 | Object.defineProperty(exports, "__esModule", { value: true });
|
22 | exports.ResourceFactory = void 0;
|
23 | const cloudform_types_1 = require("cloudform-types");
|
24 | const graphql_mapping_template_1 = require("graphql-mapping-template");
|
25 | const graphql_transformer_common_1 = require("graphql-transformer-common");
|
26 | const graphQlApi_1 = __importStar(require("cloudform-types/types/appSync/graphQlApi"));
|
27 | const constants_1 = require("./constants");
|
28 | function replaceIfUsername(identityClaim) {
|
29 | return identityClaim === 'username' ? 'cognito:username' : identityClaim;
|
30 | }
|
31 | function isUsername(identityClaim) {
|
32 | return identityClaim === 'username';
|
33 | }
|
34 | class ResourceFactory {
|
35 | constructor() {
|
36 | this.getSourceMapper = (includeVersion) => {
|
37 | if (includeVersion) {
|
38 | return [
|
39 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('row'), graphql_mapping_template_1.methodCall(graphql_mapping_template_1.ref('entry.get'), graphql_mapping_template_1.str('_source'))),
|
40 | graphql_mapping_template_1.qref('$row.put("_version", $entry.get("_version"))'),
|
41 | graphql_mapping_template_1.qref('$es_items.add($row)'),
|
42 | ];
|
43 | }
|
44 | return [graphql_mapping_template_1.qref('$es_items.add($entry.get("_source"))')];
|
45 | };
|
46 | }
|
47 | makeParams() {
|
48 | return {
|
49 | [graphql_transformer_common_1.ResourceConstants.PARAMETERS.AppSyncApiName]: new cloudform_types_1.StringParameter({
|
50 | Description: 'The name of the AppSync API',
|
51 | Default: 'AppSyncSimpleTransform',
|
52 | }),
|
53 | [graphql_transformer_common_1.ResourceConstants.PARAMETERS.APIKeyExpirationEpoch]: new cloudform_types_1.NumberParameter({
|
54 | Description: 'The epoch time in seconds when the API Key should expire.' +
|
55 | ' Setting this to 0 will default to 7 days from the deployment date.' +
|
56 | ' Setting this to -1 will not create an API Key.',
|
57 | Default: 0,
|
58 | MinValue: -1,
|
59 | }),
|
60 | [graphql_transformer_common_1.ResourceConstants.PARAMETERS.CreateAPIKey]: new cloudform_types_1.NumberParameter({
|
61 | Description: 'The boolean value to control if an API Key will be created or not.' +
|
62 | ' The value of the property is automatically set by the CLI.' +
|
63 | ' If the value is set to 0 no API Key will be created.',
|
64 | Default: 0,
|
65 | MinValue: 0,
|
66 | MaxValue: 1,
|
67 | }),
|
68 | [graphql_transformer_common_1.ResourceConstants.PARAMETERS.AuthCognitoUserPoolId]: new cloudform_types_1.StringParameter({
|
69 | Description: 'The id of an existing User Pool to connect. If this is changed, a user pool will not be created for you.',
|
70 | Default: graphql_transformer_common_1.ResourceConstants.NONE,
|
71 | }),
|
72 | };
|
73 | }
|
74 | initTemplate(apiKeyConfig) {
|
75 | return {
|
76 | Parameters: this.makeParams(),
|
77 | Resources: {
|
78 | [graphql_transformer_common_1.ResourceConstants.RESOURCES.APIKeyLogicalID]: this.makeAppSyncApiKey(apiKeyConfig),
|
79 | },
|
80 | Outputs: {
|
81 | [graphql_transformer_common_1.ResourceConstants.OUTPUTS.GraphQLAPIApiKeyOutput]: this.makeApiKeyOutput(),
|
82 | },
|
83 | Conditions: {
|
84 | [graphql_transformer_common_1.ResourceConstants.CONDITIONS.ShouldCreateAPIKey]: cloudform_types_1.Fn.Equals(cloudform_types_1.Fn.Ref(graphql_transformer_common_1.ResourceConstants.PARAMETERS.CreateAPIKey), 1),
|
85 | [graphql_transformer_common_1.ResourceConstants.CONDITIONS.APIKeyExpirationEpochIsPositive]: cloudform_types_1.Fn.And([
|
86 | cloudform_types_1.Fn.Not(cloudform_types_1.Fn.Equals(cloudform_types_1.Fn.Ref(graphql_transformer_common_1.ResourceConstants.PARAMETERS.APIKeyExpirationEpoch), -1)),
|
87 | cloudform_types_1.Fn.Not(cloudform_types_1.Fn.Equals(cloudform_types_1.Fn.Ref(graphql_transformer_common_1.ResourceConstants.PARAMETERS.APIKeyExpirationEpoch), 0)),
|
88 | ]),
|
89 | },
|
90 | };
|
91 | }
|
92 | makeAppSyncApiKey(apiKeyConfig) {
|
93 | let expirationDays = 7;
|
94 | if (apiKeyConfig && apiKeyConfig.apiKeyExpirationDays) {
|
95 | expirationDays = apiKeyConfig.apiKeyExpirationDays;
|
96 | }
|
97 | let expirationDateInSeconds = 60 * 60 * 24 * expirationDays;
|
98 | if (expirationDays === 1)
|
99 | expirationDateInSeconds += 60 * 2;
|
100 | const nowEpochTime = Math.floor(Date.now() / 1000);
|
101 | return new cloudform_types_1.AppSync.ApiKey({
|
102 | ApiId: cloudform_types_1.Fn.GetAtt(graphql_transformer_common_1.ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
|
103 | Description: apiKeyConfig && apiKeyConfig.description ? apiKeyConfig.description : undefined,
|
104 | Expires: cloudform_types_1.Fn.If(graphql_transformer_common_1.ResourceConstants.CONDITIONS.APIKeyExpirationEpochIsPositive, cloudform_types_1.Fn.Ref(graphql_transformer_common_1.ResourceConstants.PARAMETERS.APIKeyExpirationEpoch), nowEpochTime + expirationDateInSeconds),
|
105 | }).condition(graphql_transformer_common_1.ResourceConstants.CONDITIONS.ShouldCreateAPIKey);
|
106 | }
|
107 | makeApiKeyOutput() {
|
108 | return {
|
109 | Description: "Your GraphQL API key. Provide via 'x-api-key' header.",
|
110 | Value: cloudform_types_1.Fn.GetAtt(graphql_transformer_common_1.ResourceConstants.RESOURCES.APIKeyLogicalID, 'ApiKey'),
|
111 | Export: {
|
112 | Name: cloudform_types_1.Fn.Join(':', [cloudform_types_1.Refs.StackName, 'GraphQLApiKey']),
|
113 | },
|
114 | Condition: graphql_transformer_common_1.ResourceConstants.CONDITIONS.ShouldCreateAPIKey,
|
115 | };
|
116 | }
|
117 | updateGraphQLAPIWithAuth(apiRecord, authConfig) {
|
118 | let properties = {
|
119 | ...apiRecord.Properties,
|
120 | Name: apiRecord.Properties.Name,
|
121 | AuthenticationType: authConfig.defaultAuthentication.authenticationType,
|
122 | UserPoolConfig: undefined,
|
123 | OpenIDConnectConfig: undefined,
|
124 | };
|
125 | switch (authConfig.defaultAuthentication.authenticationType) {
|
126 | case 'AMAZON_COGNITO_USER_POOLS':
|
127 | properties.UserPoolConfig = new graphQlApi_1.UserPoolConfig({
|
128 | UserPoolId: cloudform_types_1.Fn.Ref(graphql_transformer_common_1.ResourceConstants.PARAMETERS.AuthCognitoUserPoolId),
|
129 | AwsRegion: cloudform_types_1.Refs.Region,
|
130 | DefaultAction: 'ALLOW',
|
131 | });
|
132 | break;
|
133 | case 'OPENID_CONNECT':
|
134 | if (!authConfig.defaultAuthentication.openIDConnectConfig) {
|
135 | throw new Error('openIDConnectConfig is not configured for defaultAuthentication');
|
136 | }
|
137 | properties.OpenIDConnectConfig = this.assignOpenIDConnectConfig(authConfig.defaultAuthentication.openIDConnectConfig);
|
138 | break;
|
139 | }
|
140 | if (authConfig.additionalAuthenticationProviders && authConfig.additionalAuthenticationProviders.length > 0) {
|
141 | const additionalAuthenticationProviders = new Array();
|
142 | for (const sourceProvider of authConfig.additionalAuthenticationProviders) {
|
143 | let provider;
|
144 | switch (sourceProvider.authenticationType) {
|
145 | case 'AMAZON_COGNITO_USER_POOLS':
|
146 | provider = {
|
147 | AuthenticationType: 'AMAZON_COGNITO_USER_POOLS',
|
148 | UserPoolConfig: new graphQlApi_1.UserPoolConfig({
|
149 | UserPoolId: cloudform_types_1.Fn.Ref(graphql_transformer_common_1.ResourceConstants.PARAMETERS.AuthCognitoUserPoolId),
|
150 | AwsRegion: cloudform_types_1.Refs.Region,
|
151 | }),
|
152 | };
|
153 | break;
|
154 | case 'API_KEY':
|
155 | provider = {
|
156 | AuthenticationType: 'API_KEY',
|
157 | };
|
158 | break;
|
159 | case 'AWS_IAM':
|
160 | provider = {
|
161 | AuthenticationType: 'AWS_IAM',
|
162 | };
|
163 | break;
|
164 | case 'OPENID_CONNECT':
|
165 | if (!sourceProvider.openIDConnectConfig) {
|
166 | throw new Error('openIDConnectConfig is not configured for provider');
|
167 | }
|
168 | provider = {
|
169 | AuthenticationType: 'OPENID_CONNECT',
|
170 | OpenIDConnectConfig: this.assignOpenIDConnectConfig(sourceProvider.openIDConnectConfig),
|
171 | };
|
172 | break;
|
173 | }
|
174 | additionalAuthenticationProviders.push(provider);
|
175 | }
|
176 | properties.AdditionalAuthenticationProviders = additionalAuthenticationProviders;
|
177 | }
|
178 | return new graphQlApi_1.default(properties);
|
179 | }
|
180 | assignOpenIDConnectConfig(config) {
|
181 | return new graphQlApi_1.OpenIDConnectConfig({
|
182 | Issuer: config.issuerUrl,
|
183 | ClientId: config.clientId,
|
184 | IatTTL: config.iatTTL,
|
185 | AuthTTL: config.authTTL,
|
186 | });
|
187 | }
|
188 | blankResolver(type, field) {
|
189 | return new cloudform_types_1.AppSync.Resolver({
|
190 | ApiId: cloudform_types_1.Fn.GetAtt(graphql_transformer_common_1.ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
|
191 | DataSourceName: 'NONE',
|
192 | FieldName: field,
|
193 | TypeName: type,
|
194 | RequestMappingTemplate: graphql_mapping_template_1.print(graphql_mapping_template_1.obj({
|
195 | version: graphql_mapping_template_1.str('2017-02-28'),
|
196 | payload: graphql_mapping_template_1.obj({}),
|
197 | })),
|
198 | ResponseMappingTemplate: graphql_mapping_template_1.print(graphql_mapping_template_1.ref(`util.toJson($context.source.${field})`)),
|
199 | });
|
200 | }
|
201 | noneDataSource() {
|
202 | return new cloudform_types_1.AppSync.DataSource({
|
203 | ApiId: cloudform_types_1.Fn.GetAtt(graphql_transformer_common_1.ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
|
204 | Name: 'NONE',
|
205 | Type: 'NONE',
|
206 | });
|
207 | }
|
208 | staticGroupAuthorizationExpression(rules, field) {
|
209 | if (!rules || rules.length === 0) {
|
210 | return graphql_mapping_template_1.comment(`No Static Group Authorization Rules`);
|
211 | }
|
212 | const variableToSet = this.getStaticAuthorizationVariable(field);
|
213 | let groupAuthorizationExpressions = [];
|
214 | for (const rule of rules) {
|
215 | const groups = rule.groups;
|
216 | const groupClaimAttribute = rule.groupClaim || constants_1.DEFAULT_GROUP_CLAIM;
|
217 | if (groups) {
|
218 | groupAuthorizationExpressions = groupAuthorizationExpressions.concat(graphql_mapping_template_1.comment(`Authorization rule: { allow: groups, groups: ${JSON.stringify(groups)}, groupClaim: "${groupClaimAttribute}" }`), this.setUserGroups(rule.groupClaim), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('allowedGroups'), graphql_mapping_template_1.list(groups.map(s => graphql_mapping_template_1.str(s)))), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('userGroup'), graphql_mapping_template_1.ref('userGroups'), [
|
219 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$allowedGroups.contains($userGroup)`), graphql_mapping_template_1.compoundExpression([graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')), graphql_mapping_template_1.raw('#break')])),
|
220 | ]));
|
221 | }
|
222 | }
|
223 | const staticGroupAuthorizedVariable = this.getStaticAuthorizationVariable(field);
|
224 | return graphql_mapping_template_1.block('Static Group Authorization Checks', [
|
225 | graphql_mapping_template_1.raw(`#set($${staticGroupAuthorizedVariable} = $util.defaultIfNull(
|
226 | $${staticGroupAuthorizedVariable}, false))`),
|
227 | ...groupAuthorizationExpressions,
|
228 | ]);
|
229 | }
|
230 | dynamicGroupAuthorizationExpressionForCreateOperations(rules, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsDynamicGroupAuthorizedVariable) {
|
231 | if (!rules || rules.length === 0) {
|
232 | return graphql_mapping_template_1.comment(`No Dynamic Group Authorization Rules`);
|
233 | }
|
234 | return graphql_mapping_template_1.block('Dynamic Group Authorization Checks', [
|
235 | this.dynamicAuthorizationExpressionForCreate(rules, variableToCheck, variableToSet),
|
236 | ]);
|
237 | }
|
238 | dynamicGroupAuthorizationExpressionForCreateOperationsByField(rules, fieldToCheck, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsDynamicGroupAuthorizedVariable) {
|
239 | if (!rules || rules.length === 0) {
|
240 | return graphql_mapping_template_1.comment(`No dynamic group authorization rules for field "${fieldToCheck}"`);
|
241 | }
|
242 | let groupAuthorizationExpression = this.dynamicAuthorizationExpressionForCreate(rules, variableToCheck, variableToSet, rule => `Authorization rule on field "${fieldToCheck}": { allow: ${rule.allow}, \
|
243 | groupsField: "${rule.groupsField || constants_1.DEFAULT_GROUPS_FIELD}", groupClaim: "${rule.groupClaim || constants_1.DEFAULT_GROUP_CLAIM}" }`);
|
244 | return graphql_mapping_template_1.block(`Dynamic group authorization rules for field "${fieldToCheck}"`, [groupAuthorizationExpression]);
|
245 | }
|
246 | dynamicAuthorizationExpressionForCreate(rules, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsDynamicGroupAuthorizedVariable, formatComment) {
|
247 | let groupAuthorizationExpressions = [];
|
248 | for (const rule of rules) {
|
249 | const groupsAttribute = rule.groupsField || constants_1.DEFAULT_GROUPS_FIELD;
|
250 | const groupClaimAttribute = rule.groupClaim || constants_1.DEFAULT_GROUP_CLAIM;
|
251 | groupAuthorizationExpressions = groupAuthorizationExpressions.concat(formatComment
|
252 | ? graphql_mapping_template_1.comment(formatComment(rule))
|
253 | : graphql_mapping_template_1.comment(`Authorization rule: { allow: ${rule.allow}, groupsField: "${groupsAttribute}", groupClaim: "${groupClaimAttribute}"`), this.setUserGroups(rule.groupClaim), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw(`$util.defaultIfNull($${variableToSet}, false)`)), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('userGroup'), graphql_mapping_template_1.ref('userGroups'), [
|
254 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isList($ctx.args.input.${groupsAttribute})`), graphql_mapping_template_1.iff(graphql_mapping_template_1.ref(`${variableToCheck}.${groupsAttribute}.contains($userGroup)`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')))),
|
255 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isString($ctx.args.input.${groupsAttribute})`), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$ctx.args.input.${groupsAttribute} == $userGroup`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')))),
|
256 | ]));
|
257 | }
|
258 | return graphql_mapping_template_1.compoundExpression(groupAuthorizationExpressions);
|
259 | }
|
260 | ownerAuthorizationExpressionForCreateOperations(rules, fieldIsList, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable) {
|
261 | if (!rules || rules.length === 0) {
|
262 | return graphql_mapping_template_1.comment(`No Owner Authorization Rules`);
|
263 | }
|
264 | return graphql_mapping_template_1.block('Owner Authorization Checks', [
|
265 | this.ownershipAuthorizationExpressionForCreate(rules, fieldIsList, variableToCheck, variableToSet),
|
266 | ]);
|
267 | }
|
268 | ownerAuthorizationExpressionForSubscriptions(rules, variableToCheck = 'ctx.args', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable) {
|
269 | if (!rules || rules.length === 0) {
|
270 | return graphql_mapping_template_1.comment(`No Owner Authorization Rules`);
|
271 | }
|
272 | return graphql_mapping_template_1.block('Owner Authorization Checks', [
|
273 | this.ownershipAuthorizationExpressionForSubscriptions(rules, variableToCheck, variableToSet),
|
274 | ]);
|
275 | }
|
276 | ownershipAuthorizationExpressionForSubscriptions(rules, variableToCheck = 'ctx.args', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable, formatComment) {
|
277 | let ownershipAuthorizationExpressions = [];
|
278 | let ruleNumber = 0;
|
279 | for (const rule of rules) {
|
280 | const ownerAttribute = rule.ownerField || constants_1.DEFAULT_OWNER_FIELD;
|
281 | const rawUsername = rule.identityField || rule.identityClaim || constants_1.DEFAULT_IDENTITY_FIELD;
|
282 | const isUser = isUsername(rawUsername);
|
283 | const identityAttribute = replaceIfUsername(rawUsername);
|
284 | const allowedOwnersVariable = `allowedOwners${ruleNumber}`;
|
285 | ownershipAuthorizationExpressions = ownershipAuthorizationExpressions.concat(formatComment
|
286 | ? graphql_mapping_template_1.comment(formatComment(rule))
|
287 | : graphql_mapping_template_1.comment(`Authorization rule: { allow: ${rule.allow}, ownerField: "${ownerAttribute}", identityClaim: "${identityAttribute}" }`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(allowedOwnersVariable), graphql_mapping_template_1.raw(`$util.defaultIfNull($${variableToCheck}.${ownerAttribute}, null)`)), isUser
|
288 | ?
|
289 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('identityValue'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${rawUsername}"),
|
290 | $util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}"))`))
|
291 | : graphql_mapping_template_1.set(graphql_mapping_template_1.ref('identityValue'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}")`)), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isList($${allowedOwnersVariable})`), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('allowedOwner'), graphql_mapping_template_1.ref(allowedOwnersVariable), [
|
292 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$allowedOwner == $identityValue`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true'))),
|
293 | ])), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isString($${allowedOwnersVariable})`), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$${allowedOwnersVariable} == $identityValue`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')))));
|
294 | ruleNumber++;
|
295 | }
|
296 | return graphql_mapping_template_1.compoundExpression([graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw(`false`)), ...ownershipAuthorizationExpressions]);
|
297 | }
|
298 | ownerAuthorizationExpressionForCreateOperationsByField(rules, fieldToCheck, fieldIsList, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable) {
|
299 | if (!rules || rules.length === 0) {
|
300 | return graphql_mapping_template_1.comment(`No Owner Authorization Rules`);
|
301 | }
|
302 | return graphql_mapping_template_1.block(`Owner authorization rules for field "${fieldToCheck}"`, [
|
303 | this.ownershipAuthorizationExpressionForCreate(rules, fieldIsList, variableToCheck, variableToSet, rule => `Authorization rule: { allow: ${rule.allow}, \
|
304 | ownerField: "${rule.ownerField || constants_1.DEFAULT_OWNER_FIELD}", \
|
305 | identityClaim: "${rule.identityField || rule.identityClaim || constants_1.DEFAULT_IDENTITY_FIELD}" }`),
|
306 | ]);
|
307 | }
|
308 | ownershipAuthorizationExpressionForCreate(rules, fieldIsList, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable, formatComment) {
|
309 | let ownershipAuthorizationExpressions = [];
|
310 | let ruleNumber = 0;
|
311 | for (const rule of rules) {
|
312 | const ownerAttribute = rule.ownerField || constants_1.DEFAULT_OWNER_FIELD;
|
313 | const rawUsername = rule.identityField || rule.identityClaim || constants_1.DEFAULT_IDENTITY_FIELD;
|
314 | const isUser = isUsername(rawUsername);
|
315 | const identityAttribute = replaceIfUsername(rawUsername);
|
316 | const ownerFieldIsList = fieldIsList(ownerAttribute);
|
317 | const allowedOwnersVariable = `allowedOwners${ruleNumber}`;
|
318 | ownershipAuthorizationExpressions = ownershipAuthorizationExpressions.concat(formatComment
|
319 | ? graphql_mapping_template_1.comment(formatComment(rule))
|
320 | : graphql_mapping_template_1.comment(`Authorization rule: { allow: ${rule.allow}, ownerField: "${ownerAttribute}", identityClaim: "${identityAttribute}" }`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(allowedOwnersVariable), graphql_mapping_template_1.raw(`$util.defaultIfNull($${variableToCheck}.${ownerAttribute}, null)`)), isUser
|
321 | ?
|
322 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('identityValue'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${rawUsername}"), $util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}"))`))
|
323 | : graphql_mapping_template_1.set(graphql_mapping_template_1.ref('identityValue'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}")`)), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isList($${allowedOwnersVariable})`), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('allowedOwner'), graphql_mapping_template_1.ref(allowedOwnersVariable), [
|
324 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$allowedOwner == $identityValue`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true'))),
|
325 | ])), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isString($${allowedOwnersVariable})`), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$${allowedOwnersVariable} == $identityValue`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')))));
|
326 | if (!ownerFieldIsList) {
|
327 | ownershipAuthorizationExpressions.push(graphql_mapping_template_1.iff(graphql_mapping_template_1.and([graphql_mapping_template_1.raw(`$util.isNull($${allowedOwnersVariable})`), graphql_mapping_template_1.parens(graphql_mapping_template_1.raw(`! $${variableToCheck}.containsKey("${ownerAttribute}")`))]), graphql_mapping_template_1.compoundExpression([
|
328 | graphql_mapping_template_1.qref(`$${variableToCheck}.put("${ownerAttribute}", $identityValue)`),
|
329 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')),
|
330 | ])));
|
331 | }
|
332 | else {
|
333 | ownershipAuthorizationExpressions.push(graphql_mapping_template_1.iff(graphql_mapping_template_1.and([graphql_mapping_template_1.raw(`$util.isNull($${allowedOwnersVariable})`), graphql_mapping_template_1.parens(graphql_mapping_template_1.raw(`! $${variableToCheck}.containsKey("${ownerAttribute}")`))]), graphql_mapping_template_1.compoundExpression([
|
334 | graphql_mapping_template_1.qref(`$${variableToCheck}.put("${ownerAttribute}", ["$identityValue"])`),
|
335 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')),
|
336 | ])));
|
337 | }
|
338 | ruleNumber++;
|
339 | }
|
340 | return graphql_mapping_template_1.compoundExpression([graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw(`false`)), ...ownershipAuthorizationExpressions]);
|
341 | }
|
342 | dynamicGroupAuthorizationExpressionForUpdateOrDeleteOperations(rules, fieldIsList, fieldBeingProtected, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsDynamicGroupAuthorizedVariable) {
|
343 | const fieldMention = fieldBeingProtected ? ` for field "${fieldBeingProtected}"` : '';
|
344 | if (!rules || rules.length === 0) {
|
345 | return graphql_mapping_template_1.comment(`No dynamic group authorization rules${fieldMention}`);
|
346 | }
|
347 | let groupAuthorizationExpressions = [];
|
348 | let ruleNumber = 0;
|
349 | for (const rule of rules) {
|
350 | const groupsAttribute = rule.groupsField || constants_1.DEFAULT_GROUPS_FIELD;
|
351 | const groupsAttributeName = fieldBeingProtected
|
352 | ? `${fieldBeingProtected}_groupsAttribute${ruleNumber}`
|
353 | : `groupsAttribute${ruleNumber}`;
|
354 | const groupName = fieldBeingProtected ? `${fieldBeingProtected}_group${ruleNumber}` : `group${ruleNumber}`;
|
355 | const groupClaimAttribute = rule.groupClaim || constants_1.DEFAULT_GROUP_CLAIM;
|
356 | const groupsFieldIsList = fieldIsList(groupsAttribute);
|
357 | groupAuthorizationExpressions = groupAuthorizationExpressions.concat(graphql_mapping_template_1.comment(`Authorization rule${fieldMention}: { allow: ${rule.allow}, groupsField: "${groupsAttribute}", groupClaim: "${groupClaimAttribute}"}`), this.setUserGroups(rule.groupClaim), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('userGroup'), graphql_mapping_template_1.ref('userGroups'), [
|
358 | groupsFieldIsList
|
359 | ? graphql_mapping_template_1.raw(`$util.qr($groupAuthExpressions.add("contains(#${groupsAttributeName}, :${groupName}$foreach.count)"))`)
|
360 | : graphql_mapping_template_1.raw(`$util.qr($groupAuthExpressions.add("#${groupsAttributeName} = :${groupName}$foreach.count"))`),
|
361 | graphql_mapping_template_1.raw(`$util.qr($groupAuthExpressionValues.put(":${groupName}$foreach.count", { "S": $userGroup }))`),
|
362 | ]), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw('$userGroups.size() > 0'), graphql_mapping_template_1.raw(`$util.qr($groupAuthExpressionNames.put("#${groupsAttributeName}", "${groupsAttribute}"))`)));
|
363 | ruleNumber++;
|
364 | }
|
365 | return graphql_mapping_template_1.block('Dynamic group authorization checks', [
|
366 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('groupAuthExpressions'), graphql_mapping_template_1.list([])),
|
367 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('groupAuthExpressionValues'), graphql_mapping_template_1.obj({})),
|
368 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('groupAuthExpressionNames'), graphql_mapping_template_1.obj({})),
|
369 | ...groupAuthorizationExpressions,
|
370 | ]);
|
371 | }
|
372 | ownerAuthorizationExpressionForUpdateOrDeleteOperations(rules, fieldIsList, fieldBeingProtected, variableToCheck = 'ctx.args.input', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable) {
|
373 | const fieldMention = fieldBeingProtected ? ` for field "${fieldBeingProtected}"` : '';
|
374 | if (!rules || rules.length === 0) {
|
375 | return graphql_mapping_template_1.comment(`No owner authorization rules${fieldMention}`);
|
376 | }
|
377 | let ownerAuthorizationExpressions = [];
|
378 | let ruleNumber = 0;
|
379 | for (const rule of rules) {
|
380 | const ownerAttribute = rule.ownerField || constants_1.DEFAULT_OWNER_FIELD;
|
381 | const rawUsername = rule.identityField || rule.identityClaim || constants_1.DEFAULT_IDENTITY_FIELD;
|
382 | const isUser = isUsername(rawUsername);
|
383 | const identityAttribute = replaceIfUsername(rawUsername);
|
384 | const ownerFieldIsList = fieldIsList(ownerAttribute);
|
385 | const ownerName = fieldBeingProtected ? `${fieldBeingProtected}_owner${ruleNumber}` : `owner${ruleNumber}`;
|
386 | const identityName = fieldBeingProtected ? `${fieldBeingProtected}_identity${ruleNumber}` : `identity${ruleNumber}`;
|
387 | ownerAuthorizationExpressions.push(graphql_mapping_template_1.comment(`Authorization rule${fieldMention}: { allow: ${rule.allow}, ownerField: "${ownerAttribute}", identityClaim: "${identityAttribute}" }`));
|
388 | if (ownerFieldIsList) {
|
389 | ownerAuthorizationExpressions.push(graphql_mapping_template_1.raw(`$util.qr($ownerAuthExpressions.add("contains(#${ownerName}, :${identityName})"))`));
|
390 | }
|
391 | else {
|
392 | ownerAuthorizationExpressions.push(graphql_mapping_template_1.raw(`$util.qr($ownerAuthExpressions.add("#${ownerName} = :${identityName}"))`));
|
393 | }
|
394 | ownerAuthorizationExpressions = ownerAuthorizationExpressions.concat(graphql_mapping_template_1.raw(`$util.qr($ownerAuthExpressionNames.put("#${ownerName}", "${ownerAttribute}"))`), isUser
|
395 | ? graphql_mapping_template_1.raw(`$util.qr($ownerAuthExpressionValues.put(":${identityName}", $util.dynamodb.toDynamoDB($util.defaultIfNull($ctx.identity.claims.get("${rawUsername}"), $util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}")))))`)
|
396 | : graphql_mapping_template_1.raw(`$util.qr($ownerAuthExpressionValues.put(":${identityName}", $util.dynamodb.toDynamoDB($util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}"))))`));
|
397 | ruleNumber++;
|
398 | }
|
399 | return graphql_mapping_template_1.block('Owner Authorization Checks', [
|
400 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('ownerAuthExpressions'), graphql_mapping_template_1.list([])),
|
401 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('ownerAuthExpressionValues'), graphql_mapping_template_1.obj({})),
|
402 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('ownerAuthExpressionNames'), graphql_mapping_template_1.obj({})),
|
403 | ...ownerAuthorizationExpressions,
|
404 | ]);
|
405 | }
|
406 | dynamicGroupAuthorizationExpressionForReadOperations(rules, variableToCheck = 'ctx.result', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsDynamicGroupAuthorizedVariable, defaultValue = graphql_mapping_template_1.raw(`$util.defaultIfNull($${variableToSet}, false)`)) {
|
407 | if (!rules || rules.length === 0) {
|
408 | return graphql_mapping_template_1.comment(`No Dynamic Group Authorization Rules`);
|
409 | }
|
410 | let groupAuthorizationExpressions = [];
|
411 | for (const rule of rules) {
|
412 | const groupsAttribute = rule.groupsField || constants_1.DEFAULT_GROUPS_FIELD;
|
413 | const groupClaimAttribute = rule.groupClaim || constants_1.DEFAULT_GROUP_CLAIM;
|
414 | groupAuthorizationExpressions = groupAuthorizationExpressions.concat(graphql_mapping_template_1.comment(`Authorization rule: { allow: ${rule.allow}, groupsField: "${groupsAttribute}", groupClaim: "${groupClaimAttribute}" }`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('allowedGroups'), graphql_mapping_template_1.ref(`util.defaultIfNull($${variableToCheck}.${groupsAttribute}, [])`)), this.setUserGroups(rule.groupClaim), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('userGroup'), graphql_mapping_template_1.ref('userGroups'), [
|
415 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw('$util.isList($allowedGroups)'), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$allowedGroups.contains($userGroup)`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')))),
|
416 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isString($allowedGroups)`), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$allowedGroups == $userGroup`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')))),
|
417 | ]));
|
418 | }
|
419 | return graphql_mapping_template_1.block('Dynamic Group Authorization Checks', [graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), defaultValue), ...groupAuthorizationExpressions]);
|
420 | }
|
421 | ownerAuthorizationExpressionForReadOperations(rules, variableToCheck = 'ctx.result', variableToSet = graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable, defaultValue = graphql_mapping_template_1.raw(`$util.defaultIfNull($${variableToSet}, false)`)) {
|
422 | if (!rules || rules.length === 0) {
|
423 | return graphql_mapping_template_1.comment(`No Owner Authorization Rules`);
|
424 | }
|
425 | let ownerAuthorizationExpressions = [];
|
426 | let ruleNumber = 0;
|
427 | for (const rule of rules) {
|
428 | const ownerAttribute = rule.ownerField || constants_1.DEFAULT_OWNER_FIELD;
|
429 | const rawUsername = rule.identityField || rule.identityClaim || constants_1.DEFAULT_IDENTITY_FIELD;
|
430 | const isUser = isUsername(rawUsername);
|
431 | const identityAttribute = replaceIfUsername(rawUsername);
|
432 | const allowedOwnersVariable = `allowedOwners${ruleNumber}`;
|
433 | ownerAuthorizationExpressions = ownerAuthorizationExpressions.concat(graphql_mapping_template_1.comment(`Authorization rule: { allow: ${rule.allow}, ownerField: "${ownerAttribute}", identityClaim: "${identityAttribute}" }`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(allowedOwnersVariable), graphql_mapping_template_1.ref(`${variableToCheck}.${ownerAttribute}`)), isUser
|
434 | ?
|
435 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('identityValue'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${rawUsername}"), $util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}"))`))
|
436 | : graphql_mapping_template_1.set(graphql_mapping_template_1.ref('identityValue'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${identityAttribute}"), "${graphql_transformer_common_1.NONE_VALUE}")`)), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isList($${allowedOwnersVariable})`), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('allowedOwner'), graphql_mapping_template_1.ref(allowedOwnersVariable), [
|
437 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$allowedOwner == $identityValue`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true'))),
|
438 | ])), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$util.isString($${allowedOwnersVariable})`), graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$${allowedOwnersVariable} == $identityValue`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), graphql_mapping_template_1.raw('true')))));
|
439 | ruleNumber++;
|
440 | }
|
441 | return graphql_mapping_template_1.block('Owner Authorization Checks', [graphql_mapping_template_1.set(graphql_mapping_template_1.ref(variableToSet), defaultValue), ...ownerAuthorizationExpressions]);
|
442 | }
|
443 | throwIfSubscriptionUnauthorized() {
|
444 | const ifUnauthThrow = graphql_mapping_template_1.iff(graphql_mapping_template_1.not(graphql_mapping_template_1.parens(graphql_mapping_template_1.or([
|
445 | graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsStaticGroupAuthorizedVariable), graphql_mapping_template_1.raw('true')),
|
446 | graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable), graphql_mapping_template_1.raw('true')),
|
447 | ]))), graphql_mapping_template_1.raw('$util.unauthorized()'));
|
448 | return graphql_mapping_template_1.block('Throw if unauthorized', [ifUnauthThrow]);
|
449 | }
|
450 | throwIfUnauthorized(field) {
|
451 | const staticGroupAuthorizedVariable = this.getStaticAuthorizationVariable(field);
|
452 | const ifUnauthThrow = graphql_mapping_template_1.iff(graphql_mapping_template_1.not(graphql_mapping_template_1.parens(graphql_mapping_template_1.or([
|
453 | graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(staticGroupAuthorizedVariable), graphql_mapping_template_1.raw('true')),
|
454 | graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsDynamicGroupAuthorizedVariable), graphql_mapping_template_1.raw('true')),
|
455 | graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsOwnerAuthorizedVariable), graphql_mapping_template_1.raw('true')),
|
456 | ]))), graphql_mapping_template_1.raw('$util.unauthorized()'));
|
457 | return graphql_mapping_template_1.block('Throw if unauthorized', [ifUnauthThrow]);
|
458 | }
|
459 | throwIfStaticGroupUnauthorized(field) {
|
460 | const staticGroupAuthorizedVariable = this.getStaticAuthorizationVariable(field);
|
461 | const ifUnauthThrow = graphql_mapping_template_1.iff(graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(staticGroupAuthorizedVariable), graphql_mapping_template_1.raw('false')), graphql_mapping_template_1.raw('$util.unauthorized()'));
|
462 | return graphql_mapping_template_1.block('Throw if unauthorized', [ifUnauthThrow]);
|
463 | }
|
464 | throwIfNotStaticGroupAuthorizedOrAuthConditionIsEmpty(field) {
|
465 | const staticGroupAuthorizedVariable = this.getStaticAuthorizationVariable(field);
|
466 | const ifUnauthThrow = graphql_mapping_template_1.iff(graphql_mapping_template_1.not(graphql_mapping_template_1.parens(graphql_mapping_template_1.or([graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(staticGroupAuthorizedVariable), graphql_mapping_template_1.raw('true')), graphql_mapping_template_1.parens(graphql_mapping_template_1.raw('$totalAuthExpression != ""'))]))), graphql_mapping_template_1.raw('$util.unauthorized()'));
|
467 | return graphql_mapping_template_1.block('Throw if unauthorized', [ifUnauthThrow]);
|
468 | }
|
469 | collectAuthCondition() {
|
470 | return graphql_mapping_template_1.block('Collect Auth Condition', [
|
471 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition), graphql_mapping_template_1.raw(`$util.defaultIfNull($authCondition, ${graphql_mapping_template_1.print(graphql_mapping_template_1.obj({
|
472 | expression: graphql_mapping_template_1.str(''),
|
473 | expressionNames: graphql_mapping_template_1.obj({}),
|
474 | expressionValues: graphql_mapping_template_1.obj({}),
|
475 | }))})`)),
|
476 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('totalAuthExpression'), graphql_mapping_template_1.str('')),
|
477 | graphql_mapping_template_1.comment('Add dynamic group auth conditions if they exist'),
|
478 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('groupAuthExpressions'), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('authExpr'), graphql_mapping_template_1.ref('groupAuthExpressions'), [
|
479 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('totalAuthExpression'), graphql_mapping_template_1.str(`$totalAuthExpression $authExpr`)),
|
480 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('foreach.hasNext'), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('totalAuthExpression'), graphql_mapping_template_1.str(`$totalAuthExpression OR`))),
|
481 | ])),
|
482 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('groupAuthExpressionNames'), graphql_mapping_template_1.raw(`$util.qr($${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expressionNames.putAll($groupAuthExpressionNames))`)),
|
483 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('groupAuthExpressionValues'), graphql_mapping_template_1.raw(`$util.qr($${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expressionValues.putAll($groupAuthExpressionValues))`)),
|
484 | graphql_mapping_template_1.comment('Add owner auth conditions if they exist'),
|
485 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$totalAuthExpression != "" && $ownerAuthExpressions && $ownerAuthExpressions.size() > 0`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('totalAuthExpression'), graphql_mapping_template_1.str(`$totalAuthExpression OR`))),
|
486 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('ownerAuthExpressions'), graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('authExpr'), graphql_mapping_template_1.ref('ownerAuthExpressions'), [
|
487 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('totalAuthExpression'), graphql_mapping_template_1.str(`$totalAuthExpression $authExpr`)),
|
488 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('foreach.hasNext'), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('totalAuthExpression'), graphql_mapping_template_1.str(`$totalAuthExpression OR`))),
|
489 | ])),
|
490 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('ownerAuthExpressionNames'), graphql_mapping_template_1.raw(`$util.qr($${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expressionNames.putAll($ownerAuthExpressionNames))`)),
|
491 | graphql_mapping_template_1.iff(graphql_mapping_template_1.ref('ownerAuthExpressionValues'), graphql_mapping_template_1.raw(`$util.qr($${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expressionValues.putAll($ownerAuthExpressionValues))`)),
|
492 | graphql_mapping_template_1.comment('Set final expression if it has changed.'),
|
493 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw(`$totalAuthExpression != ""`), graphql_mapping_template_1.ifElse(graphql_mapping_template_1.raw(`$util.isNullOrEmpty($${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expression)`), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(`${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expression`), graphql_mapping_template_1.str(`($totalAuthExpression)`)), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(`${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expression`), graphql_mapping_template_1.str(`$${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthCondition}.expression AND ($totalAuthExpression)`)))),
|
494 | ]);
|
495 | }
|
496 | appendItemIfLocallyAuthorized() {
|
497 | return graphql_mapping_template_1.iff(graphql_mapping_template_1.parens(graphql_mapping_template_1.or([
|
498 | graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsLocalDynamicGroupAuthorizedVariable), graphql_mapping_template_1.raw('true')),
|
499 | graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsLocalOwnerAuthorizedVariable), graphql_mapping_template_1.raw('true')),
|
500 | ])), graphql_mapping_template_1.qref('$items.add($item)'));
|
501 | }
|
502 | setUserGroups(customGroup) {
|
503 | if (customGroup) {
|
504 | return graphql_mapping_template_1.compoundExpression([
|
505 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('userGroups'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${customGroup}"), [])`)),
|
506 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw('$util.isString($userGroups)'), graphql_mapping_template_1.ifElse(graphql_mapping_template_1.raw('$util.isList($util.parseJson($userGroups))'), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('userGroups'), graphql_mapping_template_1.raw('$util.parseJson($userGroups)')), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('userGroups'), graphql_mapping_template_1.raw('[$userGroups]')))),
|
507 | ]);
|
508 | }
|
509 | return graphql_mapping_template_1.set(graphql_mapping_template_1.ref('userGroups'), graphql_mapping_template_1.raw(`$util.defaultIfNull($ctx.identity.claims.get("${constants_1.DEFAULT_GROUP_CLAIM}"), [])`));
|
510 | }
|
511 | generateSubscriptionResolver(fieldName, subscriptionTypeName = 'Subscription') {
|
512 | return new cloudform_types_1.AppSync.Resolver({
|
513 | ApiId: cloudform_types_1.Fn.GetAtt(graphql_transformer_common_1.ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
|
514 | DataSourceName: 'NONE',
|
515 | FieldName: fieldName,
|
516 | TypeName: subscriptionTypeName,
|
517 | RequestMappingTemplate: graphql_mapping_template_1.print(graphql_mapping_template_1.raw(`{
|
518 | "version": "2018-05-29",
|
519 | "payload": {}
|
520 | }`)),
|
521 | ResponseMappingTemplate: graphql_mapping_template_1.print(graphql_mapping_template_1.raw(`$util.toJson(null)`)),
|
522 | });
|
523 | }
|
524 | operationCheckExpression(operation, field) {
|
525 | return graphql_mapping_template_1.block('Checking for allowed operations which can return this field', [
|
526 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('operation'), graphql_mapping_template_1.raw('$util.defaultIfNull($context.source.operation, "null")')),
|
527 | graphql_mapping_template_1.ifElse(graphql_mapping_template_1.raw(`$operation == "${operation}"`), graphql_mapping_template_1.ref('util.toJson(null)'), graphql_mapping_template_1.ref(`util.toJson($context.source.${field})`)),
|
528 | ]);
|
529 | }
|
530 | setOperationExpression(operation) {
|
531 | return graphql_mapping_template_1.print(graphql_mapping_template_1.block('Setting the operation', [graphql_mapping_template_1.set(graphql_mapping_template_1.ref('context.result.operation'), graphql_mapping_template_1.str(operation))]));
|
532 | }
|
533 | getAuthModeCheckWrappedExpression(expectedAuthModes, expression) {
|
534 | if (!expectedAuthModes || expectedAuthModes.size === 0) {
|
535 | return expression;
|
536 | }
|
537 | const conditions = [];
|
538 | for (const expectedAuthMode of expectedAuthModes) {
|
539 | conditions.push(graphql_mapping_template_1.equals(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthMode), graphql_mapping_template_1.str(`${expectedAuthMode}`)));
|
540 | }
|
541 | return graphql_mapping_template_1.block('Check authMode and execute owner/group checks', [
|
542 | graphql_mapping_template_1.iff(conditions.length === 1 ? conditions[0] : graphql_mapping_template_1.or(conditions), expression),
|
543 | ]);
|
544 | }
|
545 | getAuthModeDeterminationExpression(authProviders, isUserPoolTheDefault) {
|
546 | if (!authProviders || authProviders.size === 0) {
|
547 | return graphql_mapping_template_1.comment(`No authentication mode determination needed`);
|
548 | }
|
549 | const expressions = [];
|
550 | for (const authProvider of authProviders) {
|
551 | if (authProvider === 'userPools') {
|
552 | const statements = [
|
553 | graphql_mapping_template_1.raw(`$util.isNullOrEmpty($${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthMode})`),
|
554 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity)`)),
|
555 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.sub)`)),
|
556 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.issuer)`)),
|
557 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.username)`)),
|
558 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.claims)`)),
|
559 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.sourceIp)`)),
|
560 | ];
|
561 | if (isUserPoolTheDefault === true) {
|
562 | statements.push(graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.defaultAuthStrategy)`)));
|
563 | }
|
564 | const userPoolsExpression = graphql_mapping_template_1.iff(graphql_mapping_template_1.and(statements), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthMode), graphql_mapping_template_1.str(`userPools`)));
|
565 | expressions.push(userPoolsExpression);
|
566 | }
|
567 | else if (authProvider === 'oidc') {
|
568 | const oidcExpression = graphql_mapping_template_1.iff(graphql_mapping_template_1.and([
|
569 | graphql_mapping_template_1.raw(`$util.isNullOrEmpty($${graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthMode})`),
|
570 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity)`)),
|
571 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.sub)`)),
|
572 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.issuer)`)),
|
573 | graphql_mapping_template_1.not(graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.claims)`)),
|
574 | graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.username)`),
|
575 | graphql_mapping_template_1.raw(`$util.isNull($ctx.identity.sourceIp)`),
|
576 | ]), graphql_mapping_template_1.set(graphql_mapping_template_1.ref(graphql_transformer_common_1.ResourceConstants.SNIPPETS.AuthMode), graphql_mapping_template_1.str(`oidc`)));
|
577 | if (expressions.length > 0) {
|
578 | expressions.push(graphql_mapping_template_1.newline());
|
579 | }
|
580 | expressions.push(oidcExpression);
|
581 | }
|
582 | }
|
583 | return graphql_mapping_template_1.block('Determine request authentication mode', expressions);
|
584 | }
|
585 | getStaticAuthorizationVariable(field) {
|
586 | return field
|
587 | ? `${field.name.value}_${graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsStaticGroupAuthorizedVariable}`
|
588 | : graphql_transformer_common_1.ResourceConstants.SNIPPETS.IsStaticGroupAuthorizedVariable;
|
589 | }
|
590 | makeIAMPolicyForRole(isAuthPolicy, resources) {
|
591 | const policies = new Array();
|
592 | const authPiece = isAuthPolicy ? 'auth' : 'unauth';
|
593 | let policyResources = [];
|
594 | let resourceSize = 0;
|
595 | const MAX_BUILT_SIZE_BYTES = 6000;
|
596 | const RESOURCE_OVERHEAD = 100;
|
597 | const createPolicy = newPolicyResources => new cloudform_types_1.IAM.ManagedPolicy({
|
598 | Roles: [
|
599 | { Ref: `${authPiece}RoleName` },
|
600 | ],
|
601 | PolicyDocument: {
|
602 | Version: '2012-10-17',
|
603 | Statement: [
|
604 | {
|
605 | Effect: 'Allow',
|
606 | Action: ['appsync:GraphQL'],
|
607 | Resource: newPolicyResources,
|
608 | },
|
609 | ],
|
610 | },
|
611 | });
|
612 | for (const resource of resources) {
|
613 | const resourceParts = resource.split('/');
|
614 | if (resourceParts[1] !== 'null') {
|
615 | policyResources.push(cloudform_types_1.Fn.Sub('arn:aws:appsync:${AWS::Region}:${AWS::AccountId}:apis/${apiId}/types/${typeName}/fields/${fieldName}', {
|
616 | apiId: {
|
617 | 'Fn::GetAtt': ['GraphQLAPI', 'ApiId'],
|
618 | },
|
619 | typeName: resourceParts[0],
|
620 | fieldName: resourceParts[1],
|
621 | }));
|
622 | resourceSize += RESOURCE_OVERHEAD + resourceParts[0].length + resourceParts[1].length;
|
623 | }
|
624 | else {
|
625 | policyResources.push(cloudform_types_1.Fn.Sub('arn:aws:appsync:${AWS::Region}:${AWS::AccountId}:apis/${apiId}/types/${typeName}/*', {
|
626 | apiId: {
|
627 | 'Fn::GetAtt': ['GraphQLAPI', 'ApiId'],
|
628 | },
|
629 | typeName: resourceParts[0],
|
630 | }));
|
631 | resourceSize += RESOURCE_OVERHEAD + resourceParts[0].length;
|
632 | }
|
633 | if (resourceSize > MAX_BUILT_SIZE_BYTES) {
|
634 | const policy = createPolicy(policyResources.slice(0, policyResources.length - 1));
|
635 | policies.push(policy);
|
636 | policyResources = policyResources.slice(-1);
|
637 | resourceSize = 0;
|
638 | }
|
639 | }
|
640 | if (policyResources.length > 0) {
|
641 | const policy = createPolicy(policyResources);
|
642 | policies.push(policy);
|
643 | }
|
644 | return policies;
|
645 | }
|
646 | makeESItemsExpression(includeVersion) {
|
647 | return graphql_mapping_template_1.compoundExpression([
|
648 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('es_items'), graphql_mapping_template_1.list([])),
|
649 | graphql_mapping_template_1.forEach(graphql_mapping_template_1.ref('entry'), graphql_mapping_template_1.ref('context.result.hits.hits'), [
|
650 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw('!$foreach.hasNext'), graphql_mapping_template_1.set(graphql_mapping_template_1.ref('nextToken'), graphql_mapping_template_1.ref('entry.sort.get(0)'))),
|
651 | ...this.getSourceMapper(includeVersion),
|
652 | ]),
|
653 | ]);
|
654 | }
|
655 | makeESToGQLExpression() {
|
656 | return graphql_mapping_template_1.compoundExpression([
|
657 | graphql_mapping_template_1.set(graphql_mapping_template_1.ref('es_response'), graphql_mapping_template_1.obj({
|
658 | items: graphql_mapping_template_1.ref('es_items'),
|
659 | })),
|
660 | graphql_mapping_template_1.iff(graphql_mapping_template_1.raw('$es_items.size() > 0'), graphql_mapping_template_1.compoundExpression([graphql_mapping_template_1.qref('$es_response.put("nextToken", $nextToken)'), graphql_mapping_template_1.qref('$es_response.put("total", $es_items.size())')])),
|
661 | graphql_mapping_template_1.toJson(graphql_mapping_template_1.ref('es_response')),
|
662 | ]);
|
663 | }
|
664 | }
|
665 | exports.ResourceFactory = ResourceFactory;
|
666 |
|
\ | No newline at end of file |