Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(fix) Call Auth migration from S3 migration for all auth resources in S3 #8511

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions packages/amplify-category-auth/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ const {
} = require('./provider-utils/awscloudformation/utils/auth-sms-workflow-helper');
const { AuthInputState } = require('./provider-utils/awscloudformation/auth-inputs-manager/auth-input-state');
const { printer } = require('amplify-prompts');
const { checkAuthResourceMigration } = require('./provider-utils/awscloudformation/utils/migrate-override-resource');
const { privateKeys } = require('./provider-utils/awscloudformation/constants');
const { checkAuthResourceMigration } = require('./provider-utils/awscloudformation/utils/check-for-auth-migration');

// this function is being kept for temporary compatability.
async function add(context) {
Expand Down Expand Up @@ -82,6 +82,10 @@ function canResourceBeTransformed(resourceName) {
return resourceInputState.cliInputFileExists();
}

async function migrateAuthResource( context, resourceName ){
await checkAuthResourceMigration( context, resourceName );
}

async function externalAuthEnable(context, externalCategory, resourceName, requirements) {
const { amplify } = context;
const serviceMetadata = getSupportedServices.supportedServices;
Expand All @@ -103,7 +107,7 @@ async function externalAuthEnable(context, externalCategory, resourceName, requi
}
currentAuthName = await getAuthResourceName(context);
// check for migration when auth has been enabled
checkAuthResourceMigration(context, currentAuthName);
await checkAuthResourceMigration(context, currentAuthName);
const cliState = new AuthInputState(currentAuthName);
currentAuthParams = await cliState.loadResourceParameters(context, cliState.getCLIInputPayload());

Expand Down Expand Up @@ -496,6 +500,7 @@ async function isSMSWorkflowEnabled(context, resourceName) {

module.exports = {
externalAuthEnable,
migrateAuthResource,
checkRequirements,
add,
migrate,
Expand All @@ -517,4 +522,5 @@ module.exports = {
AmplifyUserPoolGroupTransform,
transformCategoryStack,
AmplifyAuthCognitoStackTemplate,

};
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import {
S3TriggerFunctionType,
S3UserInputs,
} from '../../../../provider-utils/awscloudformation/service-walkthrough-types/s3-user-input-types';
import * as s3AuthAPI from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-auth-api';
import { S3CLITriggerUpdateMenuOptions, UserPermissionTypeOptions } from '../../../../provider-utils/awscloudformation/service-walkthroughs/s3-questions';

jest.mock('amplify-cli-core');
jest.mock('amplify-prompts');
jest.mock('../../../../provider-utils/awscloudformation/service-walkthroughs/s3-user-input-state');
jest.mock('../../../../provider-utils/awscloudformation/cdk-stack-builder/s3-stack-transform');
jest.mock('../../../../provider-utils/awscloudformation/service-walkthroughs/s3-auth-api');
jest.mock('uuid');

describe('add s3 walkthrough tests', () => {
Expand Down Expand Up @@ -61,6 +63,9 @@ describe('add s3 walkthrough tests', () => {
it('addWalkthrough() simple-auth test', async () => {
jest.spyOn(S3InputState.prototype, 'saveCliInputPayload').mockImplementation(() => true);
jest.spyOn(AmplifyS3ResourceStackTransform.prototype, 'transform').mockImplementation(() => Promise.resolve());
jest.spyOn(s3AuthAPI, 'migrateAuthDependencyResource').mockReturnValue(new Promise((resolve, _reject)=>{
process.nextTick(() => resolve(undefined));
}));

const mockDataBuilder = new S3MockDataBuilder(undefined);
const expectedCLIInputsJSON: S3UserInputs = mockDataBuilder.getCLIInputs();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ export const run = async (context: $TSContext) => {
}
} else if (amplifyMeta[categoryName][selectedResourceName].service === AmplifySupportedService.S3 ) {
// S3 migration logic goes in here
const resourceInputState = new S3InputState(selectedResourceName, undefined);
if (!resourceInputState.cliInputFileExists()) {
const s3ResourceInputState = new S3InputState(selectedResourceName, undefined);
if (!s3ResourceInputState.cliInputFileExists()) {
if (await prompter.yesOrNo('File migration required to continue. Do you want to continue?', true)) {
resourceInputState.migrate();
await s3ResourceInputState.migrate(context); //migrate auth and storage config resources
const stackGenerator = new AmplifyS3ResourceStackTransform(selectedResourceName, context);
stackGenerator.transform( CLISubCommandType.MIGRATE );
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { $TSAny, $TSContext } from "amplify-cli-core";
import { S3UserInputs } from "../service-walkthrough-types/s3-user-input-types";
import { S3InputState } from "./s3-user-input-state";
import { $TSAny, $TSContext} from "amplify-cli-core";
import { printer } from "amplify-prompts";
import { AmplifyCategories } from "amplify-cli-core";

/* This file contains all functions interacting with AUTH category */

//UPSTREAM API: function to be called from Storage to fetch or update Auth resources

/**
* Get the name of the Auth resource used by S3
* @param context used to fetch all auth resources used by storage(S3)
* @returns Name of the auth resource used by S3
*/
export async function getAuthResourceARN( context : $TSContext ) : Promise<string> {
let authResources = (await context.amplify.getResourceStatus('auth')).allResources;
authResources = authResources.filter((resource: $TSAny) => resource.service === 'Cognito');
Expand All @@ -13,3 +19,19 @@ export async function getAuthResourceARN( context : $TSContext ) : Promise<stri
}
return authResources[0].resourceName as string;
}
/**
* Migrate all Auth resources used by Storage(S3) for Override feature.
* @param context - used to fetch auth resources and to migrate auth resources for override-feature.
*/
export async function migrateAuthDependencyResource( context : $TSContext ) {
const authResourceName = await getAuthResourceARN(context);
try {
await context.amplify.invokePluginMethod(context,
AmplifyCategories.AUTH, undefined,
'migrateAuthResource',
[context, authResourceName ]);
} catch (error) {
printer.error(error as string);
throw error;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { ResourceDoesNotExistError, ResourceAlreadyExistsError, $TSContext } from 'amplify-cli-core';
import { ResourceDoesNotExistError,
ResourceAlreadyExistsError,
$TSContext,
ConfigurationError} from 'amplify-cli-core';

import { printer } from 'amplify-prompts';

export async function printErrorNoResourcesToUpdate( context : $TSContext ){
Expand All @@ -12,3 +16,9 @@ export async function printErrorAlreadyCreated( context : $TSContext ){
printer.warn(errMessage);
await context.usageData.emitError(new ResourceAlreadyExistsError(errMessage));
}

export async function printErrorAuthResourceMigrationFailed( context : $TSContext ){
const errMessage = 'Auth migration has failed';
printer.warn(errMessage);
await context.usageData.emitError(new ConfigurationError(errMessage));
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { S3AccessType, S3PermissionType, S3UserInputs, GroupAccessType } from '../service-walkthrough-types/s3-user-input-types';
import { $TSObject, AmplifyCategories, AmplifySupportedService } from 'amplify-cli-core';
import { $TSContext, $TSObject, AmplifyCategories, AmplifySupportedService } from 'amplify-cli-core';
import { JSONUtilities, pathManager } from 'amplify-cli-core';
import { CLIInputSchemaValidator } from 'amplify-cli-core';
import * as fs from 'fs-extra';
import * as path from 'path';
import { buildShortUUID } from './s3-walkthrough';
import { migrateAuthDependencyResource } from './s3-auth-api';
import { printer } from "amplify-prompts";


type ResourcRefType = {
Expand Down Expand Up @@ -186,7 +188,13 @@ export class S3InputState {
}
}

public migrate(){
public async migrate(context : $TSContext ){
try {
await migrateAuthDependencyResource(context);
} catch( error ) {
printer.error(`Migration for Auth resource failed with error : ${error as string}`)
throw error;
}
const oldS3Params : MigrationParams = this.getOldS3ParamsForMigration();
const cliInputs : S3UserInputs = this.genInputParametersForMigration( oldS3Params );
this.saveCliInputPayload(cliInputs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ import {
askAndOpenFunctionEditor,
S3CLITriggerUpdateMenuOptions,
} from './s3-questions';
import { printErrorAlreadyCreated, printErrorNoResourcesToUpdate } from './s3-errors';
import { printErrorAlreadyCreated, printErrorAuthResourceMigrationFailed, printErrorNoResourcesToUpdate } from './s3-errors';
import { getAllDefaults } from '../default-values/s3-defaults';

import { migrateAuthDependencyResource } from './s3-auth-api';
module.exports = {
addWalkthrough /* Add walkthrough for S3 resource */,
updateWalkthrough /* Update walkthrough for S3 resource */,
migrate: migrateCategory /* Migrate function to migrate from non-cdk to cdk implementation */,
migrate: migrateStorageCategory /* Migrate function to migrate from non-cdk to cdk implementation */,
getIAMPolicies /* Utility function to get IAM policies - cloudformation from actions */,
};

Expand All @@ -53,6 +53,14 @@ export async function addWalkthrough(context: $TSContext, defaultValuesFilename:
const { amplify } = context;
const amplifyMeta = stateManager.getMeta();

//Migrate auth category if required
try {
await migrateAuthDependencyResource(context)
} catch ( error ){
await printErrorAuthResourceMigrationFailed(context);
exitOnNextTick(0);
}

//First ask customers to configure Auth on the S3 resource, invoke auth workflow
await askAndInvokeAuthWorkflow(context);
const resourceName = await getS3ResourceNameFromMeta(amplifyMeta);
Expand Down Expand Up @@ -109,7 +117,7 @@ export async function addWalkthrough(context: $TSContext, defaultValuesFilename:
* @param context
* @returns resourceName
*/
export async function updateWalkthrough(context: $TSAny) {
export async function updateWalkthrough(context: $TSContext) {
const amplifyMeta = stateManager.getMeta();
const resourceName: string | undefined = await getS3ResourceNameFromMeta(amplifyMeta);
if (resourceName === undefined) {
Expand All @@ -127,7 +135,8 @@ export async function updateWalkthrough(context: $TSAny) {
//Check if migration is required
if (!cliInputsState.cliInputFileExists()) {
if (context.exeInfo?.forcePush || (await prompter.confirmContinue('File migration required to continue. Do you want to continue?'))) {
cliInputsState.migrate();
//migrate auth and storage
await cliInputsState.migrate( context );
const stackGenerator = new AmplifyS3ResourceStackTransform(resourceName, context);
await stackGenerator.transform(CLISubCommandType.UPDATE); //generates cloudformation
} else {
Expand Down Expand Up @@ -182,11 +191,11 @@ export async function updateWalkthrough(context: $TSAny) {
* @param context
* @param resourceName
*/
export async function migrateCategory(context: $TSAny, resourceName: $TSAny): Promise<string | undefined> {
export async function migrateStorageCategory(context: $TSContext, resourceName: string): Promise<string | undefined> {
let cliInputsState = new S3InputState(resourceName, undefined);
//Check if migration is required
if (!cliInputsState.cliInputFileExists()) {
cliInputsState.migrate();
await cliInputsState.migrate( context );
const stackGenerator = new AmplifyS3ResourceStackTransform(resourceName, context);
await stackGenerator.transform(CLISubCommandType.MIGRATE);
return stackGenerator.getCFN();
Expand Down