From 8e229bfcc15e7727ec1c18376cb3abee5ad3678e Mon Sep 17 00:00:00 2001 From: kddejong <36457093+kddejong@users.noreply.github.com> Date: Sun, 25 Nov 2018 10:13:59 -0600 Subject: [PATCH] Add a new rule to validate a managed policy description against a regex (#484) --- setup.py | 3 +- .../resources/iam/ManagedPolicyDescription.py | 58 +++++++++++++++++++ .../iam/managed_policy_description.yaml | 17 ++++++ .../iam/managed_policy_description.yaml | 16 +++++ .../test_iam_managed_policy_description.py | 37 ++++++++++++ tox.ini | 14 +++-- 6 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 src/cfnlint/rules/resources/iam/ManagedPolicyDescription.py create mode 100644 test/fixtures/templates/bad/resources/iam/managed_policy_description.yaml create mode 100644 test/fixtures/templates/good/resources/iam/managed_policy_description.yaml create mode 100644 test/rules/resources/iam/test_iam_managed_policy_description.py diff --git a/setup.py b/setup.py index 09bcb2592f..6bb5298118 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,8 @@ def get_version(filename): 'aws-sam-translator>=1.8.0', 'jsonpatch', 'jsonschema~=2.6', - 'pathlib2>=2.3.0;python_version<"3.4"' + 'pathlib2>=2.3.0;python_version<"3.4"', + 'regex>=2018.11.07' ], python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', entry_points={ diff --git a/src/cfnlint/rules/resources/iam/ManagedPolicyDescription.py b/src/cfnlint/rules/resources/iam/ManagedPolicyDescription.py new file mode 100644 index 0000000000..3a7a0d91b4 --- /dev/null +++ b/src/cfnlint/rules/resources/iam/ManagedPolicyDescription.py @@ -0,0 +1,58 @@ +""" + Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" +import regex +from cfnlint import CloudFormationLintRule +from cfnlint import RuleMatch + + +class ManagedPolicyDescription(CloudFormationLintRule): + """Check if IAM Policy Description is syntax correct""" + id = 'E3507' + shortdesc = 'Check if IAM Managed Policy description follows supported regex' + description = 'IAM Managed Policy description much comply with the regex [\\p{L}\\p{M}\\p{Z}\\p{S}\\p{N}\\p{P}]*' + source_url = 'https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-managedpolicy.html' + tags = ['properties', 'iam'] + + def __init__(self): + """Init""" + super(ManagedPolicyDescription, self).__init__() + self.resource_property_types.append('AWS::IAM::ManagedPolicy') + + def check_value(self, value, path): + """Check the value""" + regex_string = r'^[\p{L}\p{M}\p{Z}\p{S}\p{N}\p{P}]+$' + r = regex.compile(regex_string) + if not r.match(value): + message = 'ManagedPolicy Description needs to follow regex pattern "{0}"' + return [ + RuleMatch(path[:], message.format(regex_string)) + ] + + return [] + + def match_resource_properties(self, properties, _, path, cfn): + """Check CloudFormation Properties""" + matches = [] + + matches.extend( + cfn.check_value( + obj=properties, key='Description', + path=path[:], + check_value=self.check_value + )) + + return matches diff --git a/test/fixtures/templates/bad/resources/iam/managed_policy_description.yaml b/test/fixtures/templates/bad/resources/iam/managed_policy_description.yaml new file mode 100644 index 0000000000..b4711e9b39 --- /dev/null +++ b/test/fixtures/templates/bad/resources/iam/managed_policy_description.yaml @@ -0,0 +1,17 @@ +--- +AWSTemplateFormatVersion: "2010-09-09" +Resources: + SomeManagedPolicy: + Type: "AWS::IAM::ManagedPolicy" + Properties: + Description: | + Example1 + Managed Policy + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: "Allow" + Action: + - "s3:ListBucket" + - "s3:GetObject" + Resource: '*' diff --git a/test/fixtures/templates/good/resources/iam/managed_policy_description.yaml b/test/fixtures/templates/good/resources/iam/managed_policy_description.yaml new file mode 100644 index 0000000000..06ad2dece3 --- /dev/null +++ b/test/fixtures/templates/good/resources/iam/managed_policy_description.yaml @@ -0,0 +1,16 @@ +--- +AWSTemplateFormatVersion: "2010-09-09" +Resources: + SomeManagedPolicy: + Type: "AWS::IAM::ManagedPolicy" + Properties: + Description: | + Example1? Managed Policy + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: "Allow" + Action: + - "s3:ListBucket" + - "s3:GetObject" + Resource: '*' diff --git a/test/rules/resources/iam/test_iam_managed_policy_description.py b/test/rules/resources/iam/test_iam_managed_policy_description.py new file mode 100644 index 0000000000..d11ef0d8d7 --- /dev/null +++ b/test/rules/resources/iam/test_iam_managed_policy_description.py @@ -0,0 +1,37 @@ +""" + Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" +from cfnlint.rules.resources.iam.ManagedPolicyDescription import ManagedPolicyDescription # pylint: disable=E0401 +from ... import BaseRuleTestCase + + +class TestManagedPolicyDescription(BaseRuleTestCase): + """Test Managed Policy Description""" + def setUp(self): + """Setup""" + super(TestManagedPolicyDescription, self).setUp() + self.collection.register(ManagedPolicyDescription()) + self.success_templates = [ + 'fixtures/templates/good/resources/iam/managed_policy_description.yaml' + ] + + def test_file_positive(self): + """Test Positive""" + self.helper_file_positive() + + def test_file_negative(self): + """Test failure""" + self.helper_file_negative('fixtures/templates/bad/resources/iam/managed_policy_description.yaml', 1) diff --git a/tox.ini b/tox.ini index ca2e53e1dc..d73ca37d92 100644 --- a/tox.ini +++ b/tox.ini @@ -5,11 +5,13 @@ envlist = py27,py36,pylint36,pylint27 changedir = test commands = python -m unittest discover deps = - requests - aws-sam-translator>=1.6.0 + requests>=2.15.0 + six~=1.11 + aws-sam-translator>=1.8.0 jsonpatch mock - pathlib2 + pathlib2>=2.3.0 + regex>=2018.11.07 setenv = LANG=en_US.UTF-8 AWS_DEFAULT_REGION=us-east-1 @@ -19,9 +21,10 @@ changedir = basepython = python3.6 deps = pylint - requests + requests>=2.15.0 pylint-quotes jsonpatch + regex>=2018.11.07 commands=pylint --load-plugins pylint_quotes src/cfnlint [testenv:pylint27] @@ -29,7 +32,8 @@ changedir = basepython = python2.7 deps = pylint - requests + requests>=2.15.0 pylint-quotes jsonpatch + regex>=2018.11.07 commands=pylint --load-plugins pylint_quotes src/cfnlint