Anthony Sottile | 8f61529 | 2022-01-15 19:24:05 -0500 | [diff] [blame^] | 1 | from __future__ import annotations |
| 2 | |
Anthony Sottile | a7f7343 | 2020-02-29 20:34:45 -0800 | [diff] [blame] | 3 | from unittest.mock import patch |
| 4 | |
Ara Hayrabedian | 02e8bdc | 2015-06-12 19:20:56 +0400 | [diff] [blame] | 5 | import pytest |
| 6 | |
Anthony Sottile | 4575652 | 2019-02-11 19:56:15 -0800 | [diff] [blame] | 7 | from pre_commit_hooks.detect_aws_credentials import get_aws_cred_files_from_env |
Daniel Roschka | b0d4cdb | 2016-12-30 08:41:24 +0100 | [diff] [blame] | 8 | from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_env |
| 9 | from pre_commit_hooks.detect_aws_credentials import get_aws_secrets_from_file |
Ara Hayrabedian | 02e8bdc | 2015-06-12 19:20:56 +0400 | [diff] [blame] | 10 | from pre_commit_hooks.detect_aws_credentials import main |
| 11 | from testing.util import get_resource_path |
| 12 | |
| 13 | |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 14 | @pytest.mark.parametrize( |
| 15 | ('env_vars', 'values'), |
| 16 | ( |
| 17 | ({}, set()), |
Anthony Sottile | a5cf10d | 2021-05-14 19:12:09 -0700 | [diff] [blame] | 18 | ({'AWS_PLACEHOLDER_KEY': '/foo'}, set()), |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 19 | ({'AWS_CONFIG_FILE': '/foo'}, {'/foo'}), |
| 20 | ({'AWS_CREDENTIAL_FILE': '/foo'}, {'/foo'}), |
| 21 | ({'AWS_SHARED_CREDENTIALS_FILE': '/foo'}, {'/foo'}), |
| 22 | ({'BOTO_CONFIG': '/foo'}, {'/foo'}), |
Anthony Sottile | a5cf10d | 2021-05-14 19:12:09 -0700 | [diff] [blame] | 23 | ({'AWS_PLACEHOLDER_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar'}, {'/bar'}), |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 24 | ( |
| 25 | { |
Anthony Sottile | a5cf10d | 2021-05-14 19:12:09 -0700 | [diff] [blame] | 26 | 'AWS_PLACEHOLDER_KEY': '/foo', 'AWS_CONFIG_FILE': '/bar', |
Anthony Sottile | 2a902e0 | 2017-07-12 18:35:24 -0700 | [diff] [blame] | 27 | 'AWS_CREDENTIAL_FILE': '/baz', |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 28 | }, |
Anthony Sottile | b281d87 | 2017-07-17 17:41:44 -0700 | [diff] [blame] | 29 | {'/bar', '/baz'}, |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 30 | ), |
| 31 | ( |
| 32 | { |
| 33 | 'AWS_CONFIG_FILE': '/foo', 'AWS_CREDENTIAL_FILE': '/bar', |
Anthony Sottile | 2a902e0 | 2017-07-12 18:35:24 -0700 | [diff] [blame] | 34 | 'AWS_SHARED_CREDENTIALS_FILE': '/baz', |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 35 | }, |
Anthony Sottile | b281d87 | 2017-07-17 17:41:44 -0700 | [diff] [blame] | 36 | {'/foo', '/bar', '/baz'}, |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 37 | ), |
| 38 | ), |
| 39 | ) |
| 40 | def test_get_aws_credentials_file_from_env(env_vars, values): |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 41 | with patch.dict('os.environ', env_vars, clear=True): |
Anthony Sottile | 4575652 | 2019-02-11 19:56:15 -0800 | [diff] [blame] | 42 | assert get_aws_cred_files_from_env() == values |
Daniel Roschka | b0d4cdb | 2016-12-30 08:41:24 +0100 | [diff] [blame] | 43 | |
| 44 | |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 45 | @pytest.mark.parametrize( |
| 46 | ('env_vars', 'values'), |
| 47 | ( |
| 48 | ({}, set()), |
Anthony Sottile | a5cf10d | 2021-05-14 19:12:09 -0700 | [diff] [blame] | 49 | ({'AWS_PLACEHOLDER_KEY': 'foo'}, set()), |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 50 | ({'AWS_SECRET_ACCESS_KEY': 'foo'}, {'foo'}), |
| 51 | ({'AWS_SECURITY_TOKEN': 'foo'}, {'foo'}), |
| 52 | ({'AWS_SESSION_TOKEN': 'foo'}, {'foo'}), |
Alexander Demin | 75d4832 | 2020-02-13 12:01:38 +0000 | [diff] [blame] | 53 | ({'AWS_SESSION_TOKEN': ''}, set()), |
| 54 | ({'AWS_SESSION_TOKEN': 'foo', 'AWS_SECURITY_TOKEN': ''}, {'foo'}), |
Anthony Sottile | a5cf10d | 2021-05-14 19:12:09 -0700 | [diff] [blame] | 55 | ( |
| 56 | {'AWS_PLACEHOLDER_KEY': 'foo', 'AWS_SECRET_ACCESS_KEY': 'bar'}, |
| 57 | {'bar'}, |
| 58 | ), |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 59 | ( |
| 60 | {'AWS_SECRET_ACCESS_KEY': 'foo', 'AWS_SECURITY_TOKEN': 'bar'}, |
Anthony Sottile | 2a902e0 | 2017-07-12 18:35:24 -0700 | [diff] [blame] | 61 | {'foo', 'bar'}, |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 62 | ), |
| 63 | ), |
| 64 | ) |
| 65 | def test_get_aws_secrets_from_env(env_vars, values): |
Daniel Roschka | b0d4cdb | 2016-12-30 08:41:24 +0100 | [diff] [blame] | 66 | """Test that reading secrets from environment variables works.""" |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 67 | with patch.dict('os.environ', env_vars, clear=True): |
| 68 | assert get_aws_secrets_from_env() == values |
Daniel Roschka | b0d4cdb | 2016-12-30 08:41:24 +0100 | [diff] [blame] | 69 | |
| 70 | |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 71 | @pytest.mark.parametrize( |
| 72 | ('filename', 'expected_keys'), |
| 73 | ( |
| 74 | ( |
| 75 | 'aws_config_with_secret.ini', |
Anthony Sottile | 2a902e0 | 2017-07-12 18:35:24 -0700 | [diff] [blame] | 76 | {'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb'}, |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 77 | ), |
| 78 | ('aws_config_with_session_token.ini', {'foo'}), |
Anthony Sottile | e9aea74 | 2017-07-15 12:56:51 -0700 | [diff] [blame] | 79 | ( |
| 80 | 'aws_config_with_secret_and_session_token.ini', |
| 81 | {'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb', 'foo'}, |
| 82 | ), |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 83 | ( |
| 84 | 'aws_config_with_multiple_sections.ini', |
| 85 | { |
| 86 | '7xebzorgm5143ouge9gvepxb2z70bsb2rtrh099e', |
| 87 | 'z2rpgs5uit782eapz5l1z0y2lurtsyyk6hcfozlb', |
| 88 | 'ixswosj8gz3wuik405jl9k3vdajsnxfhnpui38ez', |
Anthony Sottile | 2a902e0 | 2017-07-12 18:35:24 -0700 | [diff] [blame] | 89 | 'foo', |
| 90 | }, |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 91 | ), |
| 92 | ('aws_config_without_secrets.ini', set()), |
Pablo Vega | 7c631b3 | 2018-01-26 15:19:01 -0800 | [diff] [blame] | 93 | ('aws_config_without_secrets_with_spaces.ini', set()), |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 94 | ('nonsense.txt', set()), |
| 95 | ('ok_json.json', set()), |
| 96 | ), |
| 97 | ) |
Daniel Roschka | b0d4cdb | 2016-12-30 08:41:24 +0100 | [diff] [blame] | 98 | def 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 Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 104 | @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 Vega | 7c631b3 | 2018-01-26 15:19:01 -0800 | [diff] [blame] | 111 | ('aws_config_without_secrets_with_spaces.ini', 0), |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 112 | ('nonsense.txt', 0), |
| 113 | ('ok_json.json', 0), |
| 114 | ), |
Ara Hayrabedian | 02e8bdc | 2015-06-12 19:20:56 +0400 | [diff] [blame] | 115 | ) |
Ara Hayrabedian | 02e8bdc | 2015-06-12 19:20:56 +0400 | [diff] [blame] | 116 | def test_detect_aws_credentials(filename, expected_retval): |
| 117 | # with a valid credentials file |
Anthony Sottile | a99475a | 2016-05-27 14:09:50 -0700 | [diff] [blame] | 118 | ret = main(( |
| 119 | get_resource_path(filename), |
Anthony Sottile | 4575652 | 2019-02-11 19:56:15 -0800 | [diff] [blame] | 120 | '--credentials-file', |
| 121 | 'testing/resources/aws_config_with_multiple_sections.ini', |
Anthony Sottile | a99475a | 2016-05-27 14:09:50 -0700 | [diff] [blame] | 122 | )) |
Ara Hayrabedian | 02e8bdc | 2015-06-12 19:20:56 +0400 | [diff] [blame] | 123 | assert ret == expected_retval |
| 124 | |
| 125 | |
Anthony Sottile | 21553c2 | 2020-02-18 10:24:17 -0800 | [diff] [blame] | 126 | def 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 Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 139 | @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') |
| 141 | def test_non_existent_credentials(mock_secrets_env, mock_secrets_file, capsys): |
Daniel Roschka | b0d4cdb | 2016-12-30 08:41:24 +0100 | [diff] [blame] | 142 | """Test behavior with no configured AWS secrets.""" |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 143 | mock_secrets_env.return_value = set() |
| 144 | mock_secrets_file.return_value = set() |
Anthony Sottile | d444ab8 | 2016-02-08 17:05:39 -0800 | [diff] [blame] | 145 | ret = main(( |
Daniel Roschka | b0d4cdb | 2016-12-30 08:41:24 +0100 | [diff] [blame] | 146 | get_resource_path('aws_config_without_secrets.ini'), |
Anthony Sottile | 8626e26 | 2019-02-11 19:57:37 -0800 | [diff] [blame] | 147 | '--credentials-file=testing/resources/credentailsfilethatdoesntexist', |
Anthony Sottile | d444ab8 | 2016-02-08 17:05:39 -0800 | [diff] [blame] | 148 | )) |
| 149 | assert ret == 2 |
| 150 | out, _ = capsys.readouterr() |
Daniel Roschka | 3939aee | 2017-01-03 19:05:49 +0100 | [diff] [blame] | 151 | 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 Fiedler | 312e721 | 2017-02-10 08:26:26 -0500 | [diff] [blame] | 156 | |
| 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 Sottile | 4575652 | 2019-02-11 19:56:15 -0800 | [diff] [blame] | 160 | def test_non_existent_credentials_with_allow_flag( |
| 161 | mock_secrets_env, mock_secrets_file, |
| 162 | ): |
Mike Fiedler | 312e721 | 2017-02-10 08:26:26 -0500 | [diff] [blame] | 163 | 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 Sottile | 8626e26 | 2019-02-11 19:57:37 -0800 | [diff] [blame] | 167 | '--credentials-file=testing/resources/credentailsfilethatdoesntexist', |
| 168 | '--allow-missing-credentials', |
Mike Fiedler | 312e721 | 2017-02-10 08:26:26 -0500 | [diff] [blame] | 169 | )) |
| 170 | assert ret == 0 |