def _item_check(materials_provider, table_name, table_index, ciphertext_item, plaintext_item, attribute_actions, prep): ciphertext_item = ddb_to_dict(ciphertext_item) plaintext_item = ddb_to_dict(plaintext_item) prep() # Test scenario setup that needs to happen inside the test cmp = materials_provider( ) # Some of the materials providers need to be constructed inside the test table = fake_table(ciphertext_item) table_info = TableInfo(name=table_name, primary_index=TableIndex( partition=table_index['partition'], sort=table_index.get('sort', None))) item_key = { table_info.primary_index.partition: ciphertext_item[table_info.primary_index.partition] } if table_info.primary_index.sort is not None: item_key[table_info.primary_index.sort] = ciphertext_item[ table_info.primary_index.sort] e_table = EncryptedTable(table=table, materials_provider=cmp, table_info=table_info, attribute_actions=attribute_actions, auto_refresh_table_indexes=False) decrypted_item = e_table.get_item(Key=item_key)['Item'] assert set(decrypted_item.keys()) == set(plaintext_item.keys()) for key in decrypted_item: if key == 'version': continue assert decrypted_item[key] == plaintext_item[key]
def client_cycle_single_item_check(materials_provider, initial_actions, initial_item, table_name, region_name=None): check_attribute_actions = initial_actions.copy() check_attribute_actions.set_index_keys(*list(TEST_KEY.keys())) item = initial_item.copy() item.update(TEST_KEY) ddb_item = dict_to_ddb(item) ddb_key = dict_to_ddb(TEST_KEY) kwargs = {} if region_name is not None: kwargs["region_name"] = region_name client = boto3.client("dynamodb", **kwargs) e_client = EncryptedClient(client=client, materials_provider=materials_provider, attribute_actions=initial_actions) _put_result = e_client.put_item(TableName=table_name, Item=ddb_item) # noqa encrypted_result = client.get_item(TableName=table_name, Key=ddb_key, ConsistentRead=True) check_encrypted_item(item, ddb_to_dict(encrypted_result["Item"]), check_attribute_actions) decrypted_result = e_client.get_item(TableName=table_name, Key=ddb_key, ConsistentRead=True) assert ddb_to_dict(decrypted_result["Item"]) == item e_client.delete_item(TableName=table_name, Key=ddb_key) del item del check_attribute_actions
def _batch_items_check(materials_provider, table_name, table_index, ciphertext_item, plaintext_item, attribute_actions): plaintext_item = ddb_to_dict(plaintext_item) ciphertext_item = ddb_to_dict(ciphertext_item) e_resource, item_key = _resource_setup(materials_provider, table_name, table_index, ciphertext_item, attribute_actions) response = e_resource.batch_get_item( RequestItems={table_name: { "Keys": [item_key] }}) decrypted_item = response["Responses"][table_name][0] _compare_item(plaintext_item, decrypted_item)
def decrypt_python_item(item, crypto_config): # type: (dynamodb_types.ITEM, CryptoConfig) -> dynamodb_types.ITEM """Decrypt a dictionary for DynamoDB. >>> from dynamodb_encryption_sdk.encrypted.item import decrypt_python_item >>> encrypted_item = { ... 'some': Binary(b'ENCRYPTED_DATA'), ... 'more': Binary(b'ENCRYPTED_DATA') ... } >>> decrypted_item = decrypt_python_item( ... item=encrypted_item, ... crypto_config=my_crypto_config ... ) .. note:: This handles human-friendly dictionaries and is for use with the boto3 DynamoDB service or table resource. :param dict item: Encrypted and signed dictionary :param CryptoConfig crypto_config: Cryptographic configuration :returns: Plaintext dictionary :rtype: dict """ ddb_item = dict_to_ddb(item) decrypted_ddb_item = decrypt_dynamodb_item(ddb_item, crypto_config) return ddb_to_dict(decrypted_ddb_item)
def test_transformable_item(item): ddb_json = dict_to_ddb(item) serialized = {} for key, value in ddb_json.items(): serialized[key] = serialize_attribute(value) deserialized = {} for key, value in serialized.items(): deserialized[key] = deserialize_attribute(value) end_result = ddb_to_dict(deserialized) assert end_result == item
def _item_check(materials_provider, table_name, table_index, ciphertext_item, plaintext_item, attribute_actions, prep): ciphertext_item = ddb_to_dict(ciphertext_item) plaintext_item = ddb_to_dict(plaintext_item) metatable = None try: metatable = prep( ) # Test scenario setup that needs to happen inside the test cmp = materials_provider( ) # Some of the materials providers need to be constructed inside the test table = fake_table(ciphertext_item) table_info = TableInfo( name=table_name, primary_index=TableIndex(partition=table_index["partition"], sort=table_index.get("sort", None)), ) item_key = { table_info.primary_index.partition: ciphertext_item[table_info.primary_index.partition] } if table_info.primary_index.sort is not None: item_key[table_info.primary_index.sort] = ciphertext_item[ table_info.primary_index.sort] e_table = EncryptedTable( table=table, materials_provider=cmp, table_info=table_info, attribute_actions=attribute_actions, auto_refresh_table_indexes=False, ) decrypted_item = e_table.get_item(Key=item_key)["Item"] assert set(decrypted_item.keys()) == set(plaintext_item.keys()) for key in decrypted_item: if key == "version": continue assert decrypted_item[key] == plaintext_item[key] finally: if metatable: metatable.delete() metatable.wait_until_not_exists()
def decrypt_python_item( item, key_store: KeyStore, encryption_context: EncryptionContext, attribute_actions: AttributeActions, ): ddb_item = dict_to_ddb(item) decrypted_ddb_item = decrypt_dynamodb_item( item=ddb_item, key_store=key_store, encryption_context=encryption_context, attribute_actions=attribute_actions, ) return ddb_to_dict(decrypted_ddb_item)
def _generate(materials_provider, table_data, ciphertext_file, metastore_info): # pylint: disable=too-many-locals client = boto3.client("dynamodb", region_name="us-west-2") data_table_output = defaultdict(list) metastore_output = defaultdict(list) metatable = _create_meta_table(client, metastore_info) for table_name in table_data: table = None try: table_index = table_data[table_name]["index"] table_index_types = table_data[table_name]["index_types"] table_items = table_data[table_name]["items"] _create_data_table(client, table_name, table_index, table_index_types) table = boto3.resource("dynamodb", region_name="us-west-2").Table(table_name) table.wait_until_exists() cmp = materials_provider() table_info = TableInfo( name=table_name, primary_index=TableIndex(partition=table_index["partition"], sort=table_index.get("sort", None)), ) for plaintext_item in table_items: source_item = plaintext_item["item"] item_key = { table_info.primary_index.partition: source_item[table_info.primary_index.partition] } if table_info.primary_index.sort is not None: item_key[table_info.primary_index.sort] = source_item[ table_info.primary_index.sort] attribute_actions = plaintext_item["action"] e_table = EncryptedTable( table=table, materials_provider=cmp, table_info=table_info, attribute_actions=attribute_actions, auto_refresh_table_indexes=False, ) e_table.put_item(Item=ddb_to_dict(source_item)) retrieved_item = table.get_item(Key=ddb_to_dict(item_key)) parsed_item = dict_to_ddb(retrieved_item["Item"]) data_table_output[table_name].append(ddb_to_json(parsed_item)) finally: if table: table.delete() with open(ciphertext_file, "w", encoding="utf-8") as outfile: json.dump(data_table_output, outfile, indent=4) if metatable: # Assume exactly one entry in metastore table wrapping_key = dict_to_ddb(metatable.scan()["Items"][0]) metastore_output[metastore_info["table_name"]].append( ddb_to_json(wrapping_key)) metastore_ciphertext_file = _filename_from_uri( metastore_info["ciphertext"]) with open(metastore_ciphertext_file, "w", encoding="utf-8") as outfile: json.dump(metastore_output, outfile, indent=4) metatable.delete()
def _ddb_dict_ddb_transform_cycle(item): ddb_item = dict_to_ddb(item) cycled_item = ddb_to_dict(ddb_item) assert cycled_item == item
def test_serializable_item(item): ddb_json = dict_to_ddb(item) end_result = ddb_to_dict(ddb_json) assert end_result == item