Repository: aws-cloudformation/cfn-lint

Issue:
E2057 False positive for IAM policy Effect conditionals
*cfn-lint version: (`cfn-lint --version`)*
cfn-lint 0.21.4

*Description of issue.*
cfn-lint reports "E2507 IAM Policy Effect should be Allow or Deny" when an IAM policy statement contains an intrinsic statement, even if that intrinsic returns Allow or Deny eg:

`Effect: !If [ IsUsEast1, 'Allow', 'Deny' ]`

I would guess this probably affects all IAM policy statements and intrinsics, I have observed it for the following policy types:
-  AWS::S3::BucketPolicy
-  AWS::IAM::ManagedPolicy
-  AWS::IAM::User policies

And the following intrinsics
- !If
- !Sub
- !Ref

A simple reproduce example termplate is attached: [E2507-false-positive.yml.txt](https://github.com/aws-cloudformation/cfn-python-lint/files/3269255/E2507-false-positive.yml.txt)



Discussion:

Resolving patch:
diff --git a/src/cfnlint/rules/resources/iam/Policy.py b/src/cfnlint/rules/resources/iam/Policy.py
--- a/src/cfnlint/rules/resources/iam/Policy.py
+++ b/src/cfnlint/rules/resources/iam/Policy.py
@@ -140,11 +140,12 @@ def _check_policy_statement(self, branch, statement, is_identity_policy, resourc
             matches.append(
                 RuleMatch(branch[:], message))
         else:
-            effect = statement.get('Effect')
-            if effect not in ['Allow', 'Deny']:
-                message = 'IAM Policy Effect should be Allow or Deny'
-                matches.append(
-                    RuleMatch(branch[:] + ['Effect'], message))
+            for effect, effect_path in statement.get_safe('Effect'):
+                if isinstance(effect, six.string_types):
+                    if effect not in ['Allow', 'Deny']:
+                        message = 'IAM Policy Effect should be Allow or Deny'
+                        matches.append(
+                            RuleMatch(branch[:] + effect_path, message))
         if 'Action' not in statement and 'NotAction' not in statement:
             message = 'IAM Policy statement missing Action or NotAction'
             matches.append(


Test patch:
diff --git a/test/fixtures/templates/good/resources/iam/resource_policy.yaml b/test/fixtures/templates/good/resources/iam/resource_policy.yaml
--- a/test/fixtures/templates/good/resources/iam/resource_policy.yaml
+++ b/test/fixtures/templates/good/resources/iam/resource_policy.yaml
@@ -3,6 +3,10 @@ AWSTemplateFormatVersion: "2010-09-09"
 Parameters:
   myExampleBucket:
     Type: String
+  BucketEffect:
+    Type: String
+Conditions:
+  IsUsEast1: !Equals ['us-east-1', !Ref 'AWS::Region']
 Resources:
   WebsiteBucketPolicy:
     Type: AWS::S3::BucketPolicy
@@ -46,15 +50,26 @@ Resources:
           -
             Action:
               - "s3:GetObject"
-            Effect: "Allow"
-            Resource:
-              Fn::Join:
-                - ""
-                -
-                  - "arn:aws:s3:::"
-                  -
-                    Ref: "myExampleBucket"
-                  - "/*"
+            Effect: !If [ IsUsEast1, 'Allow', 'Deny' ]
+            Resource: !Sub "arn:aws:s3:::${myExampleBucket}/*"
+            Principal: "*"
+            Condition:
+              StringLike:
+                aws:Referer:
+                  - "http://www.example.com/*"
+                  - "http://example.com/*"
+  SampleBucketPolicy2:
+    Type: AWS::S3::BucketPolicy
+    Properties:
+      Bucket:
+        Ref: "myExampleBucket"
+      PolicyDocument:
+        Statement:
+          -
+            Action:
+              - "s3:GetObject"
+            Effect: !Ref BucketEffect
+            Resource: !Sub "arn:aws:s3:::${myExampleBucket}/*"
             Principal: "*"
             Condition:
               StringLike: