From 0938325c6440b1ac0393f5a2cc2c1fc09e6dc8c7 Mon Sep 17 00:00:00 2001 From: John Walker Date: Mon, 15 Jul 2019 11:08:04 -0700 Subject: [PATCH 01/12] Update PR template --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ab40d21d7..176df025b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -4,3 +4,7 @@ By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. + +# Check any applicable: +- [ ] Were any files moved? Moving files changes their URL, which breaks all hyperlinks to the files. + From ee1b4cc11ca182211dcd932569b7ab64879f8245 Mon Sep 17 00:00:00 2001 From: Caitlin Tibbetts Date: Mon, 22 Jul 2019 14:51:25 -0700 Subject: [PATCH 02/12] Added a check for max_age being greater than 0 (#172) * Added a check for max_age being greater than 0 * Fixed flake8 by adding missing pydocstyle dependency * Added the dependency to decrypt_oracle as well * Added test for max_age<=0 ValueError * Updated test for max_age<=0.0 ValueError * Added negative test case --- decrypt_oracle/tox.ini | 1 + src/aws_encryption_sdk/materials_managers/caching.py | 3 +++ test/unit/test_material_managers_caching.py | 2 ++ tox.ini | 1 + 4 files changed, 7 insertions(+) diff --git a/decrypt_oracle/tox.ini b/decrypt_oracle/tox.ini index 60aea91c7..f0a7804e5 100644 --- a/decrypt_oracle/tox.ini +++ b/decrypt_oracle/tox.ini @@ -156,6 +156,7 @@ basepython = python3 deps = flake8 flake8-docstrings + pydocstyle<4.0.0 # https://github.com/JBKahn/flake8-print/pull/30 flake8-print>=3.1.0 commands = diff --git a/src/aws_encryption_sdk/materials_managers/caching.py b/src/aws_encryption_sdk/materials_managers/caching.py index b2bdcba9f..992a39a7a 100644 --- a/src/aws_encryption_sdk/materials_managers/caching.py +++ b/src/aws_encryption_sdk/materials_managers/caching.py @@ -108,6 +108,9 @@ def __attrs_post_init__(self): if self.max_bytes_encrypted > MAX_BYTES_PER_KEY: raise ValueError("max_bytes_encrypted cannot exceed {}".format(MAX_BYTES_PER_KEY)) + if self.max_age <= 0.0: + raise ValueError("max_age cannot be less than or equal to 0") + if self.backing_materials_manager is None: if self.master_key_provider is None: raise TypeError("Either backing_materials_manager or master_key_provider must be defined") diff --git a/test/unit/test_material_managers_caching.py b/test/unit/test_material_managers_caching.py index 426fe3348..833d6aa53 100644 --- a/test/unit/test_material_managers_caching.py +++ b/test/unit/test_material_managers_caching.py @@ -117,6 +117,8 @@ def test_mkp_to_default_cmm(mocker): dict(max_bytes_encrypted=MAX_BYTES_PER_KEY + 1), r"max_bytes_encrypted cannot exceed {}".format(MAX_BYTES_PER_KEY), ), + (dict(max_age=0.0), r"max_age cannot be less than or equal to 0"), + (dict(max_age=-1.0), r"max_age cannot be less than or equal to 0"), ), ) def test_invalid_values(invalid_kwargs, error_message): diff --git a/tox.ini b/tox.ini index e13ea2cb8..06564ef6a 100644 --- a/tox.ini +++ b/tox.ini @@ -117,6 +117,7 @@ basepython = python3 deps = flake8 flake8-docstrings + pydocstyle<4.0.0 # https://github.com/JBKahn/flake8-print/pull/30 flake8-print>=3.1.0 flake8-bugbear From 1de8d5cf6aaabb7ea4d5de20e5defaafdc61b614 Mon Sep 17 00:00:00 2001 From: Ryan Ragona Date: Fri, 2 Aug 2019 07:33:25 -0800 Subject: [PATCH 03/12] Fixed KMS master key provider tests when default AWS region is configured (#179) * Fixed KMS master key provider tests for users who have their default AWS region configured * created fixture for botocore session with no region set * add auto-used fixture in KMS master key provider unit tests to test against both with and without default region --- .../test_providers_kms_master_key_provider.py | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/test/unit/test_providers_kms_master_key_provider.py b/test/unit/test_providers_kms_master_key_provider.py index 48802a36f..9a122e622 100644 --- a/test/unit/test_providers_kms_master_key_provider.py +++ b/test/unit/test_providers_kms_master_key_provider.py @@ -12,6 +12,7 @@ # language governing permissions and limitations under the License. """Unit test suite from aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider""" import botocore.client +import botocore.session import pytest from mock import ANY, MagicMock, call, patch, sentinel @@ -22,6 +23,19 @@ pytestmark = [pytest.mark.unit, pytest.mark.local] +@pytest.fixture(autouse=True, params=[True, False], ids=["default region", "no default region"]) +def patch_default_region(request, monkeypatch): + """Run all tests in this module both with a default region set and no default region set. + + This ensures that we do not regress on default region handling. + https://github.com/aws/aws-encryption-sdk-python/issues/31 + """ + if request.param: + monkeypatch.setenv("AWS_DEFAULT_REGION", "us-west-2") + else: + monkeypatch.delenv("AWS_DEFAULT_REGION", raising=False) + + def test_init_with_regionless_key_ids_and_region_names(): key_ids = ("alias/key_1",) region_names = ("test-region-1",) @@ -32,6 +46,7 @@ def test_init_with_regionless_key_ids_and_region_names(): class TestKMSMasterKeyProvider(object): @pytest.fixture(autouse=True) def apply_fixtures(self): + self.botocore_no_region_session = botocore.session.Session(session_vars={"region": (None, None, None, None)}) self.mock_botocore_session_patcher = patch("aws_encryption_sdk.key_providers.kms.botocore.session.Session") self.mock_botocore_session = self.mock_botocore_session_patcher.start() self.mock_boto3_session_patcher = patch("aws_encryption_sdk.key_providers.kms.boto3.session.Session") @@ -69,7 +84,7 @@ def test_init_with_region_names(self, mock_add_clients): @patch("aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider.add_regional_client") def test_init_with_default_region_found(self, mock_add_regional_client): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) assert test.default_region is None with patch.object( test.config.botocore_session, "get_config_variable", return_value=sentinel.default_region @@ -77,11 +92,11 @@ def test_init_with_default_region_found(self, mock_add_regional_client): test._process_config() mock_get_config.assert_called_once_with("region") assert test.default_region is sentinel.default_region - mock_add_regional_client.assert_called_once_with(sentinel.default_region) + mock_add_regional_client.assert_called_with(sentinel.default_region) @patch("aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider.add_regional_client") def test_init_with_default_region_not_found(self, mock_add_regional_client): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) assert test.default_region is None with patch.object(test.config.botocore_session, "get_config_variable", return_value=None) as mock_get_config: test._process_config() @@ -93,12 +108,12 @@ def test_add_regional_client_new(self): test = KMSMasterKeyProvider() test._regional_clients = {} test.add_regional_client("ex_region_name") - self.mock_boto3_session.assert_called_once_with(region_name="ex_region_name", botocore_session=ANY) - self.mock_boto3_session_instance.client.assert_called_once_with("kms", config=test._user_agent_adding_config) + self.mock_boto3_session.assert_called_with(region_name="ex_region_name", botocore_session=ANY) + self.mock_boto3_session_instance.client.assert_called_with("kms", config=test._user_agent_adding_config) assert test._regional_clients["ex_region_name"] is self.mock_boto3_client_instance def test_add_regional_client_exists(self): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) test._regional_clients["ex_region_name"] = sentinel.existing_client test.add_regional_client("ex_region_name") assert not self.mock_boto3_session.called @@ -114,7 +129,7 @@ def test_client_valid_region_name(self, mock_add_client): test = KMSMasterKeyProvider() test._regional_clients["us-east-1"] = self.mock_boto3_client_instance client = test._client("arn:aws:kms:us-east-1:222222222222:key/aaaaaaaa-1111-2222-3333-bbbbbbbbbbbb") - mock_add_client.assert_called_once_with("us-east-1") + mock_add_client.assert_called_with("us-east-1") assert client is self.mock_boto3_client_instance @patch("aws_encryption_sdk.key_providers.kms.KMSMasterKeyProvider.add_regional_client") @@ -124,10 +139,10 @@ def test_client_no_region_name_with_default(self, mock_add_client): test._regional_clients[sentinel.default_region] = sentinel.default_client client = test._client("") assert client is sentinel.default_client - mock_add_client.assert_called_once_with(sentinel.default_region) + mock_add_client.assert_called_with(sentinel.default_region) def test_client_no_region_name_without_default(self): - test = KMSMasterKeyProvider() + test = KMSMasterKeyProvider(botocore_session=self.botocore_no_region_session) with pytest.raises(UnknownRegionError) as excinfo: test._client("") excinfo.match("No default region found and no region determinable from key id: *") From baf1164c13f5231f3532cc2b6e2b59f163357cca Mon Sep 17 00:00:00 2001 From: Caitlin Tibbetts Date: Fri, 2 Aug 2019 11:49:05 -0700 Subject: [PATCH 04/12] Wrote example and test for using one kms cmk with an unsigned algorithm --- examples/src/one_kms_cmk_unsigned.py | 51 ++++++++++++++++++++ examples/test/test_i_one_kms_cmk_unsigned.py | 29 +++++++++++ 2 files changed, 80 insertions(+) create mode 100644 examples/src/one_kms_cmk_unsigned.py create mode 100644 examples/test/test_i_one_kms_cmk_unsigned.py diff --git a/examples/src/one_kms_cmk_unsigned.py b/examples/src/one_kms_cmk_unsigned.py new file mode 100644 index 000000000..235a8ac06 --- /dev/null +++ b/examples/src/one_kms_cmk_unsigned.py @@ -0,0 +1,51 @@ +# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +"""Example showing basic encryption and decryption of a value already in memory +using one KMS CMK with an unsigned algorithm. +""" +import aws_encryption_sdk +from aws_encryption_sdk.identifiers import Algorithm + + +def encrypt_decrypt(key_arn, source_plaintext, botocore_session=None): + """Encrypts and then decrypts a string under one KMS customer master key (CMK) with an unsigned algorithm. + + :param str key_arn: Amazon Resource Name (ARN) of the KMS CMK + :param bytes source_plaintext: Data to encrypt + :param botocore_session: existing botocore session instance + :type botocore_session: botocore.session.Session + """ + kwargs = dict(key_ids=[key_arn]) + + if botocore_session is not None: + kwargs["botocore_session"] = botocore_session + + # Create master key provider using the ARN of the key and the session (botocore_session) + kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kwargs) + + # Encrypt the plaintext using the AWS Encryption SDK. It returns the encrypted message and the header + ciphertext, encrypted_message_header = aws_encryption_sdk.encrypt( + algorithm=Algorithm.AES_256_GCM_IV12_TAG16, source=source_plaintext, key_provider=kms_key_provider + ) + + # Decrypt the encrypted message using the AWS Encryption SDK. It returns the decrypted message and the header + plaintext, decrypted_message_header = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=kms_key_provider) + + # Check if the original message and the decrypted message are the same + assert source_plaintext == plaintext + + # Check if the headers of the encrypted message and decrypted message match + assert all( + pair in encrypted_message_header.encryption_context.items() + for pair in decrypted_message_header.encryption_context.items() + ) diff --git a/examples/test/test_i_one_kms_cmk_unsigned.py b/examples/test/test_i_one_kms_cmk_unsigned.py new file mode 100644 index 000000000..8a2758c96 --- /dev/null +++ b/examples/test/test_i_one_kms_cmk_unsigned.py @@ -0,0 +1,29 @@ +# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. +"""Unit test suite for the encryption and decryption using one KMS CMK with an unsigned algorithm example.""" + +import botocore.session +import pytest + +from ..src.one_kms_cmk_unsigned import encrypt_decrypt +from .examples_test_utils import get_cmk_arn +from .examples_test_utils import static_plaintext + + +pytestmark = [pytest.mark.examples] + + +def test_one_kms_cmk_unsigned(): + plaintext = static_plaintext + cmk_arn = get_cmk_arn() + encrypt_decrypt(key_arn=cmk_arn, source_plaintext=plaintext, botocore_session=botocore.session.Session()) From a7fcb4a01b6c14628eabcd1c18b9c4112c556b48 Mon Sep 17 00:00:00 2001 From: Caitlin Tibbetts Date: Tue, 6 Aug 2019 14:45:05 -0700 Subject: [PATCH 05/12] Update one_kms_cmk_unsigned.py --- examples/src/one_kms_cmk_unsigned.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/src/one_kms_cmk_unsigned.py b/examples/src/one_kms_cmk_unsigned.py index 235a8ac06..4c4e737bd 100644 --- a/examples/src/one_kms_cmk_unsigned.py +++ b/examples/src/one_kms_cmk_unsigned.py @@ -14,6 +14,7 @@ using one KMS CMK with an unsigned algorithm. """ import aws_encryption_sdk +from aws_encryption_sdk import encrypt, decrypt from aws_encryption_sdk.identifiers import Algorithm @@ -34,12 +35,12 @@ def encrypt_decrypt(key_arn, source_plaintext, botocore_session=None): kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kwargs) # Encrypt the plaintext using the AWS Encryption SDK. It returns the encrypted message and the header - ciphertext, encrypted_message_header = aws_encryption_sdk.encrypt( + ciphertext, encrypted_message_header = encrypt( algorithm=Algorithm.AES_256_GCM_IV12_TAG16, source=source_plaintext, key_provider=kms_key_provider ) # Decrypt the encrypted message using the AWS Encryption SDK. It returns the decrypted message and the header - plaintext, decrypted_message_header = aws_encryption_sdk.decrypt(source=ciphertext, key_provider=kms_key_provider) + plaintext, decrypted_message_header = decrypt(source=ciphertext, key_provider=kms_key_provider) # Check if the original message and the decrypted message are the same assert source_plaintext == plaintext From 862734a027059dd34d16e89d76e8b85b66aa0653 Mon Sep 17 00:00:00 2001 From: Caitlin Tibbetts Date: Tue, 6 Aug 2019 14:45:27 -0700 Subject: [PATCH 06/12] Update examples/src/one_kms_cmk_unsigned.py Co-Authored-By: Matt Bullock --- examples/src/one_kms_cmk_unsigned.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/src/one_kms_cmk_unsigned.py b/examples/src/one_kms_cmk_unsigned.py index 4c4e737bd..1b7a24533 100644 --- a/examples/src/one_kms_cmk_unsigned.py +++ b/examples/src/one_kms_cmk_unsigned.py @@ -36,7 +36,7 @@ def encrypt_decrypt(key_arn, source_plaintext, botocore_session=None): # Encrypt the plaintext using the AWS Encryption SDK. It returns the encrypted message and the header ciphertext, encrypted_message_header = encrypt( - algorithm=Algorithm.AES_256_GCM_IV12_TAG16, source=source_plaintext, key_provider=kms_key_provider + algorithm=Algorithm.AES_256_GCM_IV12_TAG16_HKDF_SHA256, source=source_plaintext, key_provider=kms_key_provider ) # Decrypt the encrypted message using the AWS Encryption SDK. It returns the decrypted message and the header From 4def8ba64a4ac9ce692dab4a30b7a6aca1ab6b30 Mon Sep 17 00:00:00 2001 From: Caitlin Tibbetts Date: Wed, 7 Aug 2019 09:40:14 -0700 Subject: [PATCH 07/12] isort-check now succeeds --- examples/src/one_kms_cmk_unsigned.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/src/one_kms_cmk_unsigned.py b/examples/src/one_kms_cmk_unsigned.py index 1b7a24533..df2f4373d 100644 --- a/examples/src/one_kms_cmk_unsigned.py +++ b/examples/src/one_kms_cmk_unsigned.py @@ -13,8 +13,7 @@ """Example showing basic encryption and decryption of a value already in memory using one KMS CMK with an unsigned algorithm. """ -import aws_encryption_sdk -from aws_encryption_sdk import encrypt, decrypt +from aws_encryption_sdk import KMSMasterKeyProvider, decrypt, encrypt from aws_encryption_sdk.identifiers import Algorithm @@ -32,7 +31,7 @@ def encrypt_decrypt(key_arn, source_plaintext, botocore_session=None): kwargs["botocore_session"] = botocore_session # Create master key provider using the ARN of the key and the session (botocore_session) - kms_key_provider = aws_encryption_sdk.KMSMasterKeyProvider(**kwargs) + kms_key_provider = KMSMasterKeyProvider(**kwargs) # Encrypt the plaintext using the AWS Encryption SDK. It returns the encrypted message and the header ciphertext, encrypted_message_header = encrypt( From 7ef7aa290b4454242d0d2811505b253f92a66eae Mon Sep 17 00:00:00 2001 From: Bohdan Date: Fri, 20 Sep 2019 21:10:12 +0300 Subject: [PATCH 08/12] [issue-190] Regional clients modify default botocore session (#193) * [issue-190] Creation of regional clients modifies default botocore session's region --- src/aws_encryption_sdk/key_providers/kms.py | 4 ++-- test/integration/integration_test_utils.py | 19 +++++++++++++++++++ .../test_i_aws_encrytion_sdk_client.py | 15 ++++++++++++++- .../test_providers_kms_master_key_provider.py | 8 ++++++-- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/aws_encryption_sdk/key_providers/kms.py b/src/aws_encryption_sdk/key_providers/kms.py index df089e3b1..c0a2dc46e 100644 --- a/src/aws_encryption_sdk/key_providers/kms.py +++ b/src/aws_encryption_sdk/key_providers/kms.py @@ -161,8 +161,8 @@ def add_regional_client(self, region_name): :param str region_name: AWS Region ID (ex: us-east-1) """ if region_name not in self._regional_clients: - session = boto3.session.Session(region_name=region_name, botocore_session=self.config.botocore_session) - client = session.client("kms", config=self._user_agent_adding_config) + session = boto3.session.Session(botocore_session=self.config.botocore_session) + client = session.client("kms", region_name=region_name, config=self._user_agent_adding_config) self._register_client(client, region_name) self._regional_clients[region_name] = client diff --git a/test/integration/integration_test_utils.py b/test/integration/integration_test_utils.py index a5b4d6001..b65d93570 100644 --- a/test/integration/integration_test_utils.py +++ b/test/integration/integration_test_utils.py @@ -13,10 +13,13 @@ """Utility functions to handle configuration and credentials setup for integration tests.""" import os +import botocore.session + from aws_encryption_sdk.key_providers.kms import KMSMasterKeyProvider AWS_KMS_KEY_ID = "AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID" _KMS_MKP = None +_KMS_MKP_BOTO = None def get_cmk_arn(): @@ -47,3 +50,19 @@ def setup_kms_master_key_provider(cache=True): _KMS_MKP = kms_master_key_provider return kms_master_key_provider + + +def setup_kms_master_key_provider_with_botocore_session(cache=True): + """Reads the test_values config file and builds the requested KMS Master Key Provider with botocore_session.""" + global _KMS_MKP_BOTO # pylint: disable=global-statement + if cache and _KMS_MKP_BOTO is not None: + return _KMS_MKP_BOTO + + cmk_arn = get_cmk_arn() + kms_master_key_provider = KMSMasterKeyProvider(botocore_session=botocore.session.Session()) + kms_master_key_provider.add_master_key(cmk_arn) + + if cache: + _KMS_MKP_BOTO = kms_master_key_provider + + return kms_master_key_provider diff --git a/test/integration/test_i_aws_encrytion_sdk_client.py b/test/integration/test_i_aws_encrytion_sdk_client.py index 56b0536fd..26df431dc 100644 --- a/test/integration/test_i_aws_encrytion_sdk_client.py +++ b/test/integration/test_i_aws_encrytion_sdk_client.py @@ -21,7 +21,11 @@ from aws_encryption_sdk.identifiers import USER_AGENT_SUFFIX, Algorithm from aws_encryption_sdk.key_providers.kms import KMSMasterKey, KMSMasterKeyProvider -from .integration_test_utils import get_cmk_arn, setup_kms_master_key_provider +from .integration_test_utils import ( + get_cmk_arn, + setup_kms_master_key_provider, + setup_kms_master_key_provider_with_botocore_session, +) pytestmark = [pytest.mark.integ] @@ -68,6 +72,15 @@ def test_remove_bad_client(): assert not test._regional_clients +def test_regional_client_does_not_modify_botocore_session(caplog): + mkp = setup_kms_master_key_provider_with_botocore_session() + fake_region = "us-fakey-12" + + assert mkp.config.botocore_session.get_config_variable("region") != fake_region + mkp.add_regional_client(fake_region) + assert mkp.config.botocore_session.get_config_variable("region") != fake_region + + class TestKMSThickClientIntegration(object): @pytest.fixture(autouse=True) def apply_fixtures(self): diff --git a/test/unit/test_providers_kms_master_key_provider.py b/test/unit/test_providers_kms_master_key_provider.py index 9a122e622..b99a8bb94 100644 --- a/test/unit/test_providers_kms_master_key_provider.py +++ b/test/unit/test_providers_kms_master_key_provider.py @@ -108,8 +108,12 @@ def test_add_regional_client_new(self): test = KMSMasterKeyProvider() test._regional_clients = {} test.add_regional_client("ex_region_name") - self.mock_boto3_session.assert_called_with(region_name="ex_region_name", botocore_session=ANY) - self.mock_boto3_session_instance.client.assert_called_with("kms", config=test._user_agent_adding_config) + self.mock_boto3_session.assert_called_with(botocore_session=ANY) + self.mock_boto3_session_instance.client.assert_called_with( + "kms", + region_name="ex_region_name", + config=test._user_agent_adding_config, + ) assert test._regional_clients["ex_region_name"] is self.mock_boto3_client_instance def test_add_regional_client_exists(self): From 4fa42f2a609f5b4075cf1ce142ebb5587fefd7c6 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 20 Sep 2019 12:18:59 -0700 Subject: [PATCH 09/12] update changelog with changes for 1.4.1 release --- CHANGELOG.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 80b7fc304..d9bca1f73 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,23 @@ Changelog ********* +1.4.1 -- 2019-09-20 +=================== + +Bugfixes +-------- + +* Fix region configuration override in botocore sessions. + `#190 `_ + `#193 `_ + +Minor +----- + +* Caching CMM must require that max age configuration value is greater than 0. + `#147 `_ + `#172 `_ + 1.4.0 -- 2019-05-23 =================== From e5dc67581349f69b79abbc5ee23244b344764e79 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 20 Sep 2019 12:19:31 -0700 Subject: [PATCH 10/12] bump version to 1.4.1 --- src/aws_encryption_sdk/identifiers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aws_encryption_sdk/identifiers.py b/src/aws_encryption_sdk/identifiers.py index 1bd9bb1f1..e3c13c1ea 100644 --- a/src/aws_encryption_sdk/identifiers.py +++ b/src/aws_encryption_sdk/identifiers.py @@ -27,7 +27,7 @@ # We only actually need these imports when running the mypy checks pass -__version__ = "1.4.0" +__version__ = "1.4.1" USER_AGENT_SUFFIX = "AwsEncryptionSdkPython/{}".format(__version__) From 0f4dc6e7f695191daf3d8ceeef8786a93388259d Mon Sep 17 00:00:00 2001 From: Matt Bullock Date: Thu, 3 Oct 2019 15:45:07 -0700 Subject: [PATCH 11/12] Updates to handle new pylint requirements (#196) * pylint max-attributes appears to be ratcheted down recently * remove unnecessary comprehensions * whitelist some pylint use-constant-test false-positives * reorganize backwards compatibility test requirements definitions attrs==19.2.0 removed a deprecated feature that aws-encryption-sdk==1.3.3 depended on. This reorganization lets us define specific requirements bounds for old versions of aws-encryption-sdk that will probably continue to be necessary as these old versions age. * remove unnecessary comprehensions * add newlines to the end of all requirements files --- decrypt_oracle/setup.py | 2 +- doc/requirements.txt | 2 +- requirements.txt | 2 +- setup.py | 2 +- src/aws_encryption_sdk/caches/__init__.py | 1 + src/aws_encryption_sdk/streaming_client.py | 6 +++--- src/aws_encryption_sdk/structures.py | 1 + test/requirements.txt | 2 +- test/unit/test_identifiers.py | 2 +- test_vector_handlers/compatibility-requirements/1.3.3 | 2 ++ test_vector_handlers/compatibility-requirements/1.3.max | 1 + test_vector_handlers/compatibility-requirements/latest | 1 + test_vector_handlers/requirements.txt | 2 +- test_vector_handlers/setup.py | 2 +- test_vector_handlers/test/requirements.txt | 2 +- test_vector_handlers/tox.ini | 6 +++--- 16 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 test_vector_handlers/compatibility-requirements/1.3.3 create mode 100644 test_vector_handlers/compatibility-requirements/1.3.max create mode 100644 test_vector_handlers/compatibility-requirements/latest diff --git a/decrypt_oracle/setup.py b/decrypt_oracle/setup.py index e5d9ec84f..e8dfb2aac 100644 --- a/decrypt_oracle/setup.py +++ b/decrypt_oracle/setup.py @@ -22,7 +22,7 @@ def get_version(): def get_requirements(): """Read the requirements file.""" requirements = read("requirements-actual.txt") - return [r for r in requirements.strip().splitlines()] + return list(requirements.strip().splitlines()) setup( diff --git a/doc/requirements.txt b/doc/requirements.txt index 29e319455..9a54370d6 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,2 +1,2 @@ sphinx>=1.3.0 -sphinx_rtd_theme \ No newline at end of file +sphinx_rtd_theme diff --git a/requirements.txt b/requirements.txt index f04114485..7f8f0d532 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ boto3>=1.4.4 cryptography>=1.8.1 attrs>=17.4.0 -wrapt>=1.10.11 \ No newline at end of file +wrapt>=1.10.11 diff --git a/setup.py b/setup.py index 1afa9d869..6ceb2d8fb 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def get_version(): def get_requirements(): """Reads the requirements file.""" requirements = read("requirements.txt") - return [r for r in requirements.strip().splitlines()] + return list(requirements.strip().splitlines()) setup( diff --git a/src/aws_encryption_sdk/caches/__init__.py b/src/aws_encryption_sdk/caches/__init__.py index 3d3189441..9d2afa485 100644 --- a/src/aws_encryption_sdk/caches/__init__.py +++ b/src/aws_encryption_sdk/caches/__init__.py @@ -143,6 +143,7 @@ class CryptoMaterialsCacheEntryHints(object): @attr.s(hash=False) class CryptoMaterialsCacheEntry(object): + # pylint: disable=too-many-instance-attributes """Value and metadata store for cryptographic materials cache entries. :param bytes cache_key: Identifier for entries in cache diff --git a/src/aws_encryption_sdk/streaming_client.py b/src/aws_encryption_sdk/streaming_client.py index 90dc9d25c..504f68977 100644 --- a/src/aws_encryption_sdk/streaming_client.py +++ b/src/aws_encryption_sdk/streaming_client.py @@ -235,7 +235,7 @@ def read(self, b=-1): if not self._message_prepped: self._prep_message() - if self.closed: + if self.closed: # dynamic values confuse pylint: disable=using-constant-test raise ValueError("I/O operation on closed file") if b >= 0: @@ -283,7 +283,7 @@ def readline(self): def readlines(self): """Reads all chunks of output, outputting a list as defined in the IOBase specification.""" - return [line for line in self] + return list(self) def __iter__(self): """Make this class and subclasses identify as iterators.""" @@ -292,7 +292,7 @@ def __iter__(self): def next(self): """Provides hook for Python2 iterator functionality.""" _LOGGER.debug("reading next") - if self.closed: + if self.closed: # dynamic values confuse pylint: disable=using-constant-test _LOGGER.debug("stream is closed") raise StopIteration() diff --git a/src/aws_encryption_sdk/structures.py b/src/aws_encryption_sdk/structures.py index 8229d65fb..97e4c1d13 100644 --- a/src/aws_encryption_sdk/structures.py +++ b/src/aws_encryption_sdk/structures.py @@ -20,6 +20,7 @@ @attr.s(hash=True) class MessageHeader(object): + # pylint: disable=too-many-instance-attributes """Deserialized message header object. :param version: Message format version, per spec diff --git a/test/requirements.txt b/test/requirements.txt index d1b878ce2..152b5dbf4 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,4 +1,4 @@ mock pytest>=3.3.1 pytest-cov -pytest-mock \ No newline at end of file +pytest-mock diff --git a/test/unit/test_identifiers.py b/test/unit/test_identifiers.py index 8f13b1314..3fd421b65 100644 --- a/test/unit/test_identifiers.py +++ b/test/unit/test_identifiers.py @@ -41,7 +41,7 @@ def test_algorithm_safe_to_cache(check_algorithm, safe_to_cache): assert not check_algorithm.safe_to_cache() -@pytest.mark.parametrize("suite", [suite for suite in EncryptionSuite]) +@pytest.mark.parametrize("suite", list(EncryptionSuite)) def test_encryption_suite_invalid_kdf(suite): mock_kdf = Mock() mock_kdf.input_length.return_value = 1 diff --git a/test_vector_handlers/compatibility-requirements/1.3.3 b/test_vector_handlers/compatibility-requirements/1.3.3 new file mode 100644 index 000000000..7aa43f6be --- /dev/null +++ b/test_vector_handlers/compatibility-requirements/1.3.3 @@ -0,0 +1,2 @@ +aws-encryption-sdk==1.3.3 +attrs<19.2.0 diff --git a/test_vector_handlers/compatibility-requirements/1.3.max b/test_vector_handlers/compatibility-requirements/1.3.max new file mode 100644 index 000000000..72c946bf5 --- /dev/null +++ b/test_vector_handlers/compatibility-requirements/1.3.max @@ -0,0 +1 @@ +aws-encryption-sdk >= 1.3.3, < 1.4.0 diff --git a/test_vector_handlers/compatibility-requirements/latest b/test_vector_handlers/compatibility-requirements/latest new file mode 100644 index 000000000..d0197da7f --- /dev/null +++ b/test_vector_handlers/compatibility-requirements/latest @@ -0,0 +1 @@ +aws-encryption-sdk diff --git a/test_vector_handlers/requirements.txt b/test_vector_handlers/requirements.txt index 21e4de2f0..9de0ee532 100644 --- a/test_vector_handlers/requirements.txt +++ b/test_vector_handlers/requirements.txt @@ -1,3 +1,3 @@ attrs >= 17.4.0 aws-encryption-sdk -six \ No newline at end of file +six diff --git a/test_vector_handlers/setup.py b/test_vector_handlers/setup.py index f191b3869..bd16c76c8 100644 --- a/test_vector_handlers/setup.py +++ b/test_vector_handlers/setup.py @@ -22,7 +22,7 @@ def get_version(): def get_requirements(): """Read the requirements file.""" requirements = read("requirements.txt") - return [r for r in requirements.strip().splitlines()] + return list(requirements.strip().splitlines()) setup( diff --git a/test_vector_handlers/test/requirements.txt b/test_vector_handlers/test/requirements.txt index d1b878ce2..152b5dbf4 100644 --- a/test_vector_handlers/test/requirements.txt +++ b/test_vector_handlers/test/requirements.txt @@ -1,4 +1,4 @@ mock pytest>=3.3.1 pytest-cov -pytest-mock \ No newline at end of file +pytest-mock diff --git a/test_vector_handlers/tox.ini b/test_vector_handlers/tox.ini index 748ba4881..fc2c8d5a7 100644 --- a/test_vector_handlers/tox.ini +++ b/test_vector_handlers/tox.ini @@ -46,9 +46,9 @@ passenv = sitepackages = False deps = -rtest/requirements.txt - awses_1.3.3: aws-encryption-sdk==1.3.3 - awses_1.3.max: aws-encryption-sdk >= 1.3.3, < 1.4.0 - awses_latest: aws-encryption-sdk + awses_1.3.3: -rcompatibility-requirements/1.3.3 + awses_1.3.max: -rcompatibility-requirements/1.3.max + awses_latest: -rcompatibility-requirements/latest commands = {[testenv:base-command]commands} [testenv:full-encrypt] From 6fc431e1d859ba61e1928bc538dcc7a4c4566ac8 Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Thu, 3 Oct 2019 16:33:05 -0700 Subject: [PATCH 12/12] help pylint ignore mypy type use --- src/aws_encryption_sdk/keyring/base.py | 9 +++++++-- src/aws_encryption_sdk/keyring/multi_keyring.py | 5 ++++- src/aws_encryption_sdk/keyring/raw_keyring.py | 8 ++++++-- test/unit/test_providers_kms_master_key_provider.py | 4 +--- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/aws_encryption_sdk/keyring/base.py b/src/aws_encryption_sdk/keyring/base.py index 770b53c0b..236037b4e 100644 --- a/src/aws_encryption_sdk/keyring/base.py +++ b/src/aws_encryption_sdk/keyring/base.py @@ -11,8 +11,13 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. """Base class interface for Keyrings.""" -from aws_encryption_sdk.materials_managers import DecryptionMaterials, EncryptionMaterials -from aws_encryption_sdk.structures import EncryptedDataKey +from aws_encryption_sdk.materials_managers import ( # only used for mypy; pylint: disable=unused-import,duplicate-code + DecryptionMaterials, + EncryptionMaterials, +) +from aws_encryption_sdk.structures import ( # only used for mypy; pylint: disable=unused-import,duplicate-code + EncryptedDataKey, +) try: # Python 3.5.0 and 3.5.1 have incompatible typing modules from typing import Iterable # noqa pylint: disable=unused-import diff --git a/src/aws_encryption_sdk/keyring/multi_keyring.py b/src/aws_encryption_sdk/keyring/multi_keyring.py index f43820be5..cb2b5cc79 100644 --- a/src/aws_encryption_sdk/keyring/multi_keyring.py +++ b/src/aws_encryption_sdk/keyring/multi_keyring.py @@ -17,7 +17,10 @@ from attr.validators import deep_iterable, instance_of, optional from aws_encryption_sdk.exceptions import EncryptKeyError, GenerateKeyError -from aws_encryption_sdk.keyring.base import DecryptionMaterials, EncryptedDataKey, EncryptionMaterials, Keyring +from aws_encryption_sdk.keyring.base import DecryptionMaterials # only used for mypy so pylint: disable=unused-import +from aws_encryption_sdk.keyring.base import EncryptionMaterials # only used for mypy so pylint: disable=unused-import +from aws_encryption_sdk.keyring.base import Keyring +from aws_encryption_sdk.structures import EncryptedDataKey # only used for mypy so pylint: disable=unused-import try: # Python 3.5.0 and 3.5.1 have incompatible typing modules from typing import Iterable # noqa pylint: disable=unused-import diff --git a/src/aws_encryption_sdk/keyring/raw_keyring.py b/src/aws_encryption_sdk/keyring/raw_keyring.py index 513119246..922f6ae0c 100644 --- a/src/aws_encryption_sdk/keyring/raw_keyring.py +++ b/src/aws_encryption_sdk/keyring/raw_keyring.py @@ -29,8 +29,12 @@ from aws_encryption_sdk.internal.formatting.serialize import serialize_raw_master_key_prefix, serialize_wrapped_key from aws_encryption_sdk.key_providers.raw import RawMasterKey from aws_encryption_sdk.keyring.base import Keyring -from aws_encryption_sdk.materials_managers import DecryptionMaterials, EncryptionMaterials -from aws_encryption_sdk.structures import EncryptedDataKey, KeyringTrace, MasterKeyInfo, RawDataKey +from aws_encryption_sdk.materials_managers import ( # only used for mypy so pylint: disable=unused-import + DecryptionMaterials, + EncryptionMaterials, +) +from aws_encryption_sdk.structures import EncryptedDataKey # only used for mypy so pylint: disable=unused-import +from aws_encryption_sdk.structures import KeyringTrace, MasterKeyInfo, RawDataKey try: # Python 3.5.0 and 3.5.1 have incompatible typing modules from typing import Iterable # noqa pylint: disable=unused-import diff --git a/test/unit/test_providers_kms_master_key_provider.py b/test/unit/test_providers_kms_master_key_provider.py index b99a8bb94..f8d8dc453 100644 --- a/test/unit/test_providers_kms_master_key_provider.py +++ b/test/unit/test_providers_kms_master_key_provider.py @@ -110,9 +110,7 @@ def test_add_regional_client_new(self): test.add_regional_client("ex_region_name") self.mock_boto3_session.assert_called_with(botocore_session=ANY) self.mock_boto3_session_instance.client.assert_called_with( - "kms", - region_name="ex_region_name", - config=test._user_agent_adding_config, + "kms", region_name="ex_region_name", config=test._user_agent_adding_config ) assert test._regional_clients["ex_region_name"] is self.mock_boto3_client_instance