Skip to content

Commit

Permalink
Rework how SAML metadata is provided
Browse files Browse the repository at this point in the history
  • Loading branch information
ktfleming committed Sep 3, 2022
1 parent 62e0da1 commit 36965e7
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 41 deletions.
56 changes: 37 additions & 19 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-idps/saml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,9 @@ export interface UserPoolIdentityProviderSamlProps extends UserPoolIdentityProvi
readonly identifiers?: string[]

/**
* The SAML metadata file type.
* The SAML metadata.
*/
readonly metadataType: UserPoolIdentityProviderSamlMetadataType;

/**
* The SAML metadata content.
* If metadataType is set to URL, this should be the metadata URL.
* If metadataType is set to FILE, this should be the metadata file contents.
*/
readonly metadataContent: string;
readonly metadata: UserPoolIdentityProviderSamlMetadata;

/**
* Whether to enable the "Sign-out flow" feature.
Expand All @@ -55,6 +48,35 @@ export enum UserPoolIdentityProviderSamlMetadataType {
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
Expand All @@ -67,21 +89,17 @@ export class UserPoolIdentityProviderSaml extends UserPoolIdentityProviderBase {

this.validateName(props.name);

const providerDetails: Record<string, string | boolean> = {
IDPSignout: props.idpSignout ?? false,
};

if (props.metadataType === UserPoolIdentityProviderSamlMetadataType.URL) {
providerDetails.MetadataURL = props.metadataContent;
} else if (props.metadataType === UserPoolIdentityProviderSamlMetadataType.FILE) {
providerDetails.MetadataFile = props.metadataContent;
}
const { metadataType, metadataContent } = props.metadata;

const resource = new CfnUserPoolIdentityProvider(this, 'Resource', {
userPoolId: props.userPool.userPoolId,
providerName: this.getProviderName(props.name),
providerType: 'SAML',
providerDetails,
providerDetails: {
IDPSignout: props.idpSignout ?? false,
MetadataURL: metadataType === UserPoolIdentityProviderSamlMetadataType.URL ? metadataContent : undefined,
MetadataFile: metadataType === UserPoolIdentityProviderSamlMetadataType.FILE ? metadataContent : undefined,
},
idpIdentifiers: props.identifiers,
attributeMapping: super.configureAttributeMapping(),
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { App, CfnOutput, RemovalPolicy, Stack } from '@aws-cdk/core';
import { IntegTest } from '@aws-cdk/integ-tests';
import { Construct } from 'constructs';
import { UserPool, UserPoolIdentityProviderSaml, UserPoolIdentityProviderSamlMetadataType } from '../lib';
import { UserPool, UserPoolIdentityProviderSaml, UserPoolIdentityProviderSamlMetadata } from '../lib';

class TestStack extends Stack {
constructor(scope: Construct, id: string) {
Expand All @@ -13,8 +13,7 @@ class TestStack extends Stack {
new UserPoolIdentityProviderSaml(this, 'cdk', {
userPool: userpool,
name: 'cdk',
metadataType: UserPoolIdentityProviderSamlMetadataType.URL,
metadataContent: 'https://fujifish.github.io/samling/public/metadata.xml',
metadata: UserPoolIdentityProviderSamlMetadata.url('https://fujifish.github.io/samling/public/metadata.xml'),
});

const client = userpool.addClient('client');
Expand Down
29 changes: 10 additions & 19 deletions packages/@aws-cdk/aws-cognito/test/user-pool-idps/saml.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Template, Match } from '@aws-cdk/assertions';
import { Stack } from '@aws-cdk/core';
import { ProviderAttribute, UserPool, UserPoolIdentityProviderSaml, UserPoolIdentityProviderSamlMetadataType } from '../../lib';
import { ProviderAttribute, UserPool, UserPoolIdentityProviderSaml, UserPoolIdentityProviderSamlMetadata } from '../../lib';

describe('UserPoolIdentityProvider', () => {
describe('saml', () => {
Expand All @@ -12,8 +12,7 @@ describe('UserPoolIdentityProvider', () => {
// WHEN
new UserPoolIdentityProviderSaml(stack, 'userpoolidp', {
userPool: pool,
metadataType: UserPoolIdentityProviderSamlMetadataType.URL,
metadataContent: 'https://my-metadata-url.com',
metadata: UserPoolIdentityProviderSamlMetadata.url('https://my-metadata-url.com'),
});

// THEN
Expand All @@ -35,8 +34,7 @@ describe('UserPoolIdentityProvider', () => {
// WHEN
new UserPoolIdentityProviderSaml(stack, 'userpoolidp', {
userPool: pool,
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
});

// THEN
Expand All @@ -58,8 +56,7 @@ describe('UserPoolIdentityProvider', () => {
// WHEN
new UserPoolIdentityProviderSaml(stack, 'userpoolidp', {
userPool: pool,
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
idpSignout: true,
});

Expand All @@ -82,8 +79,7 @@ describe('UserPoolIdentityProvider', () => {
// WHEN
const provider = new UserPoolIdentityProviderSaml(stack, 'userpoolidp', {
userPool: pool,
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
});

// THEN
Expand All @@ -98,8 +94,7 @@ describe('UserPoolIdentityProvider', () => {
// WHEN
new UserPoolIdentityProviderSaml(stack, 'userpoolidp', {
userPool: pool,
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
attributeMapping: {
familyName: ProviderAttribute.other('family_name'),
givenName: ProviderAttribute.other('given_name'),
Expand Down Expand Up @@ -130,8 +125,7 @@ describe('UserPoolIdentityProvider', () => {
new UserPoolIdentityProviderSaml(stack, 'userpoolidp', {
userPool: pool,
name: 'my-provider',
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
});

// THEN
Expand All @@ -149,8 +143,7 @@ describe('UserPoolIdentityProvider', () => {
expect(() => new UserPoolIdentityProviderSaml(stack, 'userpoolidp', {
userPool: pool,
name: 'xy',
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
})).toThrow(/Expected provider name to be between 3 and 32 characters/);
});

Expand All @@ -162,8 +155,7 @@ describe('UserPoolIdentityProvider', () => {
// WHEN
new UserPoolIdentityProviderSaml(stack, 'xy', {
userPool: pool,
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
});

// THEN
Expand All @@ -180,8 +172,7 @@ describe('UserPoolIdentityProvider', () => {
// WHEN
new UserPoolIdentityProviderSaml(stack, `${'saml'.repeat(10)}xyz`, {
userPool: pool,
metadataType: UserPoolIdentityProviderSamlMetadataType.FILE,
metadataContent: 'my-file-contents',
metadata: UserPoolIdentityProviderSamlMetadata.file('my-file-contents'),
});

// THEN
Expand Down

0 comments on commit 36965e7

Please sign in to comment.