Skip to content

Commit be9da28

Browse files
Remove dependency on AWS Encryption SDK for HOOK types (#260)
* Remove dependency on AWS Encryption SDK for HOOK types
1 parent 775584e commit be9da28

File tree

8 files changed

+101
-337
lines changed

8 files changed

+101
-337
lines changed

src/cloudformation_cli_python_lib/cipher.py

-111
This file was deleted.

src/cloudformation_cli_python_lib/exceptions.py

-4
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,3 @@ def __init__(self, hook_type_name: str, target_type_name: str):
106106

107107
class Unknown(_HandlerError):
108108
pass
109-
110-
111-
class _EncryptionError(Exception):
112-
pass

src/cloudformation_cli_python_lib/hook.py

+4-26
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,7 @@
66
from typing import Any, Callable, MutableMapping, Optional, Tuple, Type, Union
77

88
from .boto3_proxy import SessionProxy, _get_boto_session
9-
from .cipher import Cipher, KmsCipher
10-
from .exceptions import (
11-
AccessDenied,
12-
InternalFailure,
13-
InvalidRequest,
14-
_EncryptionError,
15-
_HandlerError,
16-
)
9+
from .exceptions import InternalFailure, InvalidRequest, _HandlerError
1710
from .interface import (
1811
BaseHookHandlerRequest,
1912
HandlerErrorCode,
@@ -173,31 +166,16 @@ def _parse_request(
173166
]:
174167
try:
175168
event = HookInvocationRequest.deserialize(event_data)
176-
cipher: Cipher = KmsCipher(
177-
event.requestData.hookEncryptionKeyArn,
178-
event.requestData.hookEncryptionKeyRole,
179-
)
180-
181-
caller_credentials = cipher.decrypt_credentials(
182-
event.requestData.callerCredentials
183-
)
184-
provider_credentials = cipher.decrypt_credentials(
185-
event.requestData.providerCredentials
186-
)
187-
188-
caller_sess = _get_boto_session(caller_credentials)
189-
provider_sess = _get_boto_session(provider_credentials)
169+
caller_sess = _get_boto_session(event.requestData.callerCredentials)
170+
provider_sess = _get_boto_session(event.requestData.providerCredentials)
190171
# credentials are used when rescheduling, so can't zero them out (for now)
191172
invocation_point = HookInvocationPoint[event.actionInvocationPoint]
192173
callback_context = event.requestContext.callbackContext or {}
193-
except _EncryptionError as e:
194-
LOG.exception("Failed to decrypt credentials")
195-
raise AccessDenied(f"{e} ({type(e).__name__})") from e
196174
except Exception as e:
197175
LOG.exception("Invalid request")
198176
raise InvalidRequest(f"{e} ({type(e).__name__})") from e
199177

200-
return ((caller_sess, provider_sess)), invocation_point, callback_context, event
178+
return (caller_sess, provider_sess), invocation_point, callback_context, event
201179

202180
def _cast_hook_request(
203181
self, request: HookInvocationRequest

src/cloudformation_cli_python_lib/utils.py

+40-5
Original file line numberDiff line numberDiff line change
@@ -204,22 +204,48 @@ def deserialize(cls, json_data: MutableMapping[str, Any]) -> "HookRequestContext
204204
return HookRequestContext()
205205
return HookRequestContext(**json_data)
206206

207+
def serialize(self) -> Mapping[str, Any]:
208+
return {key: value for key, value in self.__dict__.items() if value is not None}
209+
207210

208211
@dataclass
209212
class HookRequestData:
210213
targetName: str
211214
targetType: str
212215
targetLogicalId: str
213216
targetModel: Mapping[str, Any]
214-
callerCredentials: Optional[str] = None
215-
providerCredentials: Optional[str] = None
217+
callerCredentials: Optional[Credentials] = None
218+
providerCredentials: Optional[Credentials] = None
216219
providerLogGroupName: Optional[str] = None
217-
hookEncryptionKeyArn: Optional[str] = None
218-
hookEncryptionKeyRole: Optional[str] = None
220+
221+
def __init__(self, **kwargs: Any) -> None:
222+
dataclass_fields = {f.name for f in fields(self)}
223+
for k, v in kwargs.items():
224+
if k in dataclass_fields:
225+
setattr(self, k, v)
219226

220227
@classmethod
221228
def deserialize(cls, json_data: MutableMapping[str, Any]) -> "HookRequestData":
222-
return HookRequestData(**json_data)
229+
req_data = HookRequestData(**json_data)
230+
for key in json_data:
231+
if not key.endswith("Credentials"):
232+
continue
233+
creds = json_data.get(key)
234+
if creds:
235+
cred_data = json.loads(creds)
236+
setattr(req_data, key, Credentials(**cred_data))
237+
return req_data
238+
239+
def serialize(self) -> Mapping[str, Any]:
240+
return {
241+
key: {k: v for k, v in value.items() if v is not None}
242+
if key == "targetModel"
243+
else value.__dict__.copy()
244+
if key.endswith("Credentials")
245+
else value
246+
for key, value in self.__dict__.items()
247+
if value is not None
248+
}
223249

224250

225251
@dataclass
@@ -252,6 +278,15 @@ def deserialize(cls, json_data: MutableMapping[str, Any]) -> Any:
252278
)
253279
return event
254280

281+
def serialize(self) -> Mapping[str, Any]:
282+
return {
283+
key: value.serialize()
284+
if key in ("requestData", "requestContext")
285+
else value
286+
for key, value in self.__dict__.items()
287+
if value is not None
288+
}
289+
255290

256291
@dataclass
257292
class UnmodelledHookRequest:

src/setup.py

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
python_requires=">=3.6",
1616
install_requires=[
1717
"boto3>=1.10.20",
18-
"aws-encryption-sdk==3.1.1",
1918
'dataclasses;python_version<"3.7"',
2019
],
2120
license="Apache License 2.0",

tests/lib/cipher_test.py

-134
This file was deleted.

0 commit comments

Comments
 (0)