Skip to content
This repository was archived by the owner on Jun 9, 2024. It is now read-only.

Commit 6962215

Browse files
authored
HTML Encode Email variables (#3)
1 parent 6307fc7 commit 6962215

3 files changed

Lines changed: 35 additions & 5 deletions

File tree

pythonit_toolkit/emails/backends/ses.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json
22
from typing import Optional
3-
3+
import html
44
import boto3
55
from pythonit_toolkit.emails.templates import EmailTemplate
66

@@ -21,10 +21,13 @@ def send_email(
2121
to: str,
2222
variables: Optional[dict[str, str]] = None,
2323
):
24-
variables = {"subject": subject, **(variables or {})}
24+
variables = self.encode_vars({"subject": subject, **(variables or {})})
2525
self.ses.send_templated_email(
2626
Source=from_,
2727
Destination={"ToAddresses": [to]},
2828
Template=f"pythonit-{self.environment}-{template}",
2929
TemplateData=json.dumps(variables),
3030
)
31+
32+
def encode_vars(self, variables: dict[str, str]) -> dict[str, str]:
33+
return {key: html.escape(value) for key, value in variables.items()}

tests/emails/backends/test_ses.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,24 @@ async def _():
4040
Template="pythonit-production-reset-password",
4141
TemplateData='{"subject": "Subject"}',
4242
)
43+
44+
45+
@test("variables are html encoded")
46+
async def _():
47+
with patch("pythonit_toolkit.emails.backends.ses.boto3") as mock_boto:
48+
SESEmailBackend("production").send_email(
49+
template=EmailTemplate.RESET_PASSWORD,
50+
subject="Subject",
51+
from_="test@email.it",
52+
to="destination@email.it",
53+
variables={
54+
"a": '<a href="https://google.it">link</a>',
55+
},
56+
)
57+
58+
mock_boto.client.return_value.send_templated_email.assert_called_once_with(
59+
Source="test@email.it",
60+
Destination={"ToAddresses": ["destination@email.it"]},
61+
Template="pythonit-production-reset-password",
62+
TemplateData='{"subject": "Subject", "a": "&lt;a href=&quot;https://google.it&quot;&gt;link&lt;/a&gt;"}',
63+
)

tests/pastaporto/test_tokens.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,16 @@ async def _():
8484
token = generate_service_to_service_token("secret", issuer="me", audience="you")
8585

8686
with time_machine.travel("2021-11-13 18:41:50", tick=False):
87-
decode_service_to_service_token(token, secret="secret", issuer="me", audience="you")
87+
decode_service_to_service_token(
88+
token, secret="secret", issuer="me", audience="you"
89+
)
8890

89-
with time_machine.travel("2021-11-13 18:43:10", tick=False), raises(jwt.ExpiredSignatureError):
90-
decode_service_to_service_token(token, secret="secret", issuer="me", audience="you")
91+
with time_machine.travel("2021-11-13 18:43:10", tick=False), raises(
92+
jwt.ExpiredSignatureError
93+
):
94+
decode_service_to_service_token(
95+
token, secret="secret", issuer="me", audience="you"
96+
)
9197

9298

9399
@test("Secret is required when creating a service-to-service token")

0 commit comments

Comments
 (0)