"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateSandboxExpressionForField = exports.setDeniedFieldFlag = exports.generateFieldAuthResponse = exports.generateAuthExpressionForField = void 0;
const graphql_model_transformer_1 = require("@aws-amplify/graphql-model-transformer");
const graphql_mapping_template_1 = require("graphql-mapping-template");
const utils_1 = require("../../../utils");
const helpers_1 = require("./helpers");
const common_1 = require("../../common");
const generateDynamicAuthReadExpression = (roles, fields) => {
    const ownerExpressions = new Array();
    const dynamicGroupExpressions = new Array();
    roles.forEach((role, idx) => {
        const entityIsList = (0, utils_1.fieldIsList)(fields, role.entity);
        if (role.strategy === 'owner') {
            ownerExpressions.push((0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG)), (0, graphql_mapping_template_1.compoundExpression)([
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(`ownerEntity${idx}`), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.ref)(`ctx.source.${role.entity}`), (0, graphql_mapping_template_1.nul)())),
                (0, helpers_1.generateOwnerClaimExpression)(role.claim, `ownerClaim${idx}`),
                (0, graphql_mapping_template_1.iff)((0, helpers_1.generateInvalidClaimsCondition)(role.claim, `ownerClaim${idx}`), (0, graphql_mapping_template_1.compoundExpression)([
                    (0, helpers_1.generateOwnerMultiClaimExpression)(role.claim, `ownerClaim${idx}`),
                    (0, helpers_1.generateOwnerClaimListExpression)(role.claim, `ownerClaimsList${idx}`),
                    ...(entityIsList
                        ? [
                            (0, graphql_mapping_template_1.forEach)((0, graphql_mapping_template_1.ref)('allowedOwner'), (0, graphql_mapping_template_1.ref)(`ownerEntity${idx}`), [
                                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.or)([
                                    (0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.ref)('allowedOwner'), (0, graphql_mapping_template_1.ref)(`ownerClaim${idx}`)),
                                    (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)(`ownerClaimsList${idx}.contains`), (0, graphql_mapping_template_1.ref)('allowedOwner')),
                                ]), (0, graphql_mapping_template_1.compoundExpression)([(0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG), (0, graphql_mapping_template_1.bool)(true)), (0, graphql_mapping_template_1.raw)('#break')])),
                            ]),
                        ]
                        : [
                            (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.or)([
                                (0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.ref)(`ownerEntity${idx}`), (0, graphql_mapping_template_1.ref)(`ownerClaim${idx}`)),
                                (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)(`ownerClaimsList${idx}.contains`), (0, graphql_mapping_template_1.ref)(`ownerEntity${idx}`)),
                            ]), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG), (0, graphql_mapping_template_1.bool)(true))),
                        ]),
                ])),
            ])));
        }
        if (role.strategy === 'groups') {
            dynamicGroupExpressions.push((0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG)), (0, graphql_mapping_template_1.compoundExpression)([
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(`groupEntity${idx}`), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.ref)(`ctx.source.${role.entity}`), (0, graphql_mapping_template_1.nul)())),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(`groupClaim${idx}`), (0, helpers_1.getIdentityClaimExp)((0, graphql_mapping_template_1.str)(role.claim), (0, graphql_mapping_template_1.list)([]))),
                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.isString'), (0, graphql_mapping_template_1.ref)(`groupClaim${idx}`)), (0, graphql_mapping_template_1.ifElse)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.isList'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.parseJson'), (0, graphql_mapping_template_1.ref)(`groupClaim${idx}`))), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(`groupClaim${idx}`), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.parseJson'), (0, graphql_mapping_template_1.ref)(`groupClaim${idx}`))), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(`groupClaim${idx}`), (0, graphql_mapping_template_1.list)([(0, graphql_mapping_template_1.ref)(`groupClaim${idx}`)])))),
                entityIsList
                    ? (0, graphql_mapping_template_1.forEach)((0, graphql_mapping_template_1.ref)('userGroup'), (0, graphql_mapping_template_1.ref)(`groupClaim${idx}`), [
                        (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)(`groupEntity${idx}.contains`), (0, graphql_mapping_template_1.ref)('userGroup')), (0, graphql_mapping_template_1.compoundExpression)([(0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG), (0, graphql_mapping_template_1.bool)(true)), (0, graphql_mapping_template_1.raw)('#break')])),
                    ])
                    : (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.ref)(`groupClaim${idx}.contains($groupEntity${idx})`), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG), (0, graphql_mapping_template_1.bool)(true))),
            ])));
        }
    });
    return [...(ownerExpressions.length > 0 || dynamicGroupExpressions.length > 0 ? [...ownerExpressions, ...dynamicGroupExpressions] : [])];
};
const generateAuthExpressionForField = (providers, roles, fields, fieldName = undefined) => {
    const { cognitoStaticRoles, cognitoDynamicRoles, oidcStaticRoles, oidcDynamicRoles, iamRoles, apiKeyRoles, lambdaRoles } = (0, utils_1.splitRoles)(roles);
    const totalAuthExpressions = [(0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG), (0, graphql_mapping_template_1.bool)(false))];
    if (providers.hasApiKey) {
        totalAuthExpressions.push((0, helpers_1.apiKeyExpression)(apiKeyRoles));
    }
    if (providers.hasLambda) {
        totalAuthExpressions.push((0, helpers_1.lambdaExpression)(lambdaRoles));
    }
    if (providers.hasIAM) {
        totalAuthExpressions.push((0, helpers_1.iamExpression)({
            roles: iamRoles,
            adminRolesEnabled: providers.hasAdminRolesEnabled,
            hasIdentityPoolId: providers.hasIdentityPoolId,
            genericIamAccessEnabled: providers.genericIamAccessEnabled,
            fieldName,
        }));
    }
    if (providers.hasUserPools) {
        totalAuthExpressions.push((0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.ref)('util.authType()'), (0, graphql_mapping_template_1.str)(utils_1.COGNITO_AUTH_TYPE)), (0, graphql_mapping_template_1.compoundExpression)([
            ...(0, helpers_1.generateStaticRoleExpression)(cognitoStaticRoles),
            ...generateDynamicAuthReadExpression(cognitoDynamicRoles, fields),
        ])));
    }
    if (providers.hasOIDC) {
        totalAuthExpressions.push((0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.ref)('util.authType()'), (0, graphql_mapping_template_1.str)(utils_1.OIDC_AUTH_TYPE)), (0, graphql_mapping_template_1.compoundExpression)([
            ...(0, helpers_1.generateStaticRoleExpression)(oidcStaticRoles),
            ...generateDynamicAuthReadExpression(oidcDynamicRoles, fields),
        ])));
    }
    totalAuthExpressions.push((0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.ref)(utils_1.IS_AUTHORIZED_FLAG)), (0, graphql_mapping_template_1.ref)('util.unauthorized()')));
    return (0, graphql_mapping_template_1.printBlock)('Field Authorization Steps')((0, graphql_mapping_template_1.compoundExpression)([...totalAuthExpressions, helpers_1.emptyPayload]));
};
exports.generateAuthExpressionForField = generateAuthExpressionForField;
const generateFieldAuthResponse = (operation, fieldName, subscriptionsEnabled) => {
    if (subscriptionsEnabled) {
        return (0, graphql_mapping_template_1.printBlock)('Checking for allowed operations which can return this field')((0, graphql_mapping_template_1.compoundExpression)([
            (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('operation'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('ctx.source.get'), (0, graphql_mapping_template_1.str)(graphql_model_transformer_1.OPERATION_KEY)), (0, graphql_mapping_template_1.nul)())),
            (0, graphql_mapping_template_1.ifElse)((0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.ref)('operation'), (0, graphql_mapping_template_1.str)(operation)), (0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.nul)()), (0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.ref)(`context.source["${fieldName}"]`))),
        ]));
    }
    return (0, graphql_mapping_template_1.printBlock)('Return Source Field')((0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.ref)(`context.source["${fieldName}"]`)));
};
exports.generateFieldAuthResponse = generateFieldAuthResponse;
const setDeniedFieldFlag = (operation, subscriptionsEnabled) => {
    if (subscriptionsEnabled) {
        return (0, graphql_mapping_template_1.printBlock)('Check if subscriptions is protected')((0, graphql_mapping_template_1.compoundExpression)([
            (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('ctx.source.get'), (0, graphql_mapping_template_1.str)(graphql_model_transformer_1.OPERATION_KEY)), (0, graphql_mapping_template_1.nul)()), (0, graphql_mapping_template_1.str)(operation)), (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('ctx.stash.put'), (0, graphql_mapping_template_1.str)('deniedField'), (0, graphql_mapping_template_1.bool)(true)))),
        ]));
    }
    return '';
};
exports.setDeniedFieldFlag = setDeniedFieldFlag;
const generateSandboxExpressionForField = (sandboxEnabled, genericIamAccessEnabled) => {
    const expressions = [];
    if (sandboxEnabled) {
        expressions.push((0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.authType')), (0, graphql_mapping_template_1.str)(utils_1.API_KEY_AUTH_TYPE)), (0, graphql_mapping_template_1.ret)((0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.obj)({})))));
    }
    if (genericIamAccessEnabled) {
        expressions.push((0, graphql_mapping_template_1.iff)(common_1.isNonCognitoIAMPrincipal, (0, graphql_mapping_template_1.ret)((0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.obj)({})))));
    }
    expressions.push((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.unauthorized')));
    return (0, graphql_mapping_template_1.printBlock)(`Sandbox Mode ${sandboxEnabled ? 'Enabled' : 'Disabled'}`)((0, graphql_mapping_template_1.compoundExpression)(expressions));
};
exports.generateSandboxExpressionForField = generateSandboxExpressionForField;
//# sourceMappingURL=field.js.map