Skip to content

Commit

Permalink
More feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Niranjan Jayakar committed Jun 2, 2020
1 parent ee21d0e commit f2bba19
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 99 deletions.
68 changes: 42 additions & 26 deletions packages/@aws-cdk/aws-cognito/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aw
- [Emails](#emails)
- [Lambda Triggers](#lambda-triggers)
- [Import](#importing-user-pools)
- [App Clients](#app-clients)
- [Identity Providers](#identity-providers)
- [App Clients](#app-clients)
- [Domains](#domains)

## User Pools
Expand Down Expand Up @@ -335,6 +335,36 @@ const otherAwesomePool = UserPool.fromUserPoolArn(stack, 'other-awesome-user-poo
'arn:aws:cognito-idp:eu-west-1:123456789012:userpool/us-east-1_mtRyYQ14D');
```

### Identity Providers

Users that are part of a user pool can sign in either directly through a user pool, or federate through a third-party
identity provider. Once configured, the Cognito backend will take care of integrating with the third-party provider.
Read more about [Adding User Pool Sign-in Through a Third
Party](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-federation.html).

The following third-party identity providers are currentlhy supported in the CDK -

* [Login With Amazon](https://developer.amazon.com/apps-and-games/login-with-amazon)
* [Facebook Login](https://developers.facebook.com/docs/facebook-login/)

The following code configures a user pool to federate with the third party provider, 'Login with Amazon'. The identity
provider needs to be configured with a set of credentials that the Cognito backend can use to federate with the
third-party identity provider.

```ts
const userpool = new UserPool(stack, 'Pool');

const provider = new UserPoolIdentityProviderAmazon(stack, 'Amazon', {
clientId: 'amzn-client-id',
clientSecret: 'amzn-client-secret',
userPool: userpool,
});
```

In order to allow users to sign in with a third-party identity provider, the app client that faces the user should be
configured to use the identity provider. See [App Clients](#app-clients) section to know more about App Clients.
The identity providers should be configured on `identityProviders` property available on the `UserPoolClient` construct.

### App Clients

An app is an entity within a user pool that has permission to call unauthenticated APIs (APIs that do not have an
Expand Down Expand Up @@ -418,36 +448,22 @@ pool.addClient('app-client', {
});
```

### Identity Providers

Users that are part of a user pool can sign in either directly through a user pool, or federate through a third-party
identity provider. Once configured, the Cognito backend will take care of integrating with the third-party provider.
Read more about [Adding User Pool Sign-in Through a Third
Party](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-identity-federation.html).

The following third-party identity providers are currentlhy supported in the CDK -

* [Login With Amazon](https://developer.amazon.com/apps-and-games/login-with-amazon)
* [Facebook Login](https://developers.facebook.com/docs/facebook-login/)

The following code configures a user pool to federate with the third party provider, 'Login with Amazon'. The identity
provider needs to be configured with a set of credentials that the Cognito backend can use to federate with the
third-party identity provider.
All identity providers created in the CDK app are automatically registered into the corresponding user pool. All app
clients created in the CDK have all of the identity providers enabled by default. The 'Cognito' identity provider,
that allows users to register and sign in directly with the Cognito user pool, is also enabled by default.
Alternatively, the list of supported identity providers for a client can be explicitly specified -

```ts
const userpool = new UserPool(stack, 'Pool');

const provider = UserPoolIdentityProvider.amazon(stack, 'Amazon', {
clientId: 'amzn-client-id',
clientSecret: 'amzn-client-secret',
userPool: userpool,
const pool = new UserPool(this, 'Pool');
pool.addClient('app-client', {
// ...
supportedIdentityProviders: [
UserPoolClientIdentityProvider.AMAZON,
UserPoolClientIdentityProvider.COGNITO,
]
});
```

In order to allow users to sign in with a third-party identity provider, the app client that faces the user should be
configured to use the identity provider. See [App Clients](#app-clients) section to know more about App Clients.
The identity providers should be configured on `identityProviders` property available on the `UserPoolClient` construct.

### Domains

After setting up an [app client](#app-clients), the address for the user pool's sign-up and sign-in webpages can be
Expand Down
44 changes: 28 additions & 16 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,22 +148,38 @@ export class OAuthScope {
/**
* Identity providers supported by the UserPoolClient
*/
export interface SupportedIdentityProviders {
export class UserPoolClientIdentityProvider {
/**
* Whether users can sign in directly as a user of the User Pool.
* @default true
* Allow users to sign in using 'Facebook Login'.
* A `UserPoolIdentityProviderFacebook` must be attached to the user pool.
*/
readonly cognito?: boolean;
public static readonly FACEBOOK = new UserPoolClientIdentityProvider('Facebook');

/**
* Whether users can sign in using 'Facebook Login'.
* @default false
* Allow users to sign in using 'Login With Amazon'.
* A `UserPoolIdentityProviderAmazon` must be attached to the user pool.
*/
readonly facebook?: boolean;
public static readonly AMAZON = new UserPoolClientIdentityProvider('LoginWithAmazon');

/**
* Whether users can sign in using 'Login With Amazon'.
* @default false
* Allow users to sign in directly as a user of the User Pool
*/
public static readonly COGNITO = new UserPoolClientIdentityProvider('COGNITO');

/**
* Specify a provider not yet supported by the CDK.
* @param name name of the identity provider as recognized by CloudFormation property `SupportedIdentityProviders`
*/
readonly amazon?: boolean;
public static custom(name: string) {
return new UserPoolClientIdentityProvider(name);
}

/** The name of the identity provider as recognized by CloudFormation property `SupportedIdentityProviders` */
public readonly name: string;

private constructor(name: string) {
this.name = name;
}
}

/**
Expand Down Expand Up @@ -211,7 +227,7 @@ export interface UserPoolClientOptions {
* identity providers are imported, either specify this option explicitly or ensure that the identity providers are
* registered with the user pool using the `UserPool.registerIdentityProvider()` API.
*/
readonly supportedIdentityProviders?: SupportedIdentityProviders;
readonly supportedIdentityProviders?: UserPoolClientIdentityProvider[];
}

/**
Expand Down Expand Up @@ -364,11 +380,7 @@ export class UserPoolClient extends Resource implements IUserPoolClient {
providerSet.add('COGNITO');
providers = Array.from(providerSet);
} else {
providers = [];
const idps = props.supportedIdentityProviders;
if (idps.cognito === undefined || idps.cognito === true) { providers.push('COGNITO'); }
if (idps.facebook) { providers.push('Facebook'); }
if (idps.amazon) { providers.push('LoginWithAmazon'); }
providers = props.supportedIdentityProviders.map((p) => p.name);
}
if (providers.length === 0) { return undefined; }
return Array.from(providers);
Expand Down
20 changes: 0 additions & 20 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-idp.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import { Construct, IResource, Resource } from '@aws-cdk/core';
import {
UserPoolIdentityProviderAmazon,
UserPoolIdentityProviderAmazonProps,
UserPoolIdentityProviderFacebook,
UserPoolIdentityProviderFacebookProps,
} from './user-pool-idps';

/**
* Represents a UserPoolIdentityProvider
Expand Down Expand Up @@ -33,19 +27,5 @@ export class UserPoolIdentityProvider {
return new Import(scope, id);
}

/**
* Federate login with 'Login with Amazon'
*/
public static amazon(scope: Construct, id: string, props: UserPoolIdentityProviderAmazonProps) {
return new UserPoolIdentityProviderAmazon(scope, id, props);
}

/**
* Federate login with 'Facebook Login'
*/
public static facebook(scope: Construct, id: string, props: UserPoolIdentityProviderFacebookProps) {
return new UserPoolIdentityProviderFacebook(scope, id, props);
}

private constructor() {}
}
48 changes: 11 additions & 37 deletions packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ABSENT } from '@aws-cdk/assert';
import '@aws-cdk/assert/jest';
import { Stack } from '@aws-cdk/core';
import { OAuthScope, UserPool, UserPoolClient, UserPoolIdentityProviderAmazon, UserPoolIdentityProviderFacebook } from '../lib';
import { OAuthScope, UserPool, UserPoolClient, UserPoolClientIdentityProvider, UserPoolIdentityProvider } from '../lib';

describe('User Pool Client', () => {
test('default setup', () => {
Expand Down Expand Up @@ -370,16 +370,9 @@ describe('User Pool Client', () => {
// GIVEN
const stack = new Stack();
const pool = new UserPool(stack, 'Pool');
new UserPoolIdentityProviderAmazon(stack, 'amznidp', {
userPool: pool,
clientId: 'amzn-client-id',
clientSecret: 'amzn-client-secret',
});
new UserPoolIdentityProviderFacebook(stack, 'fbidp', {
userPool: pool,
clientId: 'amzn-client-id',
clientSecret: 'amzn-client-secret',
});

const idp = UserPoolIdentityProvider.fromProviderName(stack, 'imported', 'userpool-idp');
pool.registerIdentityProvider(idp);

// WHEN
new UserPoolClient(stack, 'Client', {
Expand All @@ -389,50 +382,31 @@ describe('User Pool Client', () => {
// THEN
expect(stack).toHaveResource('AWS::Cognito::UserPoolClient', {
SupportedIdentityProviders: [
{ Ref: 'amznidp99BF1483' },
{ Ref: 'fbidp86F36311' },
'userpool-idp',
'COGNITO',
],
});
});

test('explicit supportedIdentityProviders', () => {
test('supportedIdentityProviders', () => {
// GIVEN
const stack = new Stack();
const pool = new UserPool(stack, 'Pool');

// WHEN
pool.addClient('DefaultExplicit', {
userPoolClientName: 'DefaultExplicit',
supportedIdentityProviders: {},
});
pool.addClient('AllEnabled', {
userPoolClientName: 'AllEnabled',
supportedIdentityProviders: {
amazon: true,
facebook: true,
cognito: true,
},
});
pool.addClient('CognitoDisabled', {
userPoolClientName: 'CognitoDisabled',
supportedIdentityProviders: {
cognito: false,
},
supportedIdentityProviders: [
UserPoolClientIdentityProvider.COGNITO,
UserPoolClientIdentityProvider.FACEBOOK,
UserPoolClientIdentityProvider.AMAZON,
],
});

// THEN
expect(stack).toHaveResource('AWS::Cognito::UserPoolClient', {
ClientName: 'DefaultExplicit',
SupportedIdentityProviders: [ 'COGNITO' ],
});
expect(stack).toHaveResource('AWS::Cognito::UserPoolClient', {
ClientName: 'AllEnabled',
SupportedIdentityProviders: [ 'COGNITO', 'Facebook', 'LoginWithAmazon' ],
});
expect(stack).toHaveResource('AWS::Cognito::UserPoolClient', {
ClientName: 'CognitoDisabled',
SupportedIdentityProviders: ABSENT,
});
});
});

0 comments on commit f2bba19

Please sign in to comment.