Skip to content
This repository was archived by the owner on Jun 9, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions pythonit_toolkit/emails/backends/ses.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
from typing import Optional

import html
import boto3
from pythonit_toolkit.emails.templates import EmailTemplate

Expand All @@ -21,10 +21,13 @@ def send_email(
to: str,
variables: Optional[dict[str, str]] = None,
):
variables = {"subject": subject, **(variables or {})}
variables = self.encode_vars({"subject": subject, **(variables or {})})
self.ses.send_templated_email(
Source=from_,
Destination={"ToAddresses": [to]},
Template=f"pythonit-{self.environment}-{template}",
TemplateData=json.dumps(variables),
)

def encode_vars(self, variables: dict[str, str]) -> dict[str, str]:
return {key: html.escape(value) for key, value in variables.items()}
21 changes: 21 additions & 0 deletions tests/emails/backends/test_ses.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,24 @@ async def _():
Template="pythonit-production-reset-password",
TemplateData='{"subject": "Subject"}',
)


@test("variables are html encoded")
async def _():
with patch("pythonit_toolkit.emails.backends.ses.boto3") as mock_boto:
SESEmailBackend("production").send_email(
template=EmailTemplate.RESET_PASSWORD,
subject="Subject",
from_="test@email.it",
to="destination@email.it",
variables={
"a": '<a href="https://google.it">link</a>',
},
)

mock_boto.client.return_value.send_templated_email.assert_called_once_with(
Source="test@email.it",
Destination={"ToAddresses": ["destination@email.it"]},
Template="pythonit-production-reset-password",
TemplateData='{"subject": "Subject", "a": "&lt;a href=&quot;https://google.it&quot;&gt;link&lt;/a&gt;"}',
)
12 changes: 9 additions & 3 deletions tests/pastaporto/test_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,16 @@ async def _():
token = generate_service_to_service_token("secret", issuer="me", audience="you")

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

with time_machine.travel("2021-11-13 18:43:10", tick=False), raises(jwt.ExpiredSignatureError):
decode_service_to_service_token(token, secret="secret", issuer="me", audience="you")
with time_machine.travel("2021-11-13 18:43:10", tick=False), raises(
jwt.ExpiredSignatureError
):
decode_service_to_service_token(
token, secret="secret", issuer="me", audience="you"
)


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