Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

Commit

Permalink
Regex match (#1244)
Browse files Browse the repository at this point in the history
* Make regex match non-greedy to ensure matched string matches policy.
  • Loading branch information
ahoying committed Mar 12, 2018
1 parent 2c7f17d commit a28c699
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 23 deletions.
24 changes: 3 additions & 21 deletions google/cloud/security/common/gcp_type/iam_policy.py
Expand Up @@ -19,25 +19,7 @@
import re

from google.cloud.security.common.gcp_type import errors


# TODO: use the regex_util
def _escape_and_globify(pattern_string):
"""Given a pattern string with a glob, create actual regex pattern.
To require > 0 length glob, change the "*" to ".+". This is to handle
strings like "*@company.com". (THe actual regex would probably be
".*@company.com", except that we don't want to match zero-length
usernames before the "@".)
Args:
pattern_string (str): The pattern string of which to make a regex.
Returns:
str: The pattern string, escaped except for the "*", which is
transformed into ".+" (match on one or more characters).
"""
return '^{}$'.format(re.escape(pattern_string).replace('\\*', '.+'))
from google.cloud.security.common.util.regex_util import escape_and_globify


def _get_iam_members(members):
Expand Down Expand Up @@ -137,7 +119,7 @@ def __init__(self, role_name, members=None):
'role_name={}, members={}'.format(role_name, members)))
self.role_name = role_name
self.members = _get_iam_members(members)
self.role_pattern = re.compile(_escape_and_globify(role_name),
self.role_pattern = re.compile(escape_and_globify(role_name),
flags=re.IGNORECASE)

def __eq__(self, other):
Expand Down Expand Up @@ -217,7 +199,7 @@ def __init__(self, member_type, member_name=None):
self.name = member_name
self.name_pattern = None
if member_name:
self.name_pattern = re.compile(_escape_and_globify(self.name),
self.name_pattern = re.compile(escape_and_globify(self.name),
flags=re.IGNORECASE)

def __eq__(self, other):
Expand Down
6 changes: 5 additions & 1 deletion google/cloud/security/common/util/regex_util.py
Expand Up @@ -24,11 +24,15 @@ def escape_and_globify(pattern_string):
".*@company.com", except that we don't want to match zero-length
usernames before the "@".)
Special case the pattern '*' to match 0 or more characters.
Args:
pattern_string (str): The pattern string of which to make a regex.
Returns:
str: The pattern string, escaped except for the "*", which is
transformed into ".+" (match on one or more characters).
"""
return '^{}$'.format(re.escape(pattern_string).replace('\\*', '.*'))
if pattern_string == '*':
return '^.*$'
return '^{}$'.format(re.escape(pattern_string).replace('\\*', '.+?'))
6 changes: 5 additions & 1 deletion tests/common/gcp_type/iam_policy_test.py
Expand Up @@ -92,6 +92,10 @@ def test_member_match_works(self):
'user:not-user@company.com'))
self.assertFalse(iam_policy_members[2].matches(
'user:anyone@not.company.com'))
self.assertFalse(iam_policy_members[2].matches(
'user:anyone@notmycompany.com'))
self.assertFalse(iam_policy_members[2].matches(
'user:anyone@mycompany.com.notmycompany.com'))
self.assertFalse(iam_policy_members[3].matches(
'serviceAccount:someone@gserviceaccount.com'))
self.assertFalse(iam_policy_members[3].matches(
Expand Down Expand Up @@ -123,7 +127,7 @@ def test_binding_create_from_is_correct(self):
'members': self.test_members
}
iam_binding2 = IamPolicyBinding.create_from(binding2)
self.assertEqual('^roles\/.+$', iam_binding2.role_pattern.pattern)
self.assertEqual('^roles\/.+?$', iam_binding2.role_pattern.pattern)

def test_binding_missing_role_raises(self):
"""Test that a binding with no role raises an exception."""
Expand Down

0 comments on commit a28c699

Please sign in to comment.