Skip to content

Commit

Permalink
Ability to forward some headers (#27)
Browse files Browse the repository at this point in the history
* Add support for forwarding headers

* Test for forwarding headers in email

* Docs update

* Update changelog
  • Loading branch information
JeffersonBledsoe authored Apr 21, 2023
1 parent 632cffc commit 274b717
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Changelog
2.7.1 (unreleased)
------------------

- Nothing changed yet.
- Allow forwarding request headers in the sent emails #27
[JeffersonBledsoe]


2.7.0 (2023-04-03)
Expand Down
14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,20 @@ This is useful for some SMTP servers that have problems with `quoted-printable`
By default the content-transfer-encoding is `quoted-printable` as overrided in
https://github.com/zopefoundation/Products.MailHost/blob/master/src/Products/MailHost/MailHost.py#L65

Header forwarding
=========================

It is possible to configure some headers from the form POST request to be included in the email's headers by configuring the `httpHeaders` field in your volto block.

[volto-formblock](https://github.com/collective/volto-form-block) allows the following headers to be forwarded:

- `HTTP_X_FORWARDED_FOR`
- `HTTP_X_FORWARDED_PORT`
- `REMOTE_ADDR`
- `PATH_INFO`
- `HTTP_USER_AGENT`
- `HTTP_REFERER`

Examples
========

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,14 @@ def send_data(self):
msg["To"] = mto
msg["Reply-To"] = mreply_to

msg.replace_header("Content-Type", 'text/html; charset="utf-8"')

headers_to_forward = self.block.get("httpHeaders", [])
for header in headers_to_forward:
header_value = self.request.get(header)
if header_value:
msg[header] = header_value

self.manage_attachments(msg=msg)
self.send_mail(msg=msg, charset=charset)

Expand Down
77 changes: 76 additions & 1 deletion src/collective/volto/formsupport/tests/test_send_action_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,85 @@ def test_email_sent_with_site_recipient(
self.assertIn("<strong>Message:</strong> just want to say hi", msg)
self.assertIn("<strong>Name:</strong> John", msg)

def test_email_sent_ignore_passed_recipient(
def test_email_sent_with_forwarded_headers(
self,
):
self.document.blocks = {
"form-id": {
"@type": "form",
"send": True,
"httpHeaders": [],
},
}
transaction.commit()

response = self.submit_form(
data={
"from": "john@doe.com",
"data": [
{"label": "Message", "value": "just want to say hi"},
{"label": "Name", "value": "John"},
],
"subject": "test subject",
"block_id": "form-id",
},
)
transaction.commit()
self.assertEqual(response.status_code, 204)
msg = self.mailhost.messages[0]
if isinstance(msg, bytes) and bytes is not str:
# Python 3 with Products.MailHost 4.10+
msg = msg.decode("utf-8")
self.assertIn("Subject: test subject", msg)
self.assertIn("From: john@doe.com", msg)
self.assertIn("To: site_addr@plone.com", msg)
self.assertIn("Reply-To: john@doe.com", msg)
self.assertIn("<strong>Message:</strong> just want to say hi", msg)
self.assertIn("<strong>Name:</strong> John", msg)
self.assertNotIn("REMOTE_ADDR", msg)

self.document.blocks = {
"form-id": {
"@type": "form",
"send": True,
"httpHeaders": [
"REMOTE_ADDR",
"PATH_INFO",
],
},
}
transaction.commit()

response = self.submit_form(
data={
"from": "john@doe.com",
"data": [
{"label": "Message", "value": "just want to say hi"},
{"label": "Name", "value": "John"},
],
"subject": "test subject",
"block_id": "form-id",
},
)
transaction.commit()
self.assertEqual(response.status_code, 204)

msg = self.mailhost.messages[1]
if isinstance(msg, bytes) and bytes is not str:
# Python 3 with Products.MailHost 4.10+
msg = msg.decode("utf-8")
self.assertIn("Subject: test subject", msg)
self.assertIn("From: john@doe.com", msg)
self.assertIn("To: site_addr@plone.com", msg)
self.assertIn("Reply-To: john@doe.com", msg)
self.assertIn("<strong>Message:</strong> just want to say hi", msg)
self.assertIn("<strong>Name:</strong> John", msg)
self.assertIn("REMOTE_ADDR", msg)
self.assertIn("PATH_INFO", msg)

def test_email_sent_ignore_passed_recipient(
self,
):
self.document.blocks = {
"form-id": {"@type": "form", "send": True},
}
Expand Down

0 comments on commit 274b717

Please sign in to comment.