diff --git a/tests/test_models.py b/tests/test_models.py index 521fef6..c3ef3fe 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -120,6 +120,18 @@ def test_canonicalize_resources_just_strings(): assert models.canonicalize_resources({"foo", "bar", "baz"}) == ["bar", "baz", "foo"] +def test_canonicalize_resources_multiple_wildcards(): + """If there are resources with multiple "*" that are equivalent, at least one should be kept""" + # Chose # to make sure ordering is not affecting this test, as # < * in ascii + assert models.canonicalize_resources({"foo#", "f*#", "f**#"}) == ["f*#"] + + +def test_canonicalize_resources_wildcard_preferred_over_questionmark(): + """If there are resources with multiple "*" that are equivalent, at least one should be kept""" + + assert models.canonicalize_resources({"f*", "f?"}) == ["f*"] + + def test_canonicalize_resources_wildcards(): """If any of the resources are strings with wildcards, remove the shadowed resources.""" @@ -139,6 +151,37 @@ def test_canonicalize_resources_wildcards(): ) == ["arn:a*", "arn:ba*", "arn:bb", "arn:bc", "arn:something*"] +def test_canonicalize_resources_questionmark(): + """If any of the resources are strings with questionmarks, remove the shadowed resources.""" + + assert models.canonicalize_resources( + { + "arn:something42", + "arn:something4?", + "arn:something?2", + "arn:a?", + "arn:aa", + "arn:aaa", + } + ) == ["arn:a?", "arn:aa", "arn:aaa", "arn:something42", "arn:something4?", "arn:something?2"] + + +def test_canonicalize_resources_mixed(): + """If any of the resources are strings with wildcards and questionmarks, remove the shadowed resources.""" + + assert models.canonicalize_resources( + { + "arn:something42", + "arn:something4?", + "arn:something4*", + "arn:a??b*", + "arn:aaabccc", + "arn:aaaabccc", + "arn:aab", + } + ) == ["arn:a??b*", "arn:aaaabccc", "arn:aaabccc", "arn:aab", "arn:something4*"] + + @pytest.mark.parametrize( "statement,expected", [ diff --git a/wonk/models.py b/wonk/models.py index 40b6a53..741b2c0 100644 --- a/wonk/models.py +++ b/wonk/models.py @@ -318,7 +318,7 @@ def collect_wildcard_matches(items: Set[str]) -> Union[str, List[str]]: # Build a dict of wildcard items to their regular expressions. patterns: Dict[str, re.Pattern] = {} for item in items: - if "*" not in item: + if "*" not in item or '?' in item or '**' in item: continue pattern_string = item.replace("*", ".*") @@ -326,6 +326,7 @@ def collect_wildcard_matches(items: Set[str]) -> Union[str, List[str]]: new_items = [] for item in deduped_items(items): + print(f'testing {item}') # If this item matches any of the patterns (other than itself!), then skip it. If it # doesn't, add it to the list of items to keep. if not any(