@@ -1452,7 +1452,7 @@ describe('#compileIamRole', () => {
1452
1452
expectDenyAllPolicy ( policy ) ;
1453
1453
} ) ;
1454
1454
1455
- it ( 'should give s3:GetObject permission for only objects referenced by state machine' , ( ) => {
1455
+ it ( 'should give s3 permissions for only objects referenced by state machine' , ( ) => {
1456
1456
const hello = 'hello.txt' ;
1457
1457
const world = 'world.txt' ;
1458
1458
const testBucket = 'test-bucket' ;
@@ -1469,6 +1469,16 @@ describe('#compileIamRole', () => {
1469
1469
Bucket : bucket ,
1470
1470
Key : key ,
1471
1471
} ,
1472
+ Next : 'B' ,
1473
+ } ,
1474
+ B : {
1475
+ Type : 'Task' ,
1476
+ Resource : 'arn:aws:states:::aws-sdk:s3:putObject' ,
1477
+ Parameters : {
1478
+ Bucket : bucket ,
1479
+ Key : key ,
1480
+ Body : { } ,
1481
+ } ,
1472
1482
End : true ,
1473
1483
} ,
1474
1484
} ,
@@ -1491,6 +1501,14 @@ describe('#compileIamRole', () => {
1491
1501
. to . be . deep . equal ( [ `arn:aws:s3:::${ testBucket } /${ hello } ` ] ) ;
1492
1502
expect ( policy2 . PolicyDocument . Statement [ 0 ] . Resource )
1493
1503
. to . be . deep . equal ( [ `arn:aws:s3:::${ testBucket } /${ world } ` ] ) ;
1504
+
1505
+ [ policy1 , policy2 ] . forEach ( ( policy ) => {
1506
+ expect ( policy . PolicyDocument . Statement [ 0 ] . Action )
1507
+ . to . be . deep . equal ( [
1508
+ 's3:GetObject' ,
1509
+ 's3:PutObject' ,
1510
+ ] ) ;
1511
+ } ) ;
1494
1512
} ) ;
1495
1513
1496
1514
it ( 'should give s3:GetObject permission for only objects referenced by state machine with ItemReader' , ( ) => {
@@ -1612,9 +1630,135 @@ describe('#compileIamRole', () => {
1612
1630
. provider . compiledCloudFormationTemplate . Resources ;
1613
1631
const policy1 = resources . StateMachine1Role . Properties . Policies [ 0 ] ;
1614
1632
1615
- // even though some tasks target specific topic ARNs , other states use Bucket.$
1633
+ // even though some tasks target specific values , other states use Bucket.$
1616
1634
// and Key.$ so we need to give broad permissions to be able to get any
1617
- // table and key the input specifies
1635
+ // bucket and key the input specifies
1636
+ expect ( policy1 . PolicyDocument . Statement [ 1 ] . Resource )
1637
+ . to . be . deep . equal ( '*' ) ;
1638
+ } ) ;
1639
+
1640
+ it ( 'should give s3:PutObject permission for only objects referenced by state machine with ResultWriter' , ( ) => {
1641
+ const hello = 'hello' ;
1642
+ const world = 'world' ;
1643
+ const testBucket = 'test-bucket' ;
1644
+
1645
+ const genStateMachine = ( id , lambdaArn , bucket , prefix ) => ( {
1646
+ id,
1647
+ definition : {
1648
+ StartAt : 'A' ,
1649
+ States : {
1650
+ A : {
1651
+ Type : 'Map' ,
1652
+ ItemProcessor : {
1653
+ StartAt : 'B' ,
1654
+ States : {
1655
+ B : {
1656
+ Type : 'Task' ,
1657
+ Resource : lambdaArn ,
1658
+ End : true ,
1659
+ } ,
1660
+ } ,
1661
+ } ,
1662
+ ResultWriter : {
1663
+ Resource : 'arn:aws:states:::s3:putObject' ,
1664
+ Parameters : {
1665
+ Bucket : bucket ,
1666
+ Prefix : prefix ,
1667
+ } ,
1668
+ } ,
1669
+ End : true ,
1670
+ } ,
1671
+ } ,
1672
+ } ,
1673
+ } ) ;
1674
+
1675
+ serverless . service . stepFunctions = {
1676
+ stateMachines : {
1677
+ myStateMachine1 : genStateMachine ( 'StateMachine1' ,
1678
+ 'arn:aws:lambda:us-west-2:1234567890:function:foo' , testBucket , hello ) ,
1679
+ myStateMachine2 : genStateMachine ( 'StateMachine2' ,
1680
+ 'arn:aws:lambda:us-west-2:1234567890:function:foo' , testBucket , world ) ,
1681
+ } ,
1682
+ } ;
1683
+
1684
+ serverlessStepFunctions . compileIamRole ( ) ;
1685
+ const resources = serverlessStepFunctions . serverless . service
1686
+ . provider . compiledCloudFormationTemplate . Resources ;
1687
+ const policy1 = resources . StateMachine1Role . Properties . Policies [ 0 ] ;
1688
+ const policy2 = resources . StateMachine2Role . Properties . Policies [ 0 ] ;
1689
+ expect ( policy1 . PolicyDocument . Statement [ 1 ] . Resource )
1690
+ . to . be . deep . equal ( [ `arn:aws:s3:::${ testBucket } /${ hello } /*` ] ) ;
1691
+ expect ( policy2 . PolicyDocument . Statement [ 1 ] . Resource )
1692
+ . to . be . deep . equal ( [ `arn:aws:s3:::${ testBucket } /${ world } /*` ] ) ;
1693
+ } ) ;
1694
+
1695
+ it ( 'should give s3:PutObject permission to * when Bucket.$ and Prefix.$ are seen on ResultWriter' , ( ) => {
1696
+ const genStateMachine = ( id , lambdaArn ) => ( {
1697
+ id,
1698
+ definition : {
1699
+ StartAt : 'A' ,
1700
+ States : {
1701
+ A : {
1702
+ Type : 'Map' ,
1703
+ ItemProcessor : {
1704
+ StartAt : 'B' ,
1705
+ States : {
1706
+ B : {
1707
+ Type : 'Task' ,
1708
+ Resource : lambdaArn ,
1709
+ End : true ,
1710
+ } ,
1711
+ } ,
1712
+ } ,
1713
+ ResultWriter : {
1714
+ Resource : 'arn:aws:states:::s3:putObject' ,
1715
+ Parameters : {
1716
+ Bucket : 'test-bucket' ,
1717
+ Prefix : 'test-prefix' ,
1718
+ } ,
1719
+ } ,
1720
+ Next : 'C' ,
1721
+ } ,
1722
+ C : {
1723
+ Type : 'Map' ,
1724
+ ItemProcessor : {
1725
+ StartAt : 'D' ,
1726
+ States : {
1727
+ D : {
1728
+ Type : 'Task' ,
1729
+ Resource : lambdaArn ,
1730
+ End : true ,
1731
+ } ,
1732
+ } ,
1733
+ } ,
1734
+ ResultWriter : {
1735
+ Resource : 'arn:aws:states:::s3:putObject' ,
1736
+ Parameters : {
1737
+ 'Bucket.$' : '$.testBucket' ,
1738
+ 'Prefix.$' : '$.prefix' ,
1739
+ } ,
1740
+ } ,
1741
+ End : true ,
1742
+ } ,
1743
+ } ,
1744
+ } ,
1745
+ } ) ;
1746
+
1747
+ serverless . service . stepFunctions = {
1748
+ stateMachines : {
1749
+ myStateMachine1 : genStateMachine ( 'StateMachine1' ,
1750
+ 'arn:aws:lambda:us-west-2:1234567890:function:foo' ) ,
1751
+ } ,
1752
+ } ;
1753
+
1754
+ serverlessStepFunctions . compileIamRole ( ) ;
1755
+ const resources = serverlessStepFunctions . serverless . service
1756
+ . provider . compiledCloudFormationTemplate . Resources ;
1757
+ const policy1 = resources . StateMachine1Role . Properties . Policies [ 0 ] ;
1758
+
1759
+ // even though some tasks target specific values, other states use Bucket.$
1760
+ // and Prefix.$ so we need to give broad permissions to be able to write to
1761
+ // any bucket and prefix the input specifies
1618
1762
expect ( policy1 . PolicyDocument . Statement [ 1 ] . Resource )
1619
1763
. to . be . deep . equal ( '*' ) ;
1620
1764
} ) ;
0 commit comments