Skip to content

Commit

Permalink
include sender name in email headers
Browse files Browse the repository at this point in the history
  • Loading branch information
davisagli committed Sep 24, 2024
1 parent b354fb4 commit 8bd0d53
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 31 deletions.
38 changes: 25 additions & 13 deletions backend/src/collective/volto/formsupport/processors/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
from collective.volto.formsupport.interfaces import IFormSubmissionProcessor
from email import policy
from email.message import EmailMessage
from email.utils import formataddr
from plone import api
from plone.registry.interfaces import IRegistry
from zExceptions import BadRequest
from zope.component import adapter
from zope.component import getMultiAdapter
from zope.component import getUtility
from zope.i18n import translate
from zope.interface import implementer

import codecs
Expand Down Expand Up @@ -41,6 +41,10 @@ def __init__(self, context: FormSubmissionContext):
self.records = context.get_records()
self.attachments = context.get_attachments()

registry = getUtility(IRegistry)
self.mail_settings = registry.forInterface(IMailSchema, prefix="plone")
self.charset = registry.get("plone.email_charset", "utf-8")

def __call__(self):
send_to_admin = bool(self.block.get("send"))
send_confirmation = bool(self.block.get("send_confirmation"))
Expand All @@ -53,15 +57,15 @@ def __call__(self):
)
if overview_controlpanel.mailhost_warning():
raise BadRequest("MailHost is not configured.")
registry = getUtility(IRegistry)
mail_settings = registry.forInterface(IMailSchema, prefix="plone")
charset = registry.get("plone.email_charset", "utf-8")
portal_transforms = api.portal.get_tool(name="portal_transforms")

subject = self.get_subject()

mfrom = mail_settings.email_from_address
mreply_to = self.get_reply_to() or mfrom
mfrom = formataddr((
self.mail_settings.email_from_name,
self.mail_settings.email_from_address,
))
mreply_to = self.get_reply_to()
message = self.prepare_message()
text_message = (
portal_transforms.convertTo("text/plain", message, mimetype="text/html")
Expand All @@ -70,7 +74,7 @@ def __call__(self):
)

if send_to_admin:
mto = self.block.get("recipients", mail_settings.email_from_address)
mto = self.block.get("recipients", self.mail_settings.email_from_address)
msg = EmailMessage(policy=policy.SMTP)
msg.set_content(text_message, cte=CTE)
msg.add_alternative(message, subtype="html", cte=CTE)
Expand All @@ -86,11 +90,11 @@ def __call__(self):
msg[header] = header_value

self.add_attachments(msg=msg)
self.send_mail(msg=msg, charset=charset)
self.send_mail(msg=msg, charset=self.charset)
# send a copy also to the fields with bcc flag
for bcc in self.get_bcc():
msg.replace_header("To", bcc)
self.send_mail(msg=msg, charset=charset)
self.send_mail(msg=msg, charset=self.charset)

if send_confirmation:
recipients = self.get_confirmation_recipients()
Expand All @@ -101,12 +105,20 @@ def __call__(self):
msg["To"] = self.get_confirmation_recipients()
msg.set_content(text_message, cte=CTE)
msg.add_alternative(message, subtype="html", cte=CTE)
self.send_mail(msg=msg, charset=charset)
self.send_mail(msg=msg, charset=self.charset)

def get_reply_to(self):
def get_reply_to(self) -> str:
sender = self.block.get("sender", "")
sender = self.substitute_variables(sender)
return sender
sender = (
self.substitute_variables(sender) or self.mail_settings.email_from_address
)

sender_name = self.block.get("sender_name", "")
sender_name = (
self.substitute_variables(sender_name) or self.mail_settings.email_from_name
)

return formataddr((sender_name, sender))

def get_subject(self):
subject = self.block.get("subject")
Expand Down
35 changes: 17 additions & 18 deletions backend/tests/functional/test_email_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,17 @@ def test_email_sent_with_fallback_subject_and_sender(self, submit_form):
msg = self.mailhost.messages[0].decode("utf-8")
msg = re.sub(r"\s+", " ", msg)
assert "Subject: Form Submission" in msg
assert "From: site_addr@plone.com" in msg
assert "From: Plone test site <site_addr@plone.com>" in msg
assert "To: site_addr@plone.com" in msg
assert "Reply-To: site_addr@plone.com" in msg
assert "Reply-To: Plone test site <site_addr@plone.com>" in msg

def test_email_sent_with_only_fields_from_schema(self, submit_form):
self.document.blocks = {
"form-id": {
"@type": "schemaForm",
"send": True,
"sender": "john@doe.com",
"sender_name": "John Doe",
"subject": "test subject",
"schema": {
"fieldsets": [
Expand Down Expand Up @@ -183,9 +184,9 @@ def test_email_sent_with_only_fields_from_schema(self, submit_form):
msg = self.mailhost.messages[0].decode("utf-8")
msg = re.sub(r"\s+", " ", msg)
assert "Subject: test subject" in msg
assert "From: site_addr@plone.com" in msg
assert "From: Plone test site <site_addr@plone.com>" in msg
assert "To: site_addr@plone.com" in msg
assert "Reply-To: john@doe.com" in msg
assert "Reply-To: John Doe <john@doe.com>" in msg
assert "<strong>foo:</strong> foo" in msg
assert "<strong>bar:</strong> bar" not in msg

Expand All @@ -194,7 +195,6 @@ def test_email_sent_with_site_recipient(self, submit_form):
"form-id": {
"@type": "schemaForm",
"send": True,
"sender": "john@doe.com",
"subject": "test subject",
"schema": {
"fieldsets": [
Expand Down Expand Up @@ -226,9 +226,9 @@ def test_email_sent_with_site_recipient(self, submit_form):
msg = self.mailhost.messages[0].decode("utf-8")
msg = re.sub(r"\s+", " ", msg)
assert "Subject: test subject" in msg
assert "From: site_addr@plone.com" in msg
assert "From: Plone test site <site_addr@plone.com>" in msg
assert "To: site_addr@plone.com" in msg
assert "Reply-To: john@doe.com" in msg
assert "Reply-To: Plone test site <site_addr@plone.com>" in msg
assert "<strong>Message:</strong> just want to say hi" in msg
assert "<strong>Name:</strong> John" in msg

Expand All @@ -237,7 +237,6 @@ def test_email_sent_with_forwarded_headers(self, submit_form):
"form-id": {
"@type": "schemaForm",
"send": True,
"sender": "john@doe.com",
"subject": "test subject",
"httpHeaders": [
"REMOTE_ADDR",
Expand Down Expand Up @@ -273,9 +272,9 @@ def test_email_sent_with_forwarded_headers(self, submit_form):
msg = self.mailhost.messages[0].decode("utf-8")
msg = re.sub(r"\s+", " ", msg)
assert "Subject: test subject" in msg
assert "From: site_addr@plone.com" in msg
assert "From: Plone test site <site_addr@plone.com>" in msg
assert "To: site_addr@plone.com" in msg
assert "Reply-To: john@doe.com" in msg
assert "Reply-To: Plone test site <site_addr@plone.com>" in msg
assert "<strong>Message:</strong> just want to say hi" in msg
assert "<strong>Name:</strong> John" in msg
assert "REMOTE_ADDR" in msg
Expand All @@ -288,7 +287,6 @@ def test_email_sent_with_block_recipient_if_set(self, submit_form):
"@type": "schemaForm",
"recipients": "to@block.com",
"send": True,
"sender": "john@doe.com",
"subject": "test subject",
"schema": {
"fieldsets": [
Expand Down Expand Up @@ -320,9 +318,9 @@ def test_email_sent_with_block_recipient_if_set(self, submit_form):
msg = self.mailhost.messages[0].decode("utf-8")
msg = re.sub(r"\s+", " ", msg)
assert "Subject: test subject" in msg
assert "From: site_addr@plone.com" in msg
assert "From: Plone test site <site_addr@plone.com>" in msg
assert "To: to@block.com" in msg
assert "Reply-To: john@doe.com" in msg
assert "Reply-To: Plone test site <site_addr@plone.com>" in msg
assert "<strong>Message:</strong> just want to say hi" in msg
assert "<strong>Name:</strong> John" in msg

Expand Down Expand Up @@ -363,9 +361,9 @@ def test_email_sent_with_subject_from_form_data(self, submit_form):
msg = self.mailhost.messages[0].decode("utf-8")
msg = re.sub(r"\s+", " ", msg)
assert "Subject: just want to say hi" in msg
assert "From: site_addr@plone.com" in msg
assert "From: Plone test site <site_addr@plone.com>" in msg
assert "To: site_addr@plone.com" in msg
assert "Reply-To: site_addr@plone.com" in msg
assert "Reply-To: Plone test site <site_addr@plone.com>" in msg
assert "<strong>Message:</strong> just want to say hi" in msg
assert "<strong>Name:</strong> John" in msg

Expand All @@ -375,6 +373,7 @@ def test_email_with_sender_from_form_data(self, submit_form):
"@type": "schemaForm",
"send": True,
"sender": "${email}",
"sender_name": "${name}",
"subject": "test subject",
"schema": {
"fieldsets": [
Expand Down Expand Up @@ -411,9 +410,9 @@ def test_email_with_sender_from_form_data(self, submit_form):
assert response.status_code == 200
msg = self.mailhost.messages[0].decode("utf-8")
msg = re.sub(r"\s+", " ", msg)
assert "From: site_addr@plone.com" in msg
assert "From: Plone test site <site_addr@plone.com>" in msg
assert "To: site_addr@plone.com" in msg
assert "Reply-To: smith@doe.com" in msg
assert "Reply-To: Smith <smith@doe.com>" in msg
assert "<strong>Message:</strong> just want to say hi" in msg
assert "<strong>Name:</strong> Smith" in msg

Expand Down Expand Up @@ -594,7 +593,7 @@ def test_send_confirmation(self, submit_form):
msg = self.mailhost.messages[0].decode("utf-8")
parsed_msg = Parser().parsestr(msg)
msg = re.sub(r"\s+", " ", msg)
assert parsed_msg.get("from") == "site_addr@plone.com"
assert parsed_msg.get("from") == "Plone test site <site_addr@plone.com>"
assert parsed_msg.get("to") == "smith@doe.com"
assert parsed_msg.get("subject") == "Form Submission"
assert "<strong>Name:</strong> Smith" in msg
Expand Down

0 comments on commit 8bd0d53

Please sign in to comment.