"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateIAMAccessCheck = exports.generateFieldResolverForOwner = exports.setDeniedFieldFlag = exports.emptyPayload = exports.generateSandboxExpressionForField = exports.constructAuthorizedInputStatement = exports.constructAuthFilter = exports.validateAuthResult = exports.generateAuthRulesFromRoles = exports.generateDefaultRDSExpression = void 0;
const graphql_mapping_template_1 = require("graphql-mapping-template");
const graphql_model_transformer_1 = require("@aws-amplify/graphql-model-transformer");
const utils_1 = require("../../../utils");
const common_1 = require("../../common");
const generateDefaultRDSExpression = (iamAccessEnabled) => {
    const exp = (0, graphql_mapping_template_1.ref)('util.unauthorized()');
    return (0, graphql_mapping_template_1.printBlock)('Default RDS Auth Resolver')((0, exports.generateIAMAccessCheck)(iamAccessEnabled, (0, graphql_mapping_template_1.compoundExpression)([exp, (0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.obj)({}))])));
};
exports.generateDefaultRDSExpression = generateDefaultRDSExpression;
const generateAuthRulesFromRoles = (roles, fields, hasIdentityPoolId, hideAllowedFields = false) => {
    const expressions = [];
    expressions.push((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)('hasAuth'), (0, graphql_mapping_template_1.bool)(true))), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('authRules'), (0, graphql_mapping_template_1.list)([])));
    const fieldNames = fields.map((field) => field.name.value);
    expressions.push(getIamAdminRoleExpression());
    roles.forEach((role) => {
        expressions.push(convertAuthRoleToVtl(role, fieldNames, hasIdentityPoolId, hideAllowedFields));
    });
    return expressions;
};
exports.generateAuthRulesFromRoles = generateAuthRulesFromRoles;
const getIamAdminRoleExpression = () => (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.and)([(0, graphql_mapping_template_1.ref)('ctx.stash.adminRoles'), (0, graphql_mapping_template_1.ref)('ctx.stash.adminRoles.size() > 0')]), (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
    provider: (0, graphql_mapping_template_1.str)('iam'),
    type: (0, graphql_mapping_template_1.str)('admin'),
    strict: (0, graphql_mapping_template_1.bool)(false),
    roles: (0, graphql_mapping_template_1.ref)('ctx.stash.adminRoles'),
}))));
const convertAuthRoleToVtl = (role, fields, hasIdentityPoolId, hideAllowedFields = false) => {
    const allowedFields = getAllowedFields(role, fields).map((field) => (0, graphql_mapping_template_1.str)(field));
    const showAllowedFields = allowedFields && !hideAllowedFields && allowedFields.length > 0;
    if ((0, utils_1.isAuthProviderEqual)(role.provider, 'apiKey')) {
        return (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
            type: (0, graphql_mapping_template_1.str)('public'),
            provider: (0, graphql_mapping_template_1.str)('apiKey'),
            ...(showAllowedFields && { allowedFields: (0, graphql_mapping_template_1.list)(allowedFields) }),
        })));
    }
    else if ((0, utils_1.isAuthProviderEqual)(role.provider, 'function')) {
        return (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
            type: (0, graphql_mapping_template_1.str)('custom'),
            provider: (0, graphql_mapping_template_1.str)('function'),
            ...(showAllowedFields && { allowedFields: (0, graphql_mapping_template_1.list)(allowedFields) }),
        })));
    }
    else if ((0, utils_1.isAuthProviderEqual)(role.provider, 'identityPool')) {
        return (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
            type: (0, graphql_mapping_template_1.str)(role.strategy),
            provider: (0, graphql_mapping_template_1.str)('iam'),
            roleArn: role.strategy === 'public' ? (0, graphql_mapping_template_1.ref)('ctx.stash.unauthRole') : (0, graphql_mapping_template_1.ref)('ctx.stash.authRole'),
            ...(role.strategy === 'private' && { cognitoIdentityPoolId: hasIdentityPoolId ? (0, graphql_mapping_template_1.ref)('ctx.stash.identityPoolId') : (0, graphql_mapping_template_1.nul)() }),
            ...(showAllowedFields && { allowedFields: (0, graphql_mapping_template_1.list)(allowedFields) }),
        })));
    }
    else if ((0, utils_1.isAuthProviderEqual)(role.provider, 'userPools') || (0, utils_1.isAuthProviderEqual)(role.provider, 'oidc')) {
        if (role.strategy === 'private') {
            return (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
                type: (0, graphql_mapping_template_1.str)(role.strategy),
                provider: (0, graphql_mapping_template_1.str)(role.provider),
                ...(showAllowedFields && { allowedFields: (0, graphql_mapping_template_1.list)(allowedFields) }),
            })));
        }
        else if (role.strategy === 'groups' && role.static) {
            return (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
                type: (0, graphql_mapping_template_1.str)(role.strategy),
                provider: (0, graphql_mapping_template_1.str)(role.provider),
                allowedGroups: (0, graphql_mapping_template_1.list)([(0, graphql_mapping_template_1.str)(role.entity)]),
                groupClaim: (0, graphql_mapping_template_1.str)(role.claim),
                ...(showAllowedFields && { allowedFields: (0, graphql_mapping_template_1.list)(allowedFields) }),
            })));
        }
        else if (role.strategy === 'owner') {
            const usingCognitoDefaultClaim = role.claim === utils_1.DEFAULT_UNIQUE_IDENTITY_CLAIM && (0, utils_1.isAuthProviderEqual)(role.provider, 'userPools');
            return (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
                type: (0, graphql_mapping_template_1.str)(role.strategy),
                provider: (0, graphql_mapping_template_1.str)(role.provider),
                ownerFieldName: (0, graphql_mapping_template_1.str)(role.entity),
                ownerFieldType: (0, graphql_mapping_template_1.str)(role.isEntityList ? 'string[]' : 'string'),
                ...(!usingCognitoDefaultClaim && { identityClaim: (0, graphql_mapping_template_1.str)(role.claim) }),
                ...(showAllowedFields && { allowedFields: (0, graphql_mapping_template_1.list)(allowedFields) }),
            })));
        }
        else if (role.strategy === 'groups' && !role.static) {
            return (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('authRules.add'), (0, graphql_mapping_template_1.obj)({
                type: (0, graphql_mapping_template_1.str)(role.strategy),
                provider: (0, graphql_mapping_template_1.str)(role.provider),
                groupsFieldName: (0, graphql_mapping_template_1.str)(role.entity),
                groupsFieldType: (0, graphql_mapping_template_1.str)(role.isEntityList ? 'string[]' : 'string'),
                groupClaim: (0, graphql_mapping_template_1.str)(role.claim),
                ...(showAllowedFields && { allowedFields: (0, graphql_mapping_template_1.list)(allowedFields) }),
            })));
        }
    }
    throw new Error(`Invalid Auth Rule: Unable to process ${JSON.stringify(role)}`);
};
const getAllowedFields = (role, fields) => {
    if (role.allowedFields && role.allowedFields.length > 0) {
        return role.allowedFields;
    }
    return fields;
};
const validateAuthResult = () => {
    return (0, graphql_mapping_template_1.compoundExpression)([
        (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.or)([(0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.ref)('authResult')), (0, graphql_mapping_template_1.parens)((0, graphql_mapping_template_1.and)([(0, graphql_mapping_template_1.ref)('authResult'), (0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.ref)('authResult.authorized'))]))]), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.unauthorized'))),
    ]);
};
exports.validateAuthResult = validateAuthResult;
const constructAuthFilter = () => {
    return (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.and)([(0, graphql_mapping_template_1.ref)('authResult'), (0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.isNullOrEmpty'), (0, graphql_mapping_template_1.ref)('authResult.authFilter')))]), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ctx.stash.authFilter'), (0, graphql_mapping_template_1.ref)('authResult.authFilter')));
};
exports.constructAuthFilter = constructAuthFilter;
const constructAuthorizedInputStatement = (keyName) => (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.and)([(0, graphql_mapping_template_1.ref)('authResult'), (0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.isNullOrEmpty'), (0, graphql_mapping_template_1.ref)('authResult.authorizedInput')))]), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(keyName), (0, graphql_mapping_template_1.ref)('authResult.authorizedInput')));
exports.constructAuthorizedInputStatement = constructAuthorizedInputStatement;
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;
exports.emptyPayload = (0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.raw)(JSON.stringify({ version: '2018-05-29', payload: {} })));
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 generateFieldResolverForOwner = (entity) => {
    const expressions = [
        (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.ref)(`ctx.source.${entity}`)), (0, graphql_mapping_template_1.compoundExpression)([
            (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ownerEntitiesList'), (0, graphql_mapping_template_1.list)([])),
            (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(entity), (0, graphql_mapping_template_1.ref)(`ctx.source.${entity}`)),
            (0, graphql_mapping_template_1.forEach)((0, graphql_mapping_template_1.ref)('entities'), (0, graphql_mapping_template_1.ref)(entity), [
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ownerEntities'), (0, graphql_mapping_template_1.ref)(`entities.split("${utils_1.IDENTITY_CLAIM_DELIMITER}")`)),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ownerEntitiesLastIdx'), (0, graphql_mapping_template_1.raw)('$ownerEntities.size() - 1')),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ownerEntitiesLast'), (0, graphql_mapping_template_1.ref)('ownerEntities[$ownerEntitiesLastIdx]')),
                (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('ownerEntitiesList.add'), (0, graphql_mapping_template_1.ref)('ownerEntitiesLast'))),
            ]),
            (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)(`ctx.source.${entity}.put`), (0, graphql_mapping_template_1.ref)('ownerEntitiesList'))),
            (0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.ref)('ownerEntitiesList')),
        ]), (0, graphql_mapping_template_1.compoundExpression)([
            (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ownerEntities'), (0, graphql_mapping_template_1.ref)(`ctx.source.${entity}.split("${utils_1.IDENTITY_CLAIM_DELIMITER}")`)),
            (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ownerEntitiesLastIdx'), (0, graphql_mapping_template_1.raw)('$ownerEntities.size() - 1')),
            (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('ownerEntitiesLast'), (0, graphql_mapping_template_1.ref)('ownerEntities[$ownerEntitiesLastIdx]')),
            (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('ctx.source.put'), (0, graphql_mapping_template_1.str)(entity), (0, graphql_mapping_template_1.ref)('ownerEntitiesLast'))),
            (0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.ref)(`ctx.source.${entity}`)),
        ])),
    ];
    return (0, graphql_mapping_template_1.printBlock)('Parse owner field auth for Get')((0, graphql_mapping_template_1.compoundExpression)(expressions));
};
exports.generateFieldResolverForOwner = generateFieldResolverForOwner;
const generateIAMAccessCheck = (enableIamAccess, expression) => {
    if (!enableIamAccess) {
        return expression;
    }
    return (0, graphql_mapping_template_1.ifElse)(common_1.isNonCognitoIAMPrincipal, (0, graphql_mapping_template_1.compoundExpression)([common_1.setHasAuthExpression, exports.emptyPayload]), expression);
};
exports.generateIAMAccessCheck = generateIAMAccessCheck;
//# sourceMappingURL=common.js.map