Skip to content

Commit 3939aee

Browse files
committed
Address issues mentioned in review
1 parent 5369731 commit 3939aee

2 files changed

Lines changed: 112 additions & 81 deletions

File tree

pre_commit_hooks/detect_aws_credentials.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,23 @@
1010
def get_aws_credential_files_from_env():
1111
"""Extract credential file paths from environment variables."""
1212
files = set()
13-
for env_var in {'AWS_CONFIG_FILE', 'AWS_CREDENTIAL_FILE',
14-
'AWS_SHARED_CREDENTIALS_FILE', 'BOTO_CONFIG'}:
15-
try:
13+
for env_var in (
14+
'AWS_CONFIG_FILE', 'AWS_CREDENTIAL_FILE', 'AWS_SHARED_CREDENTIALS_FILE',
15+
'BOTO_CONFIG'
16+
):
17+
if env_var in os.environ:
1618
files.add(os.environ[env_var])
17-
except KeyError:
18-
pass
1919
return files
2020

2121

2222
def get_aws_secrets_from_env():
2323
"""Extract AWS secrets from environment variables."""
2424
keys = set()
25-
for env_var in {'AWS_SECRET_ACCESS_KEY', 'AWS_SECURITY_TOKEN',
26-
'AWS_SESSION_TOKEN'}:
27-
try:
25+
for env_var in (
26+
'AWS_SECRET_ACCESS_KEY', 'AWS_SECURITY_TOKEN', 'AWS_SESSION_TOKEN'
27+
):
28+
if env_var in os.environ:
2829
keys.add(os.environ[env_var])
29-
except KeyError:
30-
pass
3130
return keys
3231

3332

@@ -49,8 +48,10 @@ def get_aws_secrets_from_file(credentials_file):
4948

5049
keys = set()
5150
for section in parser.sections():
52-
for var in {'aws_secret_access_key', 'aws_security_token',
53-
'aws_session_token'}:
51+
for var in (
52+
'aws_secret_access_key', 'aws_security_token',
53+
'aws_session_token'
54+
):
5455
try:
5556
keys.add(parser.get(section, var))
5657
except configparser.NoOptionError:
@@ -74,7 +75,7 @@ def check_file_for_aws_keys(filenames, keys):
7475
# collision
7576
if key in text_body:
7677
bad_files.append({'filename': filename,
77-
'key': key[:4].ljust(32, str('*'))})
78+
'key': key[:4] + '*' * 28})
7879
return bad_files
7980

8081

@@ -109,16 +110,17 @@ def main(argv=None):
109110
keys |= get_aws_secrets_from_env()
110111

111112
if not keys:
112-
print('No AWS keys were found in the configured credential files and '
113-
'environment variables.\nPlease ensure you have the correct '
114-
'setting for --credentials-file')
113+
print(
114+
'No AWS keys were found in the configured credential files and '
115+
'environment variables.\nPlease ensure you have the correct '
116+
'setting for --credentials-file'
117+
)
115118
return 2
116119

117120
bad_filenames = check_file_for_aws_keys(args.filenames, keys)
118121
if bad_filenames:
119122
for bad_file in bad_filenames:
120-
print('AWS secret found in {filename}: {key}'.format(
121-
**bad_file))
123+
print('AWS secret found in {filename}: {key}'.format(**bad_file))
122124
return 1
123125
else:
124126
return 0
Lines changed: 92 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
from mock import patch
23

34
from pre_commit_hooks.detect_aws_credentials import get_aws_credential_files_from_env
45
from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env
@@ -7,72 +8,100 @@
78
from testing.util import get_resource_path
89

910

10-
def test_get_aws_credentials_file_from_env(monkeypatch):
11+
@pytest.mark.parametrize(
12+
('env_vars', 'values'),
13+
(
14+
({}, set()),
15+
({'AWS_DUMMY_KEY': '/foo'}, set()),
16+
({'AWS_CONFIG_FILE': '/foo'}, {'/foo'}),
17+
({'AWS_CREDENTIAL_FILE': '/foo'}, {'/foo'}),
18+
({'AWS_SHARED_CREDENTIALS_FILE': '/foo'}, {'/foo'}),
19+
({'BOTO_CONFIG': '/foo'}, {'/foo'}),
20+
({'AWS_DUMMY_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar'}, {'/bar'}),
21+
(
22+
{
23+
'AWS_DUMMY_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar',
24+
'AWS_CREDENTIAL_FILE': '/baz'
25+
},
26+
{'/bar', '/baz'}
27+
),
28+
(
29+
{
30+
'AWS_CONFIG_FILE': '/foo', 'AWS_CREDENTIAL_FILE': '/bar',
31+
'AWS_SHARED_CREDENTIALS_FILE': '/baz'
32+
},
33+
{'/foo', '/bar', '/baz'}
34+
),
35+
),
36+
)
37+
def test_get_aws_credentials_file_from_env(env_vars, values):
1138
"""Test that reading credential files names from environment variables works."""
12-
monkeypatch.delenv('AWS_CREDENTIAL_FILE', raising=False)
13-
monkeypatch.delenv('AWS_SHARED_CREDENTIALS_FILE', raising=False)
14-
monkeypatch.delenv('BOTO_CONFIG', raising=False)
15-
assert get_aws_credential_files_from_env() == set()
16-
monkeypatch.setenv('AWS_CREDENTIAL_FILE', '/foo')
17-
assert get_aws_credential_files_from_env() == {'/foo'}
18-
monkeypatch.setenv('AWS_SHARED_CREDENTIALS_FILE', '/bar')
19-
assert get_aws_credential_files_from_env() == {'/foo', '/bar'}
20-
monkeypatch.setenv('BOTO_CONFIG', '/baz')
21-
assert get_aws_credential_files_from_env() == {'/foo', '/bar', '/baz'}
22-
monkeypatch.setenv('AWS_CONFIG_FILE', '/xxx')
23-
assert get_aws_credential_files_from_env() == {'/foo', '/bar', '/baz', '/xxx'}
24-
monkeypatch.setenv('AWS_DUMMY_KEY', 'foobar')
25-
assert get_aws_credential_files_from_env() == {'/foo', '/bar', '/baz', '/xxx'}
39+
with patch.dict('os.environ', env_vars, clear=True):
40+
assert get_aws_credential_files_from_env() == values
2641

2742

28-
def test_get_aws_secrets_from_env(monkeypatch):
43+
@pytest.mark.parametrize(
44+
('env_vars', 'values'),
45+
(
46+
({}, set()),
47+
({'AWS_DUMMY_KEY': 'foo'}, set()),
48+
({'AWS_SECRET_ACCESS_KEY': 'foo'}, {'foo'}),
49+
({'AWS_SECURITY_TOKEN': 'foo'}, {'foo'}),
50+
({'AWS_SESSION_TOKEN': 'foo'}, {'foo'}),
51+
({'AWS_DUMMY_KEY': 'foo', 'AWS_SECRET_ACCESS_KEY': 'bar'}, {'bar'}),
52+
(
53+
{'AWS_SECRET_ACCESS_KEY': 'foo', 'AWS_SECURITY_TOKEN': 'bar'},
54+
{'foo', 'bar'}
55+
),
56+
),
57+
)
58+
def test_get_aws_secrets_from_env(env_vars, values):
2959
"""Test that reading secrets from environment variables works."""
30-
monkeypatch.delenv('AWS_SECRET_ACCESS_KEY', raising=False)
31-
monkeypatch.delenv('AWS_SESSION_TOKEN', raising=False)
32-
assert get_aws_secrets_from_env() == set()
33-
monkeypatch.setenv('AWS_SECRET_ACCESS_KEY', 'foo')
34-
assert get_aws_secrets_from_env() == {'foo'}
35-
monkeypatch.setenv('AWS_SESSION_TOKEN', 'bar')
36-
assert get_aws_secrets_from_env() == {'foo', 'bar'}
37-
monkeypatch.setenv('AWS_SECURITY_TOKEN', 'baz')
38-
assert get_aws_secrets_from_env() == {'foo', 'bar', 'baz'}
39-
monkeypatch.setenv('AWS_DUMMY_KEY', 'baz')
40-
assert get_aws_secrets_from_env() == {'foo', 'bar', 'baz'}
60+
with patch.dict('os.environ', env_vars, clear=True):
61+
assert get_aws_secrets_from_env() == values
4162

4263

43-
@pytest.mark.parametrize(('filename', 'expected_keys'), (
44-
('aws_config_with_secret.ini', {
45-
'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb'}),
46-
('aws_config_with_session_token.ini', {'foo'}),
47-
('aws_config_with_secret_and_session_token.ini',
48-
{'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb', 'foo'}),
49-
('aws_config_with_multiple_sections.ini', {
50-
'7xebzorgm5143ouge9gvepxb2z70bsb2rtrh099e',
51-
'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb',
52-
'ixswosj8gz3wuik405jl9k3vdajsnxfhnpui38ez',
53-
'foo'}),
54-
('aws_config_without_secrets.ini', set()),
55-
('nonsense.txt', set()),
56-
('ok_json.json', set()),
57-
))
64+
@pytest.mark.parametrize(
65+
('filename', 'expected_keys'),
66+
(
67+
(
68+
'aws_config_with_secret.ini',
69+
{'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb'}
70+
),
71+
('aws_config_with_session_token.ini', {'foo'}),
72+
('aws_config_with_secret_and_session_token.ini',
73+
{'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb', 'foo'}),
74+
(
75+
'aws_config_with_multiple_sections.ini',
76+
{
77+
'7xebzorgm5143ouge9gvepxb2z70bsb2rtrh099e',
78+
'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb',
79+
'ixswosj8gz3wuik405jl9k3vdajsnxfhnpui38ez',
80+
'foo'
81+
}
82+
),
83+
('aws_config_without_secrets.ini', set()),
84+
('nonsense.txt', set()),
85+
('ok_json.json', set()),
86+
),
87+
)
5888
def test_get_aws_secrets_from_file(filename, expected_keys):
5989
"""Test that reading secrets from files works."""
6090
keys = get_aws_secrets_from_file(get_resource_path(filename))
6191
assert keys == expected_keys
6292

6393

64-
# Input filename, expected return value
65-
TESTS = (
66-
('aws_config_with_secret.ini', 1),
67-
('aws_config_with_session_token.ini', 1),
68-
('aws_config_with_multiple_sections.ini', 1),
69-
('aws_config_without_secrets.ini', 0),
70-
('nonsense.txt', 0),
71-
('ok_json.json', 0),
94+
@pytest.mark.parametrize(
95+
('filename', 'expected_retval'),
96+
(
97+
('aws_config_with_secret.ini', 1),
98+
('aws_config_with_session_token.ini', 1),
99+
('aws_config_with_multiple_sections.ini', 1),
100+
('aws_config_without_secrets.ini', 0),
101+
('nonsense.txt', 0),
102+
('ok_json.json', 0),
103+
),
72104
)
73-
74-
75-
@pytest.mark.parametrize(('filename', 'expected_retval'), TESTS)
76105
def test_detect_aws_credentials(filename, expected_retval):
77106
"""Test if getting configured AWS secrets from files to be checked in works."""
78107

@@ -84,20 +113,20 @@ def test_detect_aws_credentials(filename, expected_retval):
84113
assert ret == expected_retval
85114

86115

87-
def test_non_existent_credentials(capsys, monkeypatch):
116+
@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file')
117+
@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env')
118+
def test_non_existent_credentials(mock_secrets_env, mock_secrets_file, capsys):
88119
"""Test behavior with no configured AWS secrets."""
89-
monkeypatch.setattr(
90-
'pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env',
91-
lambda: set())
92-
monkeypatch.setattr(
93-
'pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file',
94-
lambda x: set())
120+
mock_secrets_env.return_value = set()
121+
mock_secrets_file.return_value = set()
95122
ret = main((
96123
get_resource_path('aws_config_without_secrets.ini'),
97124
"--credentials-file=testing/resources/credentailsfilethatdoesntexist"
98125
))
99126
assert ret == 2
100127
out, _ = capsys.readouterr()
101-
assert out == ('No AWS keys were found in the configured credential files '
102-
'and environment variables.\nPlease ensure you have the '
103-
'correct setting for --credentials-file\n')
128+
assert out == (
129+
'No AWS keys were found in the configured credential files '
130+
'and environment variables.\nPlease ensure you have the '
131+
'correct setting for --credentials-file\n'
132+
)

0 commit comments

Comments
 (0)