blob: afda47a91a4a12c2bd789efd83fd58d08ac78034 [file] [log] [blame]
Anthony Sottile8f615292022-01-15 19:24:05 -05001from __future__ import annotations
2
Anthony Sottilea7f73432020-02-29 20:34:45 -08003from unittest.mock import patch
4
Ara Hayrabedian02e8bdc2015-06-12 19:20:56 +04005import pytest
6
Anthony Sottile45756522019-02-11 19:56:15 -08007from pre_commit_hooks.detect_aws_credentials import get_aws_cred_files_from_env
Daniel Roschkab0d4cdb2016-12-30 08:41:24 +01008from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env
9from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_file
Ara Hayrabedian02e8bdc2015-06-12 19:20:56 +040010from pre_commit_hooks.detect_aws_credentials import main
11from testing.util import get_resource_path
12
13
Daniel Roschka3939aee2017-01-03 19:05:49 +010014@pytest.mark.parametrize(
15 ('env_vars', 'values'),
16 (
17 ({}, set()),
Anthony Sottilea5cf10d2021-05-14 19:12:09 -070018 ({'AWS_PLACEHOLDER_KEY': '/foo'}, set()),
Daniel Roschka3939aee2017-01-03 19:05:49 +010019 ({'AWS_CONFIG_FILE': '/foo'}, {'/foo'}),
20 ({'AWS_CREDENTIAL_FILE': '/foo'}, {'/foo'}),
21 ({'AWS_SHARED_CREDENTIALS_FILE': '/foo'}, {'/foo'}),
22 ({'BOTO_CONFIG': '/foo'}, {'/foo'}),
Anthony Sottilea5cf10d2021-05-14 19:12:09 -070023 ({'AWS_PLACEHOLDER_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar'}, {'/bar'}),
Daniel Roschka3939aee2017-01-03 19:05:49 +010024 (
25 {
Anthony Sottilea5cf10d2021-05-14 19:12:09 -070026 'AWS_PLACEHOLDER_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar',
Anthony Sottile2a902e02017-07-12 18:35:24 -070027 'AWS_CREDENTIAL_FILE': '/baz',
Daniel Roschka3939aee2017-01-03 19:05:49 +010028 },
Anthony Sottileb281d872017-07-17 17:41:44 -070029 {'/bar', '/baz'},
Daniel Roschka3939aee2017-01-03 19:05:49 +010030 ),
31 (
32 {
33 'AWS_CONFIG_FILE': '/foo', 'AWS_CREDENTIAL_FILE': '/bar',
Anthony Sottile2a902e02017-07-12 18:35:24 -070034 'AWS_SHARED_CREDENTIALS_FILE': '/baz',
Daniel Roschka3939aee2017-01-03 19:05:49 +010035 },
Anthony Sottileb281d872017-07-17 17:41:44 -070036 {'/foo', '/bar', '/baz'},
Daniel Roschka3939aee2017-01-03 19:05:49 +010037 ),
38 ),
39)
40def test_get_aws_credentials_file_from_env(env_vars, values):
Daniel Roschka3939aee2017-01-03 19:05:49 +010041 with patch.dict('os.environ', env_vars, clear=True):
Anthony Sottile45756522019-02-11 19:56:15 -080042 assert get_aws_cred_files_from_env() == values
Daniel Roschkab0d4cdb2016-12-30 08:41:24 +010043
44
Daniel Roschka3939aee2017-01-03 19:05:49 +010045@pytest.mark.parametrize(
46 ('env_vars', 'values'),
47 (
48 ({}, set()),
Anthony Sottilea5cf10d2021-05-14 19:12:09 -070049 ({'AWS_PLACEHOLDER_KEY': 'foo'}, set()),
Daniel Roschka3939aee2017-01-03 19:05:49 +010050 ({'AWS_SECRET_ACCESS_KEY': 'foo'}, {'foo'}),
51 ({'AWS_SECURITY_TOKEN': 'foo'}, {'foo'}),
52 ({'AWS_SESSION_TOKEN': 'foo'}, {'foo'}),
Alexander Demin75d48322020-02-13 12:01:38 +000053 ({'AWS_SESSION_TOKEN': ''}, set()),
54 ({'AWS_SESSION_TOKEN': 'foo', 'AWS_SECURITY_TOKEN': ''}, {'foo'}),
Anthony Sottilea5cf10d2021-05-14 19:12:09 -070055 (
56 {'AWS_PLACEHOLDER_KEY': 'foo', 'AWS_SECRET_ACCESS_KEY': 'bar'},
57 {'bar'},
58 ),
Daniel Roschka3939aee2017-01-03 19:05:49 +010059 (
60 {'AWS_SECRET_ACCESS_KEY': 'foo', 'AWS_SECURITY_TOKEN': 'bar'},
Anthony Sottile2a902e02017-07-12 18:35:24 -070061 {'foo', 'bar'},
Daniel Roschka3939aee2017-01-03 19:05:49 +010062 ),
63 ),
64)
65def test_get_aws_secrets_from_env(env_vars, values):
Daniel Roschkab0d4cdb2016-12-30 08:41:24 +010066 """Test that reading secrets from environment variables works."""
Daniel Roschka3939aee2017-01-03 19:05:49 +010067 with patch.dict('os.environ', env_vars, clear=True):
68 assert get_aws_secrets_from_env() == values
Daniel Roschkab0d4cdb2016-12-30 08:41:24 +010069
70
Daniel Roschka3939aee2017-01-03 19:05:49 +010071@pytest.mark.parametrize(
72 ('filename', 'expected_keys'),
73 (
74 (
75 'aws_config_with_secret.ini',
Anthony Sottile2a902e02017-07-12 18:35:24 -070076 {'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb'},
Daniel Roschka3939aee2017-01-03 19:05:49 +010077 ),
78 ('aws_config_with_session_token.ini', {'foo'}),
Anthony Sottilee9aea742017-07-15 12:56:51 -070079 (
80 'aws_config_with_secret_and_session_token.ini',
81 {'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb', 'foo'},
82 ),
Daniel Roschka3939aee2017-01-03 19:05:49 +010083 (
84 'aws_config_with_multiple_sections.ini',
85 {
86 '7xebzorgm5143ouge9gvepxb2z70bsb2rtrh099e',
87 'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb',
88 'ixswosj8gz3wuik405jl9k3vdajsnxfhnpui38ez',
Anthony Sottile2a902e02017-07-12 18:35:24 -070089 'foo',
90 },
Daniel Roschka3939aee2017-01-03 19:05:49 +010091 ),
92 ('aws_config_without_secrets.ini', set()),
Pablo Vega7c631b32018-01-26 15:19:01 -080093 ('aws_config_without_secrets_with_spaces.ini', set()),
Daniel Roschka3939aee2017-01-03 19:05:49 +010094 ('nonsense.txt', set()),
95 ('ok_json.json', set()),
96 ),
97)
Daniel Roschkab0d4cdb2016-12-30 08:41:24 +010098def test_get_aws_secrets_from_file(filename, expected_keys):
99 """Test that reading secrets from files works."""
100 keys = get_aws_secrets_from_file(get_resource_path(filename))
101 assert keys == expected_keys
102
103
Daniel Roschka3939aee2017-01-03 19:05:49 +0100104@pytest.mark.parametrize(
105 ('filename', 'expected_retval'),
106 (
107 ('aws_config_with_secret.ini', 1),
108 ('aws_config_with_session_token.ini', 1),
109 ('aws_config_with_multiple_sections.ini', 1),
110 ('aws_config_without_secrets.ini', 0),
Pablo Vega7c631b32018-01-26 15:19:01 -0800111 ('aws_config_without_secrets_with_spaces.ini', 0),
Daniel Roschka3939aee2017-01-03 19:05:49 +0100112 ('nonsense.txt', 0),
113 ('ok_json.json', 0),
114 ),
Ara Hayrabedian02e8bdc2015-06-12 19:20:56 +0400115)
Ara Hayrabedian02e8bdc2015-06-12 19:20:56 +0400116def test_detect_aws_credentials(filename, expected_retval):
117 # with a valid credentials file
Anthony Sottilea99475a2016-05-27 14:09:50 -0700118 ret = main((
119 get_resource_path(filename),
Anthony Sottile45756522019-02-11 19:56:15 -0800120 '--credentials-file',
121 'testing/resources/aws_config_with_multiple_sections.ini',
Anthony Sottilea99475a2016-05-27 14:09:50 -0700122 ))
Ara Hayrabedian02e8bdc2015-06-12 19:20:56 +0400123 assert ret == expected_retval
124
125
Anthony Sottile21553c22020-02-18 10:24:17 -0800126def test_allows_arbitrarily_encoded_files(tmpdir):
127 src_ini = tmpdir.join('src.ini')
128 src_ini.write(
129 '[default]\n'
130 'aws_access_key_id=AKIASDFASDF\n'
131 'aws_secret_Access_key=9018asdf23908190238123\n',
132 )
133 arbitrary_encoding = tmpdir.join('f')
134 arbitrary_encoding.write_binary(b'\x12\x9a\xe2\xf2')
135 ret = main((str(arbitrary_encoding), '--credentials-file', str(src_ini)))
136 assert ret == 0
137
138
Daniel Roschka3939aee2017-01-03 19:05:49 +0100139@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file')
140@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env')
141def test_non_existent_credentials(mock_secrets_env, mock_secrets_file, capsys):
Daniel Roschkab0d4cdb2016-12-30 08:41:24 +0100142 """Test behavior with no configured AWS secrets."""
Daniel Roschka3939aee2017-01-03 19:05:49 +0100143 mock_secrets_env.return_value = set()
144 mock_secrets_file.return_value = set()
Anthony Sottiled444ab82016-02-08 17:05:39 -0800145 ret = main((
Daniel Roschkab0d4cdb2016-12-30 08:41:24 +0100146 get_resource_path('aws_config_without_secrets.ini'),
Anthony Sottile8626e262019-02-11 19:57:37 -0800147 '--credentials-file=testing/resources/credentailsfilethatdoesntexist',
Anthony Sottiled444ab82016-02-08 17:05:39 -0800148 ))
149 assert ret == 2
150 out, _ = capsys.readouterr()
Daniel Roschka3939aee2017-01-03 19:05:49 +0100151 assert out == (
152 'No AWS keys were found in the configured credential files '
153 'and environment variables.\nPlease ensure you have the '
154 'correct setting for --credentials-file\n'
155 )
Mike Fiedler312e7212017-02-10 08:26:26 -0500156
157
158@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_file')
159@patch('pre_commit_hooks.detect_aws_credentials.get_aws_secrets_from_env')
Anthony Sottile45756522019-02-11 19:56:15 -0800160def test_non_existent_credentials_with_allow_flag(
161 mock_secrets_env, mock_secrets_file,
162):
Mike Fiedler312e7212017-02-10 08:26:26 -0500163 mock_secrets_env.return_value = set()
164 mock_secrets_file.return_value = set()
165 ret = main((
166 get_resource_path('aws_config_without_secrets.ini'),
Anthony Sottile8626e262019-02-11 19:57:37 -0800167 '--credentials-file=testing/resources/credentailsfilethatdoesntexist',
168 '--allow-missing-credentials',
Mike Fiedler312e7212017-02-10 08:26:26 -0500169 ))
170 assert ret == 0