Commit Graph

305 Commits

Author SHA1 Message Date
Mike Edmunds
0a8887913c SendinBlue: additional template/tags improvements
Additional changes related to SendinBlue improvements in #158:

* Support multiple tags in webhooks (closes #162)
* Remove additional outdated template code in backend
* Update integration tests
* Update docs and changelog; note breaking changes as discussed in #161
2019-09-04 15:45:08 -07:00
Mike Edmunds
df29ee2da6 Mailgun: make merge_data work with stored handlebars templates
Mailgun has two different template mechanisms and two different ways
of providing substitution variables to them. Update Anymail's
normalized merge_data handling to work with either (while preserving
existing batch send and metadata capabilities that also use Mailgun's
custom data and recipient variables parameters).

Completes work started by @anstosa in #156.
Closes #155.
2019-09-03 11:51:19 -07:00
Thorben Luepkes
989d56bd85 Sendinblue: use latest API improvements (templates, tags)
Track Sendinblue API updates:
* Multiple tags are now supported
* When using a template, display name is now supported on 'to', 'bcc', 'cc' and 'replyTo'
* Templates now support overriding 'from_email' and 'subject'
* Templates no longer require separate API endpoint
* 'merge_global_data' can be used without templates
2019-08-28 18:52:11 -07:00
Ansel Santosa
73a73ea01f Mailgun: Support stored templates
Add support for Mailgun's new template option

Fixes #155
2019-07-30 10:50:42 -07:00
medmunds
181d5886eb Add MAILGUN_WEBHOOK_SIGNING_KEY setting.
Fixes #153.
2019-07-07 13:43:08 -07:00
medmunds
578bad9a57 SendGrid: generate unique message_id for each batch recipient
Closes #139
2019-02-23 15:01:54 -08:00
Mike Edmunds
75d7671056 Add merge_metadata for other ESPs
Support merge_metadata in Mailgun, Mailjet, Mandrill, Postmark, 
SparkPost, and Test backends. (SendGrid covered in earlier PR.)

Also:
* Add `merge_metadata` to AnymailMessage, AnymailMessageMixin
* Add `is_batch()` logic to BasePayload, for consistent handling
* Docs

Note: Mailjet implementation switches *all* batch sending from their 
"Recipients" field to to the "Messages" array bulk sending option.
This allows an independent payload for each batch recipient.
In addition to supporting merge_metadata, this also removes the
prior limitation on mixing Cc/Bcc with merge_data.

Closes #141.
2019-02-23 13:32:28 -08:00
Mike Edmunds
978996d7b8 Test without optional packages
Tox:
* Add Tox factor for extras (all, none, individual ESP).
  For now, only break out ESPs that have specific extra
  dependencies (amazon_ses, sparkpost).
* Install most package dependencies (including extras)
  through the package itself.
* Use new runtests.py environment vars to limit test tags
  when Tox isn't installing all extras.

Travis:
* Rework matrix to request specific TOXENVs directly;
  drop tox-travis.

Test runner (runtests.py):
* Centralize RUN_LIVE_TESTS logic in runtests.py
* Add ANYMAIL_ONLY_TEST and ANYMAIL_SKIP_TESTS env vars
  (comma-separated lists of tags)

Test implementations:
* Tag all ESP-specific tests with ESP
* Tag live tests with "live"
* Don't import ESP-specific packages at test module level. 
  (Test discovery imports test modules before tag-based filtering.)

Closes #104
2019-02-09 15:04:08 -08:00
medmunds
bd55d8c298 Rework editorconfig
* Most file types prefer 2-space indents, so now default
  to that and list the exceptions
* Add max_line_length=120 for .py files (Django convention)
* Bat files require CRLF
2019-02-08 12:05:57 -08:00
medmunds
8464d3a231 Docs: note SERVER_EMAIL setting default won't work with most ESPs
mail_admins, mail_managers, and similar Django error reporting
generally won't work with the default SERVER_EMAIL setting
root@localhost.
2019-02-08 11:37:15 -08:00
medmunds
7b58d87079 Docs: Show code cross-reference links as clickable (blue) 2019-02-05 11:34:51 -08:00
medmunds
10f6f3f821 Postmark: Support both TemplateAlias and TemplateId as template_id
Accept either Postmark's template alias or numeric id for `template_id`.
2018-11-06 18:39:49 -08:00
medmunds
2cf14c3653 Mailgun: raise unsupported feature error on attachment without filename.
Mailgun's API silently drops attachments without filenames (and inline
attachments without Content-IDs). Raise an AnymailUnsupportedFeature
error on attempts to send these attachments.

Fixes #128
2018-10-11 15:38:50 -07:00
Leo Antunes
64f7d31d14 also consider Content-ID when marking attachment as inline (#126)
Handle MIME attachments with Content-ID as inline by default.

Treat MIME attachments that have a *Content-ID* but no explicit *Content-Disposition*
header as inline, matching the behavior of many email clients.
2018-10-11 14:29:00 -07:00
medmunds
9c493dba72 Postmark: Support merge_data and batch sending.
Use Postmark /email/batch or /email/batchWithTemplates APIs when
merge_data provided.

Parse Postmark batch-send API responses, and improve accuracy of
parsing individual recipient status from all responses.

Closes #122
2018-09-06 17:24:04 -07:00
medmunds
1ad406a9b5 Docs: fix typo in SendGrid 2018-09-06 17:16:16 -07:00
medmunds
753c895301 Postmark: Fix Postmark error on empty subject/body with template_id.
Postmark issues an error if Django's default empty strings are used
with template sends.

Include template send in Postmark integration tests. (Requires real
Postmark API token -- templates aren't testable with Postmark's
sandbox token.)

Fixes #121
2018-09-05 12:41:33 -07:00
medmunds
382ebf249c SendGrid: Improve esp_extra["personalizations"] handling.
Allow merging `esp_extra["personalizations"]` dict into other
message-derived personalizations.

(See comments in #120)
2018-08-27 11:10:48 -07:00
medmunds
dbca13243f SendGrid: support new "dynamic" transactional templates
Closes #120
2018-08-24 18:21:42 -07:00
medmunds
6b99b7ef4f Docs: update readme test rendering to new PyPI layout, styles 2018-08-19 16:17:07 -07:00
medmunds
13ffd5db40 Docs: add Rate-the-Docs 2018-08-18 17:36:10 -07:00
medmunds
b5f8e86dd4 Docs: update ESP features table with new Postmark metadata support 2018-08-14 16:22:31 -07:00
medmunds
9e7814ad65 Mailgun: Support new (non-legacy) webhooks
Extend existing Mailgun tracking webhook handler to support both
original (legacy) and new (June, 2018) Mailgun webhooks.

Closes #117
2018-08-14 11:53:30 -07:00
medmunds
dacc299e5a Mailgun: Document how to use European region
Closes #116
2018-08-11 16:42:09 -07:00
medmunds
215c6a0a14 Docs: fix SparkPost Python client link
(The PyPI package is named "sparkpost". The GitHub repository is
"python-sparkpost". Sorry for any confusion.)
2018-08-11 16:13:23 -07:00
medmunds
1ac335e006 Docs: update PyPI links to point to new pypi.org
(Skip the redirect through pypi.python.org)
2018-08-11 16:11:14 -07:00
medmunds
46ff2e859c Postmark: Add metadata support
Closes #114
2018-08-11 16:00:58 -07:00
medmunds
0d389f1f93 Docs: rework troubleshooting/help page
Add guidance on how and where to get help.
2018-08-11 15:38:00 -07:00
medmunds
e6431a62f0 Change attach_inline_image default domain from hostname to "inline".
This avoids problems with ESPs that don't distinguish *Content-ID*
from attachment filename, where a local hostname ending in ".com" could
cause Gmail to block messages sent with inline attachments.
(Mailgun, Mailjet, Mandrill and SparkPost have APIs affected by this.)

Fixes #112.
2018-07-06 16:30:27 -07:00
medmunds
3f2c6d6917 Docs: move changelog from GitHub release notes to repository file 2018-06-15 17:10:16 -07:00
medmunds
02e6daf9d4 SendGrid: drop deprecated sendgrid_v2 EmailBackend 2018-05-30 16:02:21 -07:00
medmunds
c0172063a4 SendGrid UUID message_id cleanup
* Update authors
* Update integration tests
* Add webhook message_id = smtp-id fallback test case
* Test webhooks ignore smtp-id in non-fallback cases
* Update docs
2018-05-30 13:50:35 -07:00
medmunds
f7aa67c42c Docs: add documentation privacy info
(and note that the docs site uses Google Analytics)
2018-05-24 11:04:13 -07:00
Mike Edmunds
ef69fa3bf7 Amazon SES support
Integrate Amazon SES.

Closes #54.
2018-04-11 10:35:23 -07:00
medmunds
26cb882636 Postmark: Update docs and tests for "modular webhooks"
Existing tracking webhook code works fine with updated event payloads.
(So older Anymail versions will work, unmodified, with new Postmark
webhooks.)

Also update older doc links into Postmark docs.

Closes #101
2018-04-06 14:31:03 -07:00
medmunds
05f11db4ce SparkPost: add SPARKPOST_API_URL setting to allow SparkPost EU, etc.
Closes #100
2018-04-06 12:58:58 -07:00
medmunds
64bb3b6098 Docs: freeze left column of ESP feature matrix
(Make the wide table a little more readable.)
2018-04-05 18:03:59 -07:00
medmunds
3928f6ea5e Inbound: fix charset handling in .text, .html, .get_content_text()
Make `AnymailInboundMessage.text`, `.html` and `.get_content_text()`
usually do the right thing for non-UTF-8 messages/attachments. Fixes
an incorrect UnicodeDecodeError when receiving an (e.g.,) ISO-8859-1
encoded message, and improves handling for inbound messages that were
not properly encoded by the sender.

* Decode using the message's (or attachments's) declared charset
  by default (rather than always defaulting to 'utf-8'; you can
  still override with `get_content_text(charset=...)`
* Add `errors` param to `get_content_text()`, defaulting to 'replace'.
  Mis-encoded messages will now use the Unicode replacement character
  rather than raising errors. (Use `get_content_text(errors='strict')`
  for the previous behavior.)
2018-04-01 17:26:17 -07:00
medmunds
0c3e3e9bad Docs: css tweaks
* Add vertical space between items in "open" lists
  (rtfd/sphinx_rtd_theme#590)
* Distinguish shell prompts in console examples,
  and omit them if the code is copied
* Add css and js extras directly from Sphinx conf.py
  (no need to override template)
2018-03-16 12:16:57 -07:00
medmunds
b06d684dd5 Use tox for running tests and building docs
* Set up tox for testing supported Django/Python combinations
* Also include tox env for checking and building docs
* Use tox-travis for Travis CI integration
* Add tests against Django master
* Document building docs and running tests with tox
2018-03-15 13:08:07 -07:00
Mike Edmunds
d93a66326c SendinBlue: implement tracking webhooks
Completes #84
2018-03-08 13:47:46 -08:00
medmunds
4b28760a9a SendinBlue: cleanup integration tests, more docs
* Don't send *quite* so many emails during live integration tests.
  (Our test account is throttled to 40/hour.)
* Relax message_id check in integration tests. SendinBlue appears
  to use both @smtp-relay.mail.fr and @smtp-relay.sendinblue.com
  Message-IDs.
* Note requirement for HTML message body in docs.
2018-03-07 18:50:52 -08:00
medmunds
ae8484fd65 Docs: clean up "securing webhooks"
* "SSL" --> "https"
* "authorization" --> "authentication"
  (e.g., "HTTP basic authentication" -- except when referring
  specifically to the HTTP "Authorization" header used to send it)
* add a sidebar with more details on why it matters
2018-03-07 12:19:38 -08:00
medmunds
1e7aacdcb4 SendinBlue: update docs, readme, setup, Travis config
* Flesh out SendinBlue docs, add a readme mention
* Stop trying to list all the supported ESPs in the project short
  description and similar headlines -- it was becoming unwieldy.
* Support `pip install django-anymail[sendinblue]`
  and use it in Travis tests (for consistency; SendinBlue
  doesn't require any extra packages)
2018-03-01 17:29:57 -08:00
medmunds
9478bf5958 [Breaking] Webhooks: disallow deprecated WEBHOOK_AUTHORIZATION setting
Drop support for the WEBHOOK_AUTHORIZATION setting deprecated in v1.4.
Only the WEBHOOK_SECRET replacement is allowed now.

Most Django management commands will now issue a system check error
if the old name is still used in settings.py
2018-03-01 14:11:15 -08:00
medmunds
06c7077e37 Fix: flag extra_headers["To"] as unsupported
Django's SMTP EmailBackend allows spoofing the To header by setting
`message.extra_headers["To"]`` different from `message.to`.

No current Anymail ESP supports this. Treat extra_headers["To"] as
an unsupported ESP feature, to flag attempts to use it.

Also document Anymail's special header handling that replicates
Django's SMTP EmailBackend behavior.
2018-02-27 13:43:58 -08:00
medmunds
07fbeac6bd Feature: Add envelope_sender
New EmailMessage attribute `envelope_sender` controls ESP's sender,
sending domain, or return path where supported:

* Mailgun: overrides SENDER_DOMAIN on individual message
  (domain portion only)
* Mailjet: becomes `Sender` API param
* Mandrill: becomes `return_path_domain` API param
  (domain portion only)
* SparkPost: becomes `return_path` API param
* Other ESPs: not believed to be supported

Also support undocumented Django SMTP backend behavior, where envelope
sender is given by `message.from_email` when
`message.extra_headers["From"]` is set. Fixes #91.
2018-02-26 18:42:19 -08:00
Rignon Noël
dc2b4b4e7a Add SendinBlue backend
Add support for sending transactional email through SendinBlue. (Thanks to @RignonNoel.)

Partially implements #84. (Tracking webhooks will be a separate PR. SendinBlue doesn't support inbound handling.)
2018-02-26 09:46:10 -08:00
medmunds
1a6086f2b5 Security: rename WEBHOOK_AUTHORIZATION --> WEBHOOK_SECRET
This fixes a low severity security issue affecting Anymail v0.2--v1.3.

Django error reporting includes the value of your Anymail
WEBHOOK_AUTHORIZATION setting. In a properly-configured deployment,
this should not be cause for concern. But if you have somehow exposed
your Django error reports (e.g., by mis-deploying with DEBUG=True or by
sending error reports through insecure channels), anyone who gains
access to those reports could discover your webhook shared secret. An
attacker could use this to post fabricated or malicious Anymail
tracking/inbound events to your app, if you are using those Anymail
features.

The fix renames Anymail's webhook shared secret setting so that
Django's error reporting mechanism will [sanitize][0] it.

If you are using Anymail's event tracking and/or inbound webhooks, you
should upgrade to this release and change "WEBHOOK_AUTHORIZATION" to
"WEBHOOK_SECRET" in the ANYMAIL section of your settings.py. You may
also want to [rotate the shared secret][1] value, particularly if you
have ever exposed your Django error reports to untrusted individuals.

If you are only using Anymail's EmailBackends for sending email and
have not set up Anymail's webhooks, this issue does not affect you.

The old WEBHOOK_AUTHORIZATION setting is still allowed in this release,
but will issue a system-check warning when running most Django
management commands. It will be removed completely in a near-future
release, as a breaking change.

Thanks to Charlie DeTar (@yourcelf) for responsibly reporting this
security issue through private channels.

[0]: https://docs.djangoproject.com/en/stable/ref/settings/#debug
[1]: https://anymail.readthedocs.io/en/1.4/tips/securing_webhooks/#use-a-shared-authorization-secret
2018-02-08 11:38:15 -08:00
Mike Edmunds
b57eb94f64 Add inbound mail handling
Add normalized event, signal, and webhooks for inbound mail.

Closes #43
Closes #86
2018-02-02 10:38:53 -08:00