Source code for dynamodb_encryption_sdk.encrypted

# Copyright 2018 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.
"""Resources for encrypting items."""
import copy

import attr

from dynamodb_encryption_sdk.exceptions import InvalidArgumentError
from dynamodb_encryption_sdk.identifiers import CryptoAction
from dynamodb_encryption_sdk.material_providers import CryptographicMaterialsProvider
from dynamodb_encryption_sdk.materials import CryptographicMaterials  # noqa pylint: disable=unused-import
from dynamodb_encryption_sdk.structures import AttributeActions, EncryptionContext

try:  # Python 3.5.0 and 3.5.1 have incompatible typing modules
    from typing import Dict  # noqa pylint: disable=unused-import
except ImportError:  # pragma: no cover
    # We only actually need these imports when running the mypy checks
    pass


__all__ = ("CryptoConfig",)


[docs]@attr.s(init=False) class CryptoConfig(object): """Container for all configuration needed to encrypt or decrypt an item using the item encryptor functions in :py:mod:`dynamodb_encryption_sdk.encrypted.item`. :param CryptographicMaterialsProvider materials_provider: Cryptographic materials provider to use :param EncryptionContext encryption_context: Context data describing what is being encrypted or decrypted :param AttributeActions attribute_actions: Description of what action should be taken for each attribute """ materials_provider = attr.ib(validator=attr.validators.instance_of(CryptographicMaterialsProvider)) encryption_context = attr.ib(validator=attr.validators.instance_of(EncryptionContext)) attribute_actions = attr.ib(validator=attr.validators.instance_of(AttributeActions)) def __init__( self, materials_provider, # type: CryptographicMaterialsProvider encryption_context, # type: EncryptionContext attribute_actions, # type: AttributeActions ): # noqa=D107 # type: (...) -> None # Workaround pending resolution of attrs/mypy interaction. # https://github.com/python/mypy/issues/2088 # https://github.com/python-attrs/attrs/issues/215 self.materials_provider = materials_provider self.encryption_context = encryption_context self.attribute_actions = attribute_actions attr.validate(self) self.__attrs_post_init__() def __attrs_post_init__(self): # type: () -> None """Make sure that primary index attributes are not being encrypted.""" if self.encryption_context.partition_key_name is not None: if ( self.attribute_actions.action(self.encryption_context.partition_key_name) is CryptoAction.ENCRYPT_AND_SIGN ): # noqa pylint: disable=line-too-long raise InvalidArgumentError("Cannot encrypt partition key") if self.encryption_context.sort_key_name is not None: if self.attribute_actions.action(self.encryption_context.sort_key_name) is CryptoAction.ENCRYPT_AND_SIGN: raise InvalidArgumentError("Cannot encrypt sort key")
[docs] def decryption_materials(self): # type: () -> CryptographicMaterials """Load decryption materials from instance resources. :returns: Decryption materials :rtype: CryptographicMaterials """ return self.materials_provider.decryption_materials(self.encryption_context)
[docs] def encryption_materials(self): # type: () -> CryptographicMaterials """Load encryption materials from instance resources. :returns: Encryption materials :rtype: CryptographicMaterials """ return self.materials_provider.encryption_materials(self.encryption_context)
[docs] def copy(self): # type: () -> CryptoConfig """Return a copy of this instance with a copied instance of its encryption context. :returns: New :class:`CryptoConfig` identical to this one :rtype: CryptoConfig """ return CryptoConfig( materials_provider=self.materials_provider, encryption_context=copy.copy(self.encryption_context), attribute_actions=self.attribute_actions, )
[docs] def with_item(self, item): """Return a copy of this instance with an encryption context that includes the provided item attributes. :param dict item: DynamoDB item in DynamnoDB JSON format :returns: New :class:`CryptoConfig` identical to this one :rtype: CryptoConfig """ new_config = self.copy() new_config.encryption_context.attributes = item return new_config