Skip to content

Commit

Permalink
Merge branch 'main' into TheRealAmazonKendra/init-template-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Sep 9, 2022
2 parents 1f4a16b + 0ad307b commit a2089d1
Show file tree
Hide file tree
Showing 61 changed files with 3,359 additions and 80 deletions.
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-cognito/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@ The following third-party identity providers are currently supported in the CDK
- [Google Login](https://developers.google.com/identity/sign-in/web/sign-in)
- [Sign In With Apple](https://developer.apple.com/sign-in-with-apple/get-started/)
- [OpenID Connect](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-oidc-idp.html)
- [SAML](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-saml-idp.html)

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
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-idps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './amazon';
export * from './facebook';
export * from './google';
export * from './oidc';
export * from './saml';
132 changes: 132 additions & 0 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-idps/saml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { Names, Token } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnUserPoolIdentityProvider } from '../cognito.generated';
import { UserPoolIdentityProviderProps } from './base';
import { UserPoolIdentityProviderBase } from './private/user-pool-idp-base';

/**
* Properties to initialize UserPoolIdentityProviderSaml.
*/
export interface UserPoolIdentityProviderSamlProps extends UserPoolIdentityProviderProps {
/**
* The name of the provider. Must be between 3 and 32 characters.
*
* @default - the unique ID of the construct
*/
readonly name?: string;

/**
* Identifiers
*
* Identifiers can be used to redirect users to the correct IdP in multitenant apps.
*
* @default - no identifiers used
*/
readonly identifiers?: string[]

/**
* The SAML metadata.
*/
readonly metadata: UserPoolIdentityProviderSamlMetadata;

/**
* Whether to enable the "Sign-out flow" feature.
*
* @default - false
*/
readonly idpSignout?: boolean;
}

/**
* Metadata types that can be used for a SAML user pool identity provider.
*/
export enum UserPoolIdentityProviderSamlMetadataType {
/** Metadata provided via a URL. */
URL = 'url',

/** Metadata provided via the contents of a file. */
FILE = 'file',
}

/**
* Metadata for a SAML user pool identity provider.
*/
export class UserPoolIdentityProviderSamlMetadata {

/**
* Specify SAML metadata via a URL.
*/
public static url(url: string): UserPoolIdentityProviderSamlMetadata {
return new UserPoolIdentityProviderSamlMetadata(url, UserPoolIdentityProviderSamlMetadataType.URL);
}

/**
* Specify SAML metadata via the contents of a file.
*/
public static file(fileContent: string): UserPoolIdentityProviderSamlMetadata {
return new UserPoolIdentityProviderSamlMetadata(fileContent, UserPoolIdentityProviderSamlMetadataType.FILE);
}

/**
* Construct the metadata for a SAML identity provider.
*
* @param metadataContent A URL hosting SAML metadata, or the content of a file containing SAML metadata.
* @param metadataType The type of metadata, either a URL or file content.
*/
private constructor(public readonly metadataContent: string, public readonly metadataType: UserPoolIdentityProviderSamlMetadataType) {
}
}

/**
* Represents a identity provider that integrates with SAML.
* @resource AWS::Cognito::UserPoolIdentityProvider
*/
export class UserPoolIdentityProviderSaml extends UserPoolIdentityProviderBase {
public readonly providerName: string;

constructor(scope: Construct, id: string, props: UserPoolIdentityProviderSamlProps) {
super(scope, id, props);

this.validateName(props.name);

const { metadataType, metadataContent } = props.metadata;

const resource = new CfnUserPoolIdentityProvider(this, 'Resource', {
userPoolId: props.userPool.userPoolId,
providerName: this.getProviderName(props.name),
providerType: 'SAML',
providerDetails: {
IDPSignout: props.idpSignout ?? false,
MetadataURL: metadataType === UserPoolIdentityProviderSamlMetadataType.URL ? metadataContent : undefined,
MetadataFile: metadataType === UserPoolIdentityProviderSamlMetadataType.FILE ? metadataContent : undefined,
},
idpIdentifiers: props.identifiers,
attributeMapping: super.configureAttributeMapping(),
});

this.providerName = super.getResourceNameAttribute(resource.ref);
}

private getProviderName(name?: string): string {
if (name) {
this.validateName(name);
return name;
}

const uniqueName = Names.uniqueResourceName(this, {
maxLength: 32,
});

if (uniqueName.length < 3) {
return `${uniqueName}saml`;
}

return uniqueName;
}

private validateName(name?: string) {
if (name && !Token.isUnresolved(name) && (name.length < 3 || name.length > 32)) {
throw new Error(`Expected provider name to be between 3 and 32 characters, received ${name} (${name.length} characters)`);
}
}
}
4 changes: 3 additions & 1 deletion packages/@aws-cdk/aws-cognito/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"@aws-cdk/assertions": "0.0.0",
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/integ-tests": "0.0.0",
"@aws-cdk/cfn2ts": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.5.2",
Expand Down Expand Up @@ -126,7 +127,8 @@
"props-physical-name:@aws-cdk/aws-cognito.UserPoolIdentityProviderAmazonProps",
"props-physical-name:@aws-cdk/aws-cognito.UserPoolIdentityProviderGoogleProps",
"props-physical-name:@aws-cdk/aws-cognito.UserPoolIdentityProviderAppleProps",
"props-physical-name:@aws-cdk/aws-cognito.UserPoolIdentityProviderOidcProps"
"props-physical-name:@aws-cdk/aws-cognito.UserPoolIdentityProviderOidcProps",
"props-physical-name:@aws-cdk/aws-cognito.UserPoolIdentityProviderSamlProps"
]
},
"stability": "stable",
Expand Down
40 changes: 40 additions & 0 deletions packages/@aws-cdk/aws-cognito/test/integ.user-pool-idp.saml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { App, CfnOutput, RemovalPolicy, Stack } from '@aws-cdk/core';
import { IntegTest } from '@aws-cdk/integ-tests';
import { Construct } from 'constructs';
import { UserPool, UserPoolIdentityProviderSaml, UserPoolIdentityProviderSamlMetadata } from '../lib';

class TestStack extends Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
const userpool = new UserPool(this, 'pool', {
removalPolicy: RemovalPolicy.DESTROY,
});

new UserPoolIdentityProviderSaml(this, 'cdk', {
userPool: userpool,
name: 'cdk',
metadata: UserPoolIdentityProviderSamlMetadata.url('https://fujifish.github.io/samling/public/metadata.xml'),
});

const client = userpool.addClient('client');

const domain = userpool.addDomain('domain', {
cognitoDomain: {
domainPrefix: 'cdk-test-pool',
},
});

new CfnOutput(this, 'SignInLink', {
value: domain.signInUrl(client, {
redirectUri: 'https://example.com',
}),
});
}
}

const app = new App();
const testCase = new TestStack(app, 'integ-user-pool-identity-provider-saml-stack');

new IntegTest(app, 'integ-user-pool-identity-provider-saml-test', {
testCases: [testCase],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"21.0.0"}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"6f6f07786415216f13b738979cec5ad81dbab3283fae83b99324965935cc1d60": {
"source": {
"path": "integ-user-pool-identity-provider-saml-stack.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "6f6f07786415216f13b738979cec5ad81dbab3283fae83b99324965935cc1d60.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"Resources": {
"pool056F3F7E": {
"Type": "AWS::Cognito::UserPool",
"Properties": {
"AccountRecoverySetting": {
"RecoveryMechanisms": [
{
"Name": "verified_phone_number",
"Priority": 1
},
{
"Name": "verified_email",
"Priority": 2
}
]
},
"AdminCreateUserConfig": {
"AllowAdminCreateUserOnly": true
},
"EmailVerificationMessage": "The verification code to your new account is {####}",
"EmailVerificationSubject": "Verify your new account",
"SmsVerificationMessage": "The verification code to your new account is {####}",
"VerificationMessageTemplate": {
"DefaultEmailOption": "CONFIRM_WITH_CODE",
"EmailMessage": "The verification code to your new account is {####}",
"EmailSubject": "Verify your new account",
"SmsMessage": "The verification code to your new account is {####}"
}
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
},
"poolclient2623294C": {
"Type": "AWS::Cognito::UserPoolClient",
"Properties": {
"UserPoolId": {
"Ref": "pool056F3F7E"
},
"AllowedOAuthFlows": [
"implicit",
"code"
],
"AllowedOAuthFlowsUserPoolClient": true,
"AllowedOAuthScopes": [
"profile",
"phone",
"email",
"openid",
"aws.cognito.signin.user.admin"
],
"CallbackURLs": [
"https://example.com"
],
"SupportedIdentityProviders": [
{
"Ref": "cdk52888317"
},
"COGNITO"
]
}
},
"pooldomain430FA744": {
"Type": "AWS::Cognito::UserPoolDomain",
"Properties": {
"Domain": "cdk-test-pool",
"UserPoolId": {
"Ref": "pool056F3F7E"
}
}
},
"cdk52888317": {
"Type": "AWS::Cognito::UserPoolIdentityProvider",
"Properties": {
"ProviderName": "cdk",
"ProviderType": "SAML",
"UserPoolId": {
"Ref": "pool056F3F7E"
},
"ProviderDetails": {
"IDPSignout": false,
"MetadataURL": "https://fujifish.github.io/samling/public/metadata.xml"
}
}
}
},
"Outputs": {
"SignInLink": {
"Value": {
"Fn::Join": [
"",
[
"https://",
{
"Ref": "pooldomain430FA744"
},
".auth.",
{
"Ref": "AWS::Region"
},
".amazoncognito.com/login?client_id=",
{
"Ref": "poolclient2623294C"
},
"&response_type=code&redirect_uri=https://example.com"
]
]
}
}
},
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "21.0.0",
"testCases": {
"integ-user-pool-identity-provider-saml-test/DefaultTest": {
"stacks": [
"integ-user-pool-identity-provider-saml-stack"
],
"assertionStack": "integ-user-pool-identity-provider-saml-test/DefaultTest/DeployAssert",
"assertionStackName": "integuserpoolidentityprovidersamltestDefaultTestDeployAssert97F09C26"
}
}
}
Loading

0 comments on commit a2089d1

Please sign in to comment.