forked from aws-amplify/amplify-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
394 additions
and
1 deletion.
There are no files selected for viewing
109 changes: 109 additions & 0 deletions
109
...tests__/provider-utils/awscloudformation/utils/generate-cognito-app-client-secret.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { $TSContext, stateManager, pathManager, AmplifyFault } from '@aws-amplify/amplify-cli-core'; | ||
import { updateAppClientWithGeneratedSecret } from '../../../../provider-utils/awscloudformation/utils/generate-cognito-app-client-secret'; | ||
import { projectHasAuth } from '../../../../provider-utils/awscloudformation/utils/project-has-auth'; | ||
import { getAuthResourceName } from '../../../../utils/getAuthResourceName'; | ||
import { getAppClientSecret } from '../../../../provider-utils/awscloudformation/utils/get-app-client-secret-sdk'; | ||
|
||
jest.mock('@aws-amplify/amplify-cli-core'); | ||
jest.mock('../../../../provider-utils/awscloudformation/utils/project-has-auth'); | ||
jest.mock('../../../../utils/getAuthResourceName'); | ||
jest.mock('../../../../provider-utils/awscloudformation/utils/get-app-client-secret-sdk'); | ||
|
||
const stateManagerMock = stateManager as jest.Mocked<typeof stateManager>; | ||
const pathManagerMock = pathManager as jest.Mocked<typeof pathManager>; | ||
const AmplifyFaultMock = AmplifyFault as jest.MockedClass<typeof AmplifyFault>; | ||
const projectHasAuthMock = projectHasAuth as jest.MockedFunction<typeof projectHasAuth>; | ||
const getAuthResourceNameMock = getAuthResourceName as jest.MockedFunction<typeof getAuthResourceName>; | ||
const getAppClientSecretMock = getAppClientSecret as jest.MockedFunction<typeof getAppClientSecret>; | ||
|
||
pathManagerMock.getBackendDirPath.mockReturnValue('mockBackendPath'); | ||
projectHasAuthMock.mockReturnValue(true); | ||
getAuthResourceNameMock.mockResolvedValue('mockResource'); | ||
const contextStub = { | ||
amplify: { | ||
getImportedAuthProperties: jest.fn().mockResolvedValue({ imported: false }), | ||
updateamplifyMetaAfterResourceUpdate: jest.fn(), | ||
}, | ||
}; | ||
describe('test auth trigger stack Parameters', () => { | ||
it('test case 1 - appClientSecret doesnt get updated when sdk returns undefined ', async () => { | ||
jest.clearAllMocks(); | ||
stateManagerMock.getMeta.mockReturnValue({ | ||
auth: { | ||
mockResource: { | ||
output: { | ||
AppClientID: 'mockClientId', | ||
UserPoolId: 'mockUserpoolId', | ||
}, | ||
}, | ||
}, | ||
}); | ||
getAppClientSecretMock.mockResolvedValue(undefined); | ||
await updateAppClientWithGeneratedSecret(contextStub as unknown as $TSContext); | ||
expect(contextStub.amplify.updateamplifyMetaAfterResourceUpdate.mock.calls).toMatchInlineSnapshot(`[]`); | ||
}); | ||
|
||
it('test case 2 - appClientSecret updates successfully ', async () => { | ||
jest.clearAllMocks(); | ||
stateManagerMock.getMeta.mockReturnValue({ | ||
auth: { | ||
mockResource: { | ||
output: { | ||
AppClientID: 'mockClientId', | ||
UserPoolId: 'mockUserpoolId', | ||
AmazonWebClient: 'mockAmazonWebClient', | ||
FacebookWebClient: 'mockFacebookWebClient', | ||
GoogleWebClient: 'mockGoogleWebClient', | ||
AppleWebClient: 'mockAppleWebClient', | ||
HostedUIDomain: 'mockHostedUIDomain', | ||
OAuthMetadata: 'mockOAuthMetadata', | ||
}, | ||
}, | ||
}, | ||
}); | ||
getAppClientSecretMock.mockResolvedValue('mockAppClientSecret'); | ||
await updateAppClientWithGeneratedSecret(contextStub as unknown as $TSContext); | ||
expect(contextStub.amplify.updateamplifyMetaAfterResourceUpdate.mock.calls).toMatchInlineSnapshot(` | ||
[ | ||
[ | ||
"auth", | ||
"mockResource", | ||
"output", | ||
{ | ||
"AmazonWebClient": "mockAmazonWebClient", | ||
"AppClientID": "mockClientId", | ||
"AppClientSecret": "mockAppClientSecret", | ||
"AppleWebClient": "mockAppleWebClient", | ||
"FacebookWebClient": "mockFacebookWebClient", | ||
"GoogleWebClient": "mockGoogleWebClient", | ||
"HostedUIDomain": "mockHostedUIDomain", | ||
"OAuthMetadata": "mockOAuthMetadata", | ||
"UserPoolId": "mockUserpoolId", | ||
}, | ||
], | ||
] | ||
`); | ||
}); | ||
|
||
it('test case 3 - throws error when getAppClientSecret call fails ', async () => { | ||
jest.clearAllMocks(); | ||
stateManagerMock.getMeta.mockReturnValue({ | ||
auth: { | ||
mockResource: { | ||
output: { | ||
AppClientID: 'mockClientId', | ||
UserPoolId: 'mockUserpoolId', | ||
}, | ||
}, | ||
}, | ||
}); | ||
getAppClientSecretMock.mockRejectedValue('error fetching app client secret'); | ||
try { | ||
await updateAppClientWithGeneratedSecret(contextStub as unknown as $TSContext); | ||
} catch (err) { | ||
console.log(err); | ||
expect(err).toMatchInlineSnapshot(`"error fetching app client secret"`); | ||
expect(contextStub.amplify.updateamplifyMetaAfterResourceUpdate.mock.calls).toMatchInlineSnapshot(`[]`); | ||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...ory-auth/src/provider-utils/awscloudformation/utils/generate-cognito-app-client-secret.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { $TSContext, AmplifyCategories, stateManager } from '@aws-amplify/amplify-cli-core'; | ||
import { getAuthResourceName } from '../../../utils/getAuthResourceName'; | ||
import { MetaOutput } from '../import/types'; | ||
import { getAppClientSecret } from './get-app-client-secret-sdk'; | ||
import { projectHasAuth } from './project-has-auth'; | ||
|
||
/** | ||
* | ||
* updates app client secret if user pool exists and userpoolClientGenerateSecret is set to true | ||
*/ | ||
export const updateAppClientWithGeneratedSecret = async (context: $TSContext): Promise<void> => { | ||
if (projectHasAuth()) { | ||
// check if its imported auth | ||
const { imported } = context.amplify.getImportedAuthProperties(context); | ||
if (!imported) { | ||
const authResourceName = await getAuthResourceName(context); | ||
const authMetaOutput: MetaOutput = stateManager.getMeta()?.auth[authResourceName]?.output; | ||
const clientId = authMetaOutput.AppClientID; | ||
const userpoolId = authMetaOutput.UserPoolId; | ||
// no else case required as userpool client is default created with userPool when created through amplify | ||
if (clientId && userpoolId) { | ||
const appClientSecret = await getAppClientSecret(context, userpoolId, clientId); | ||
if (appClientSecret) { | ||
authMetaOutput.AppClientSecret = appClientSecret; | ||
await context.amplify.updateamplifyMetaAfterResourceUpdate(AmplifyCategories.AUTH, authResourceName, 'output', authMetaOutput); | ||
} | ||
} | ||
} | ||
} | ||
}; |
33 changes: 33 additions & 0 deletions
33
...ify-category-auth/src/provider-utils/awscloudformation/utils/get-app-client-secret-sdk.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { $TSContext, AmplifyFault } from '@aws-amplify/amplify-cli-core'; | ||
import { CognitoIdentityServiceProvider } from 'aws-sdk'; | ||
|
||
export const getAppClientSecret = async (context: $TSContext, userpoolId: string, clientId: string): Promise<string | undefined> => { | ||
try { | ||
const identity = await getCognitoIdentityProviderClient(context); | ||
const params = { | ||
ClientId: clientId, | ||
UserPoolId: userpoolId, | ||
}; | ||
const result = await identity.describeUserPoolClient(params).promise(); | ||
return result.UserPoolClient?.ClientSecret; | ||
} catch (error) { | ||
throw new AmplifyFault( | ||
'ServiceCallFault', | ||
{ | ||
message: error.message, | ||
}, | ||
error, | ||
); | ||
} | ||
}; | ||
|
||
const getCognitoIdentityProviderClient = async (context: $TSContext): Promise<CognitoIdentityServiceProvider> => { | ||
const { client } = await context.amplify.invokePluginMethod<{ client: CognitoIdentityServiceProvider }>( | ||
context, | ||
'awscloudformation', | ||
undefined, | ||
'getConfiguredCognitoIdentityProviderClient', | ||
[context], | ||
); | ||
return client; | ||
}; |
99 changes: 99 additions & 0 deletions
99
packages/amplify-e2e-tests/src/__tests__/auth/hosted-ui.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { | ||
addAuthWithDefault, | ||
addAuthWithSignInSignOutUrl, | ||
amplifyPushAuth, | ||
createNewProjectDir, | ||
deleteProject, | ||
deleteProjectDir, | ||
getProjectMeta, | ||
getUserPool, | ||
initJSProjectWithProfile, | ||
updateAuthSignInSignOutUrlWithAll, | ||
} from '@aws-amplify/amplify-e2e-core'; | ||
|
||
const defaultsSettings = { | ||
name: 'authTest', | ||
}; | ||
|
||
const oauthSettings = { | ||
signinUrl: 'https://danielle.lol/', | ||
signoutUrl: 'https://danielle.lol/', | ||
}; | ||
|
||
describe('hosted ui tests', () => { | ||
let projRoot: string; | ||
|
||
beforeEach(async () => { | ||
projRoot = await createNewProjectDir('auth'); | ||
}); | ||
|
||
afterEach(async () => { | ||
await deleteProject(projRoot); | ||
deleteProjectDir(projRoot); | ||
}); | ||
|
||
describe('...amplify add auth', () => { | ||
describe('...creating with oauth', () => { | ||
it('...creates a user pool domain', async () => { | ||
await initJSProjectWithProfile(projRoot, defaultsSettings); | ||
await addAuthWithSignInSignOutUrl(projRoot, oauthSettings); | ||
await amplifyPushAuth(projRoot); | ||
|
||
const meta = getProjectMeta(projRoot); | ||
const region = meta.providers.awscloudformation.Region; | ||
const { HostedUIDomain, UserPoolId } = Object.keys(meta.auth) | ||
.map((key) => meta.auth[key]) | ||
.find((auth) => auth.service === 'Cognito').output; | ||
|
||
const userPoolRes = await getUserPool(UserPoolId, region); | ||
|
||
expect(HostedUIDomain).toBeDefined(); | ||
expect(HostedUIDomain).toEqual(userPoolRes.UserPool.Domain); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('amplify update auth', () => { | ||
describe('...updating to add oauth', () => { | ||
it('...creates a user pool domain', async () => { | ||
await initJSProjectWithProfile(projRoot, defaultsSettings); | ||
await addAuthWithDefault(projRoot); | ||
await updateAuthSignInSignOutUrlWithAll(projRoot, oauthSettings); | ||
await amplifyPushAuth(projRoot); | ||
|
||
const meta = getProjectMeta(projRoot); | ||
const region = meta.providers.awscloudformation.Region; | ||
const { HostedUIDomain, UserPoolId } = Object.keys(meta.auth) | ||
.map((key) => meta.auth[key]) | ||
.find((auth) => auth.service === 'Cognito').output; | ||
|
||
const userPoolRes = await getUserPool(UserPoolId, region); | ||
|
||
expect(HostedUIDomain).toBeDefined(); | ||
expect(HostedUIDomain).toEqual(userPoolRes.UserPool.Domain); | ||
}); | ||
}); | ||
|
||
describe('...updating to add oauth after push', () => { | ||
it('...creates a user pool domain', async () => { | ||
await initJSProjectWithProfile(projRoot, defaultsSettings); | ||
await addAuthWithDefault(projRoot); | ||
await amplifyPushAuth(projRoot); | ||
|
||
await updateAuthSignInSignOutUrlWithAll(projRoot, oauthSettings); | ||
await amplifyPushAuth(projRoot); | ||
|
||
const meta = getProjectMeta(projRoot); | ||
const region = meta.providers.awscloudformation.Region; | ||
const { HostedUIDomain, UserPoolId } = Object.keys(meta.auth) | ||
.map((key) => meta.auth[key]) | ||
.find((auth) => auth.service === 'Cognito').output; | ||
|
||
const userPoolRes = await getUserPool(UserPoolId, region); | ||
|
||
expect(HostedUIDomain).toBeDefined(); | ||
expect(HostedUIDomain).toEqual(userPoolRes.UserPool.Domain); | ||
}); | ||
}); | ||
}); | ||
}); |
106 changes: 106 additions & 0 deletions
106
packages/amplify-e2e-tests/src/__tests__/auth/user-groups.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { | ||
addAuthWithDefault, | ||
addAuthWithGroups, | ||
amplifyPushAuth, | ||
createNewProjectDir, | ||
deleteProject, | ||
deleteProjectDir, | ||
getIdentityPoolRoles, | ||
getProjectMeta, | ||
initJSProjectWithProfile, | ||
updateAuthAddUserGroups, | ||
} from '@aws-amplify/amplify-e2e-core'; | ||
|
||
const defaultsSettings = { | ||
name: 'authTest', | ||
}; | ||
|
||
describe('user group tests', () => { | ||
let projRoot: string; | ||
|
||
beforeEach(async () => { | ||
projRoot = await createNewProjectDir('auth'); | ||
}); | ||
|
||
afterEach(async () => { | ||
await deleteProject(projRoot); | ||
deleteProjectDir(projRoot); | ||
}); | ||
|
||
describe('...amplify add auth', () => { | ||
describe('...creating with a user pool group', () => { | ||
it('...assigns authenticated roles for users added to user group', async () => { | ||
await initJSProjectWithProfile(projRoot, defaultsSettings); | ||
await addAuthWithGroups(projRoot); | ||
await amplifyPushAuth(projRoot); | ||
|
||
const meta = getProjectMeta(projRoot); | ||
const region = meta.providers.awscloudformation.Region; | ||
const { AppClientID, AppClientIDWeb, IdentityPoolId, UserPoolId } = Object.keys(meta.auth) | ||
.map((key) => meta.auth[key]) | ||
.find((auth) => auth.service === 'Cognito').output; | ||
|
||
const identityPoolRoles = await getIdentityPoolRoles(IdentityPoolId, region); | ||
const roleMapKeyClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientID}`; | ||
const roleMapKeyWebClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientIDWeb}`; | ||
|
||
expect(identityPoolRoles.RoleMappings[roleMapKeyClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyClientId].Type).toEqual('Token'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyWebClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyWebClientId].Type).toEqual('Token'); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('...amplify update auth', () => { | ||
describe('...updating to add a user pool group', () => { | ||
it('...assigns authenticated roles for users added to user group', async () => { | ||
await initJSProjectWithProfile(projRoot, defaultsSettings); | ||
await addAuthWithDefault(projRoot); | ||
await amplifyPushAuth(projRoot); | ||
|
||
await updateAuthAddUserGroups(projRoot, ['mygroup']); | ||
await amplifyPushAuth(projRoot); | ||
|
||
const meta = getProjectMeta(projRoot); | ||
const region = meta.providers.awscloudformation.Region; | ||
const { AppClientID, AppClientIDWeb, IdentityPoolId, UserPoolId } = Object.keys(meta.auth) | ||
.map((key) => meta.auth[key]) | ||
.find((auth) => auth.service === 'Cognito').output; | ||
|
||
const identityPoolRoles = await getIdentityPoolRoles(IdentityPoolId, region); | ||
const roleMapKeyClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientID}`; | ||
const roleMapKeyWebClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientIDWeb}`; | ||
|
||
expect(identityPoolRoles.RoleMappings[roleMapKeyClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyClientId].Type).toEqual('Token'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyWebClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyWebClientId].Type).toEqual('Token'); | ||
}); | ||
}); | ||
|
||
describe('...updating to add a user pool group after create', () => { | ||
it('...assigns authenticated roles for users added to user group', async () => { | ||
await initJSProjectWithProfile(projRoot, defaultsSettings); | ||
await addAuthWithDefault(projRoot); | ||
await updateAuthAddUserGroups(projRoot, ['mygroup']); | ||
await amplifyPushAuth(projRoot); | ||
|
||
const meta = getProjectMeta(projRoot); | ||
const region = meta.providers.awscloudformation.Region; | ||
const { AppClientID, AppClientIDWeb, IdentityPoolId, UserPoolId } = Object.keys(meta.auth) | ||
.map((key) => meta.auth[key]) | ||
.find((auth) => auth.service === 'Cognito').output; | ||
|
||
const identityPoolRoles = await getIdentityPoolRoles(IdentityPoolId, region); | ||
const roleMapKeyClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientID}`; | ||
const roleMapKeyWebClientId = `cognito-idp.${region}.amazonaws.com/${UserPoolId}:${AppClientIDWeb}`; | ||
|
||
expect(identityPoolRoles.RoleMappings[roleMapKeyClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyClientId].Type).toEqual('Token'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyWebClientId].AmbiguousRoleResolution).toEqual('AuthenticatedRole'); | ||
expect(identityPoolRoles.RoleMappings[roleMapKeyWebClientId].Type).toEqual('Token'); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.