Skip to content

Commit a113cc4

Browse files
author
Lucas McDonald
committed
paginator
1 parent 058bd78 commit a113cc4

File tree

4 files changed

+83
-5
lines changed

4 files changed

+83
-5
lines changed

DynamoDbEncryption/runtimes/python/src/aws_database_encryption_sdk/encryptor/client.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,40 @@
3333
)
3434
from aws_database_encryption_sdk.smithygenerated.aws_cryptography_dbencryptionsdk_dynamodb.models import (
3535
DynamoDbTablesEncryptionConfig,
36+
DynamoDbTableEncryptionConfig,
3637
)
38+
from aws_database_encryption_sdk.smithygenerated.aws_cryptography_dbencryptionsdk_dynamodb_itemencryptor.config import (
39+
DynamoDbItemEncryptorConfig,
40+
)
41+
from aws_database_encryption_sdk.encryptor.item import ItemEncryptor
3742

43+
class EncryptedPaginator:
44+
def __init__(
45+
self,
46+
paginator: Paginator,
47+
item_encryptors: dict[str, ItemEncryptor]
48+
):
49+
self._paginator = paginator
50+
self._item_encryptors = item_encryptors
51+
52+
def paginate(self, **kwargs):
53+
"""Create an iterator that will paginate through responses from the underlying paginator,
54+
transparently decrypting any returned items.
55+
"""
56+
table_name = kwargs["TableName"]
57+
58+
try:
59+
item_encryptor = self._item_encryptors[table_name]
60+
except KeyError:
61+
raise KeyError(f"No encryption configuration found for table {table_name}")
62+
63+
for page in self._paginator.paginate(**kwargs):
64+
encrypted_items = page["Items"]
65+
decrypted_items = []
66+
for item in encrypted_items:
67+
decrypted_items.append(item_encryptor.decrypt_dynamodb_item(item))
68+
page["Items"] = decrypted_items
69+
yield page
3870

3971
class EncryptedClient:
4072
"""
@@ -319,4 +351,42 @@ def __getattr__(self, name):
319351
elif hasattr(self._client, name):
320352
return getattr(self._client, name)
321353
else:
322-
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
354+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
355+
356+
def _table_encryption_config_to_item_encryptor_config(
357+
table_encryption_config: DynamoDbTableEncryptionConfig
358+
) -> DynamoDbItemEncryptorConfig:
359+
return DynamoDbItemEncryptorConfig(
360+
logical_table_name=table_encryption_config.logical_table_name,
361+
partition_key_name=table_encryption_config.partition_key_name,
362+
attribute_actions_on_encrypt=table_encryption_config.attribute_actions_on_encrypt,
363+
sort_key_name=table_encryption_config.sort_key_name,
364+
allowed_unsigned_attributes=table_encryption_config.allowed_unsigned_attributes,
365+
allowed_unsigned_attribute_prefix=table_encryption_config.allowed_unsigned_attribute_prefix,
366+
algorithm_suite_id=table_encryption_config.algorithm_suite_id,
367+
keyring=table_encryption_config.keyring,
368+
cmm=table_encryption_config.cmm,
369+
legacy_override=table_encryption_config.legacy_override,
370+
plaintext_override=table_encryption_config.plaintext_override,
371+
)
372+
373+
def get_paginator(self, operation_name: str) -> EncryptedPaginator:
374+
"""Get a paginator from the underlying client. If the paginator requested is for
375+
"scan" or "query", the paginator returned will transparently decrypt the returned items.
376+
377+
:param str operation_name: Name of operation for which to get paginator
378+
:returns: Paginator for name
379+
:rtype: :class:`botocore.paginate.Paginator` or :class:`EncryptedPaginator`
380+
"""
381+
paginator = self._client.get_paginator(operation_name)
382+
383+
item_encryptors = {}
384+
for table_name, table_config in self._encryption_config.items():
385+
item_encryptors[table_name] = self._table_encryption_config_to_item_encryptor_config(table_config)
386+
387+
if operation_name in ("scan", "query"):
388+
return EncryptedPaginator(
389+
paginator=paginator, item_encryptor_by_table=item_encryptors, client=self._client
390+
)
391+
392+
return paginator

TestVectors/Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ _sed_types_file_remove_extern:
143143
_sed_types_file_add_extern:
144144
echo "no types file"
145145

146-
test_python_dynamodb_format:
146+
test_python_client_interface:
147147
rm -rf runtimes/python/.tox
148-
python3 -m tox -c runtimes/python/test/dynamodb_format
148+
python3 -m tox -c runtimes/python/test/client
149+
150+
test_python_resource_interface:
151+
rm -rf runtimes/python/.tox
152+
python3 -m tox -c runtimes/python/test/resource
153+
154+
test_python_table_interface:
155+
rm -rf runtimes/python/.tox
156+
python3 -m tox -c runtimes/python/test/table

submodules/smithy-dafny

0 commit comments

Comments
 (0)