From 58de0de5a54b9d8fb4658566e85ef408c8861088 Mon Sep 17 00:00:00 2001 From: Jason <431341+jstrese@users.noreply.github.com> Date: Thu, 8 Apr 2021 14:48:37 -0500 Subject: [PATCH] fix(stepfunctions): state machine name validation fails when tokens are used. (#13970) Name validation for state machines was added in #13387. The validation added was not considering that the name may contain an unresolved token. This change skips name validation if there is an unresolved token as it does not make sense to attempt to validate something that is unknown. This change also allows a few more special characters as they are allowed through the AWS Console. fixes #13946 #13912 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-stepfunctions/lib/state-machine.ts | 17 +++++----- .../test/state-machine.test.ts | 31 ++++++++++++++++++- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts index fa97eccad71f4..d7e7a73efa3f0 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/state-machine.ts @@ -1,7 +1,7 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as iam from '@aws-cdk/aws-iam'; import * as logs from '@aws-cdk/aws-logs'; -import { Arn, Duration, IResource, Resource, Stack } from '@aws-cdk/core'; +import { Arn, Duration, IResource, Resource, Stack, Token } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { StateGraph } from './state-graph'; import { StatesMetrics } from './stepfunctions-canned-metrics.generated'; @@ -379,7 +379,7 @@ export class StateMachine extends StateMachineBase { physicalName: props.stateMachineName, }); - if (props.stateMachineName != undefined) { + if (props.stateMachineName !== undefined) { this.validateStateMachineName(props.stateMachineName); } @@ -431,11 +431,14 @@ export class StateMachine extends StateMachineBase { } private validateStateMachineName(stateMachineName: string) { - if (stateMachineName.length < 1 || stateMachineName.length > 80) { - throw new Error(`State Machine name must be between 1 and 80 characters. Received: ${stateMachineName}`); - } - if (!stateMachineName.match('^[0-9a-zA-Z+!@._-]+$')) { - throw new Error(`State Machine name must match "^[0-9a-zA-Z+!@._-]+$". Received: ${stateMachineName}`); + if (!Token.isUnresolved(stateMachineName)) { + if (stateMachineName.length < 1 || stateMachineName.length > 80) { + throw new Error(`State Machine name must be between 1 and 80 characters. Received: ${stateMachineName}`); + } + + if (!stateMachineName.match(/^[a-z0-9\+\!\@\.\(\)\-\=\_\']+$/i)) { + throw new Error(`State Machine name must match "^[a-z0-9+!@.()-=_']+$/i". Received: ${stateMachineName}`); + } } } diff --git a/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts index 1e4abddb9234d..6db3dd6b476bd 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/state-machine.test.ts @@ -89,7 +89,36 @@ describe('State Machine', () => { expect(() => { createStateMachine(invalidCharactersName); - }).toThrow(`State Machine name must match "^[0-9a-zA-Z+!@._-]+$". Received: ${invalidCharactersName}`); + }).toThrow(`State Machine name must match "^[a-z0-9+!@.()-=_']+$/i". Received: ${invalidCharactersName}`); + }); + + test('State Machine with valid name', () => { + // GIVEN + const stack = new cdk.Stack(); + const newStateMachine = new stepfunctions.StateMachine(stack, 'dummyStateMachineToken', { + definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'dummyStateMachineTokenPass')), + }); + + // WHEN + const nameContainingToken = newStateMachine.stateMachineName + '-Name'; + const validName = 'AWS-Stepfunctions_Name.Test(@aws-cdk+)!=\'1\''; + + // THEN + expect(() => { + new stepfunctions.StateMachine(stack, 'TokenTest-StateMachine', { + stateMachineName: nameContainingToken, + definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'TokenTest-StateMachinePass')), + stateMachineType: stepfunctions.StateMachineType.EXPRESS, + }); + }).not.toThrow(); + + expect(() => { + new stepfunctions.StateMachine(stack, 'ValidNameTest-StateMachine', { + stateMachineName: validName, + definition: stepfunctions.Chain.start(new stepfunctions.Pass(stack, 'ValidNameTest-StateMachinePass')), + stateMachineType: stepfunctions.StateMachineType.EXPRESS, + }); + }).not.toThrow(); }); test('log configuration', () => {