@@ -778,6 +778,244 @@ describe('#compileIamRole', () => {
778778 expect ( policy . PolicyDocument . Statement [ 0 ] . Resource ) . to . equal ( '*' ) ;
779779 } ) ;
780780
781+ it ( 'should give Redshift Data permissions to * for safe actions' , ( ) => {
782+ serverless . service . stepFunctions = {
783+ stateMachines : {
784+ myStateMachine : {
785+ id : 'StateMachine1' ,
786+ definition : {
787+ StartAt : 'A' ,
788+ States : {
789+ A : {
790+ Type : 'Task' ,
791+ Next : 'B' ,
792+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:listStatements' ,
793+ } ,
794+ B : {
795+ Type : 'Task' ,
796+ Next : 'C' ,
797+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:describeStatement' ,
798+ } ,
799+ C : {
800+ Type : 'Task' ,
801+ Next : 'D' ,
802+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:getStatementResult' ,
803+ } ,
804+ D : {
805+ Type : 'Task' ,
806+ End : true ,
807+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:cancelStatement' ,
808+ } ,
809+ } ,
810+ } ,
811+ } ,
812+ } ,
813+ } ;
814+ serverlessStepFunctions . compileIamRole ( ) ;
815+ const statement = serverlessStepFunctions . serverless . service . provider
816+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
817+ . PolicyDocument . Statement [ 0 ] ;
818+ expect ( statement . Action ) . to . include ( 'redshift-data:ListStatements' ) ;
819+ expect ( statement . Action ) . to . include ( 'redshift-data:DescribeStatement' ) ;
820+ expect ( statement . Action ) . to . include ( 'redshift-data:GetStatementResult' ) ;
821+ expect ( statement . Action ) . to . include ( 'redshift-data:CancelStatement' ) ;
822+ expect ( statement . Resource ) . to . equal ( '*' ) ;
823+ } ) ;
824+
825+ it ( 'should give Redshift Data permissions to clusters for unsafe actions' , ( ) => {
826+ serverless . service . stepFunctions = {
827+ stateMachines : {
828+ myStateMachine : {
829+ id : 'StateMachine1' ,
830+ definition : {
831+ StartAt : 'A' ,
832+ States : {
833+ A : {
834+ Type : 'Task' ,
835+ Next : 'B' ,
836+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
837+ } ,
838+ B : {
839+ Type : 'Task' ,
840+ End : true ,
841+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
842+ } ,
843+ } ,
844+ } ,
845+ } ,
846+ } ,
847+ } ;
848+ serverlessStepFunctions . compileIamRole ( ) ;
849+ const statement = serverlessStepFunctions . serverless . service . provider
850+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
851+ . PolicyDocument . Statement [ 0 ] ;
852+ expect ( statement . Action ) . to . include ( 'redshift-data:ExecuteStatement' ) ;
853+ expect ( statement . Action ) . to . include ( 'redshift-data:BatchExecuteStatement' ) ;
854+ expect ( statement . Resource ) . to . have . deep . members ( [ {
855+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:cluster:*' ,
856+ } ] ) ;
857+ } ) ;
858+
859+ it ( 'should give Redshift Data permissions to a specified cluster for unsafe actions' , ( ) => {
860+ const clusterName = 'myCluster' ;
861+ serverless . service . stepFunctions = {
862+ stateMachines : {
863+ myStateMachine : {
864+ id : 'StateMachine1' ,
865+ definition : {
866+ StartAt : 'A' ,
867+ States : {
868+ A : {
869+ Type : 'Task' ,
870+ Next : 'B' ,
871+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
872+ Parameters : {
873+ ClusterIdentifier : clusterName ,
874+ } ,
875+ } ,
876+ B : {
877+ Type : 'Task' ,
878+ End : true ,
879+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
880+ Parameters : {
881+ ClusterIdentifier : clusterName ,
882+ } ,
883+ } ,
884+ } ,
885+ } ,
886+ } ,
887+ } ,
888+ } ;
889+ serverlessStepFunctions . compileIamRole ( ) ;
890+ const statement = serverlessStepFunctions . serverless . service . provider
891+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
892+ . PolicyDocument . Statement [ 0 ] ;
893+ expect ( statement . Action ) . to . include ( 'redshift-data:ExecuteStatement' ) ;
894+ expect ( statement . Action ) . to . include ( 'redshift-data:BatchExecuteStatement' ) ;
895+ expect ( statement . Resource ) . to . have . deep . members ( [ {
896+ 'Fn::Sub' : `arn:\${AWS::Partition}:redshift:\${AWS::Region}:\${AWS::AccountId}:cluster:${ clusterName } ` ,
897+ } ] ) ;
898+ } ) ;
899+
900+ it ( 'should give redshift:GetClusterCredentials permission to databases and database users for unsafe actions' , ( ) => {
901+ serverless . service . stepFunctions = {
902+ stateMachines : {
903+ myStateMachine : {
904+ id : 'StateMachine1' ,
905+ definition : {
906+ StartAt : 'A' ,
907+ States : {
908+ A : {
909+ Type : 'Task' ,
910+ Next : 'B' ,
911+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
912+ } ,
913+ B : {
914+ Type : 'Task' ,
915+ End : true ,
916+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
917+ } ,
918+ } ,
919+ } ,
920+ } ,
921+ } ,
922+ } ;
923+ serverlessStepFunctions . compileIamRole ( ) ;
924+ const statement = serverlessStepFunctions . serverless . service . provider
925+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
926+ . PolicyDocument . Statement [ 1 ] ;
927+ expect ( statement . Action ) . to . include ( 'redshift:GetClusterCredentials' ) ;
928+ expect ( statement . Resource ) . to . have . deep . members ( [ {
929+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbname:*/*' ,
930+ } , {
931+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbuser:*/*' ,
932+ } ] ) ;
933+ } ) ;
934+
935+ it ( 'should give redshift:GetClusterCredentials permission to specified databases for unsafe actions' , ( ) => {
936+ const dbName = 'myDatabase' ;
937+ serverless . service . stepFunctions = {
938+ stateMachines : {
939+ myStateMachine : {
940+ id : 'StateMachine1' ,
941+ definition : {
942+ StartAt : 'A' ,
943+ States : {
944+ A : {
945+ Type : 'Task' ,
946+ Next : 'B' ,
947+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
948+ Parameters : {
949+ Database : dbName ,
950+ } ,
951+ } ,
952+ B : {
953+ Type : 'Task' ,
954+ End : true ,
955+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
956+ Parameters : {
957+ Database : dbName ,
958+ } ,
959+ } ,
960+ } ,
961+ } ,
962+ } ,
963+ } ,
964+ } ;
965+ serverlessStepFunctions . compileIamRole ( ) ;
966+ const statement = serverlessStepFunctions . serverless . service . provider
967+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
968+ . PolicyDocument . Statement [ 1 ] ;
969+ expect ( statement . Action ) . to . include ( 'redshift:GetClusterCredentials' ) ;
970+ expect ( statement . Resource ) . to . have . deep . members ( [ {
971+ 'Fn::Sub' : `arn:\${AWS::Partition}:redshift:\${AWS::Region}:\${AWS::AccountId}:dbname:*/${ dbName } ` ,
972+ } , {
973+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbuser:*/*' ,
974+ } ] ) ;
975+ } ) ;
976+
977+ it ( 'should give redshift:GetClusterCredentials permission to specified database users for unsafe actions' , ( ) => {
978+ const dbUser = 'myDatabaseUser' ;
979+ serverless . service . stepFunctions = {
980+ stateMachines : {
981+ myStateMachine : {
982+ id : 'StateMachine1' ,
983+ definition : {
984+ StartAt : 'A' ,
985+ States : {
986+ A : {
987+ Type : 'Task' ,
988+ Next : 'B' ,
989+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:executeStatement' ,
990+ Parameters : {
991+ DbUser : dbUser ,
992+ } ,
993+ } ,
994+ B : {
995+ Type : 'Task' ,
996+ End : true ,
997+ Resource : 'arn:aws:states:::aws-sdk:redshiftdata:batchExecuteStatement' ,
998+ Parameters : {
999+ DbUser : dbUser ,
1000+ } ,
1001+ } ,
1002+ } ,
1003+ } ,
1004+ } ,
1005+ } ,
1006+ } ;
1007+ serverlessStepFunctions . compileIamRole ( ) ;
1008+ const statement = serverlessStepFunctions . serverless . service . provider
1009+ . compiledCloudFormationTemplate . Resources . StateMachine1Role . Properties . Policies [ 0 ]
1010+ . PolicyDocument . Statement [ 1 ] ;
1011+ expect ( statement . Action ) . to . include ( 'redshift:GetClusterCredentials' ) ;
1012+ expect ( statement . Resource ) . to . have . deep . members ( [ {
1013+ 'Fn::Sub' : 'arn:${AWS::Partition}:redshift:${AWS::Region}:${AWS::AccountId}:dbname:*/*' ,
1014+ } , {
1015+ 'Fn::Sub' : `arn:\${AWS::Partition}:redshift:\${AWS::Region}:\${AWS::AccountId}:dbuser:*/${ dbUser } ` ,
1016+ } ] ) ;
1017+ } ) ;
1018+
7811019 it ( 'should give batch permissions (too permissive, but mirrors console behaviour)' , ( ) => {
7821020 const genStateMachine = id => ( {
7831021 id,
0 commit comments