Skip to content

Commit

Permalink
Merge pull request #389 from webratz/master
Browse files Browse the repository at this point in the history
extended title validation
  • Loading branch information
phobologic committed Mar 1, 2016
2 parents ba52277 + 196a558 commit 2afa223
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 9 deletions.
29 changes: 29 additions & 0 deletions tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from troposphere.validators import boolean, integer, integer_range
from troposphere.validators import positive_integer, network_port
from troposphere.validators import s3_bucket_name, encoding, status
from troposphere.validators import iam_path, iam_names, iam_role_name
from troposphere.validators import iam_group_name


class TestValidators(unittest.TestCase):
Expand Down Expand Up @@ -79,6 +81,33 @@ def test_status(self):
with self.assertRaises(ValueError):
status(s)

def test_iam_names(self):
for s in ['foobar.+=@-,', 'BARfoo789.+=@-,']:
iam_names(s)
for s in ['foo%', 'bar$']:
with self.assertRaises(ValueError):
iam_names(s)

def test_iam_path(self):
for s in ['/%s/' % ('a'*30), '/%s/' % ('a'*510)]:
iam_path(s)
for s in ['/%s/' % ('a'*511), '/%s/' % ('a'*1025)]:
with self.assertRaises(ValueError):
iam_path(s)

def test_iam_role_name(self):
for s in ['a'*30, 'a'*64]:
iam_role_name(s)
for s in ['a'*65, 'a'*128]:
with self.assertRaises(ValueError):
iam_role_name(s)

def test_iam_group_name(self):
for s in ['a'*64, 'a'*128]:
iam_group_name(s)
for s in ['a'*129, 'a'*256]:
with self.assertRaises(ValueError):
iam_group_name(s)

if __name__ == '__main__':
unittest.main()
10 changes: 7 additions & 3 deletions troposphere/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def __init__(self, title, template=None, **kwargs):
'Metadata', 'UpdatePolicy',
'Condition', 'CreationPolicy']

# unset/None is also legal
if title and not valid_names.match(title):
raise ValueError('Name "%s" not alphanumeric' % title)
# try to validate the title if its there
if self.title:
self.validate_title()

# Create the list of properties set on this object by the user
self.properties = {}
Expand Down Expand Up @@ -154,6 +154,10 @@ def _raise_type(self, name, value, expected_type):
type(value),
expected_type))

def validate_title(self):
if not valid_names.match(self.title):
raise ValueError('Name "%s" not alphanumeric' % self.title)

def validate(self):
pass

Expand Down
18 changes: 13 additions & 5 deletions troposphere/iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

from . import AWSObject, AWSProperty, Ref
from .validators import integer, boolean, status
from .validators import iam_path, iam_role_name, iam_group_name

try:
from awacs.aws import Policy
policytypes = (dict, Policy)
Expand Down Expand Up @@ -49,11 +51,14 @@ class Policy(AWSProperty):


class Group(AWSObject):
def validate_title(self):
iam_group_name(self.title)

resource_type = "AWS::IAM::Group"

props = {
'ManagedPolicyArns': ([basestring], False),
'Path': (basestring, False),
'Path': (iam_path, False),
'Policies': ([Policy], False),
}

Expand All @@ -62,18 +67,21 @@ class InstanceProfile(AWSObject):
resource_type = "AWS::IAM::InstanceProfile"

props = {
'Path': (basestring, False),
'Path': (iam_path, False),
'Roles': (list, True),
}


class Role(AWSObject):
def validate_title(self):
iam_role_name(self.title)

resource_type = "AWS::IAM::Role"

props = {
'AssumeRolePolicyDocument': (policytypes, True),
'ManagedPolicyArns': ([basestring], False),
'Path': (basestring, False),
'Path': (iam_path, False),
'Policies': ([Policy], False),
}

Expand All @@ -89,7 +97,7 @@ class User(AWSObject):
resource_type = "AWS::IAM::User"

props = {
'Path': (basestring, False),
'Path': (iam_path, False),
'Groups': ([basestring, Ref], False),
'ManagedPolicyArns': ([basestring], False),
'LoginProfile': (LoginProfile, False),
Expand All @@ -112,7 +120,7 @@ class ManagedPolicy(AWSObject):
props = {
'Description': (basestring, False),
'Groups': ([basestring, Ref], False),
'Path': (basestring, False),
'Path': (iam_path, False),
'PolicyDocument': (policytypes, True),
'Roles': ([basestring, Ref], False),
'Users': ([basestring, Ref], False),
Expand Down
34 changes: 33 additions & 1 deletion troposphere/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# All rights reserved.
#
# See LICENSE file for full license.
from re import compile


def boolean(x):
Expand Down Expand Up @@ -53,7 +54,6 @@ def network_port(x):


def s3_bucket_name(b):
from re import compile
s3_bucket_name_re = compile(r'^[a-z\d][a-z\d\.-]{1,61}[a-z\d]$')
if s3_bucket_name_re.match(b):
return b
Expand All @@ -73,3 +73,35 @@ def status(status):
if status not in valid_statuses:
raise ValueError('Status needs to be one of %r' % valid_statuses)
return status


def iam_names(b):
iam_name_re = compile(r'^[a-zA-Z0-9_\.\+\=\@\-\,]+$')
if iam_name_re.match(b):
return b
else:
raise ValueError("%s is not a valid iam name" % b)


def iam_path(path):
if len(path) > 512:
raise ValueError('IAM path %s may not exceed 512 characters', path)

iam_path_re = compile(r'^\/.*\/$|^\/$')
if not iam_path_re.match(path):
raise ValueError("%s is not a valid iam path name" % path)
return path


def iam_role_name(role_name):
if len(role_name) > 64:
raise ValueError('IAM Role Name may not exceed 64 characters')
iam_names(role_name)
return role_name


def iam_group_name(group_name):
if len(group_name) > 128:
raise ValueError('IAM Role Name may not exceed 128 characters')
iam_names(group_name)
return group_name

0 comments on commit 2afa223

Please sign in to comment.