-
Notifications
You must be signed in to change notification settings - Fork 264
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #221 from bityob/add-dkim-support
- Loading branch information
Showing
11 changed files
with
207 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,4 @@ docs/_static/* | |
.coverage | ||
.coverage.* | ||
.coveralls.yml | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,8 @@ | |
with open('README.rst') as f: | ||
LONG_DESCRIPTION = f.read() | ||
MAJOR_VERSION = '0' | ||
MINOR_VERSION = '14' | ||
MICRO_VERSION = '260' | ||
MINOR_VERSION = '15' | ||
MICRO_VERSION = '0' | ||
VERSION = "{}.{}.{}".format(MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION) | ||
|
||
setup( | ||
|
@@ -17,7 +17,7 @@ | |
author='Pascal van Kooten', | ||
author_email='[email protected]', | ||
license='MIT', | ||
extras_require={"all": ["keyring"]}, | ||
extras_require={"all": ["keyring", "dkimpy"], "dkim": ["dkimpy"]}, | ||
install_requires=["premailer"], | ||
keywords='email mime automatic html attachment', | ||
entry_points={'console_scripts': ['yagmail = yagmail.__main__:main']}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkwMu7eqAx9WrL4lwio01L65D425hBs54Aw4HODsHQYiwQejKsZdj+kneLpm9Zdvm3U1FDD+SfkBWGJmlScoj5Kg0nYx0c0RVeowKetVrmTL7t7d01ag+QRnCBHN1E/B99rFpy47WtwAOuPuKZKIc40JvkCphxVj6GbJZsPjyA2YuhLDp0zVvNzQ61mbM5OC50unppH73maqQVh4f3kIm3Cfxbe8yw8hfVlmZomuSwv3HpZLgrF4ktktI2f3q18Wx4e4OOHaanv/b8VrXo6qIV6RLH5FSteyzFfs+qZbbaWmSDjYEoIHS/oZkaNQOZOkr2T12Rnu/lk/ubDErqaCLXQIDAQAB |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
MIIEogIBAAKCAQEAkwMu7eqAx9WrL4lwio01L65D425hBs54Aw4HODsHQYiwQejK | ||
sZdj+kneLpm9Zdvm3U1FDD+SfkBWGJmlScoj5Kg0nYx0c0RVeowKetVrmTL7t7d0 | ||
1ag+QRnCBHN1E/B99rFpy47WtwAOuPuKZKIc40JvkCphxVj6GbJZsPjyA2YuhLDp | ||
0zVvNzQ61mbM5OC50unppH73maqQVh4f3kIm3Cfxbe8yw8hfVlmZomuSwv3HpZLg | ||
rF4ktktI2f3q18Wx4e4OOHaanv/b8VrXo6qIV6RLH5FSteyzFfs+qZbbaWmSDjYE | ||
oIHS/oZkaNQOZOkr2T12Rnu/lk/ubDErqaCLXQIDAQABAoIBADWdWpcgB9lZXnYW | ||
vLl66CO8fTvLfI077V7H1fA27t2CmS1gVdPQr4CPQf1iykUEnrykuoLOCIIMupl8 | ||
J2Cy3MY+ZfnzSGDlUftAaW4EuZoEkvKccHqfQh0B5NU0ukUMVxQJ/dhj/oB8/+GM | ||
sxsiWEC1cPR10HRlj8ihV76H+9Mq+k9+/LrT8AU4qJHTZCwNvS/IESz67uutqtn2 | ||
EgYN70QPIgQLYDCLiH8D3d3bE/YfOBLMJNxWYDIFcUtDtRmvB8Qrx+dzhp1wOVj6 | ||
Ouwav5e+ZZu2LKkbRiENxjR9OrcHHcVdnuNYIfGnriPrksqljTurgamr+7zJo2Dg | ||
dalgNAECgYEAxqBXSu+YyMuT24KY01KXYDB4iK0J9XbF/Zd9VKCG4sJe/ZQWqjSH | ||
1IMb2yDQTNVic0NSQnQ6tu55UT+Avw0y4VsYsEdeyf2Y1wi+K7L2VLqny2ihjsNE | ||
pN7kJO31NPc4rELsxzxU6nQK4EAAlZs2H5BZSmPxbe0+gB3x2B23dwECgYEAvXox | ||
ESTKfn/XXTZOrS1Iv2zEonlCu5ERroAcFi8BKV3TpCOQfWDYUIflrksDkRAHjMl1 | ||
tyNmT/fPBLH9EL4CHevPOpUweHsG9LNyp3An5IpcOorzD3TTfEl+FSKZ1D4uUYeD | ||
rOx7QVCSrOAtbLQlP5Oc61blY5JINxB1TaLKUF0CgYBdd+acJNPI6cPScEpqZ1tE | ||
sIqIBqXBFPtmsnsP79qJqt34hk+EGOQyZOAe5fofrep+QxfancdjfiUozrFPNm7T | ||
DYM4sN0yQFxEFKEo/zZb+NotJjegbtNGonzJxBC3s/6/UV8LAqETEzhq/rNHs5ps | ||
kAj0sMNT72iR8YV1JcbIAQKBgGzyfJIh+HkCIyBKoLR8zE6dSPcvCEr3YBZZPU0Y | ||
G+/gLlg7xtIAxICRk2RDZ7qaX+z4zcHPDf4/O/60JRHiXy87Lr29mNA91UMQh4V1 | ||
PMrxL5TN3nJtt0jIrUGT0qWyV0mzxOfCViC5Jo1WnWfasWw8AUdkgKNfMjzPLtPE | ||
HdZVAoGAMw4Ffpdy1UPzB/nSJYzhGyXpHOWfrkfwyzTFpnKw0BeGA1AYWNxVIKHY | ||
zqVtTBTSZcLJc4+4oVYuE7Qpvyx3fIuyDoVJXgUohCk8z5HtshevGeYuNQd2Vj94 | ||
TigapgfF4hY6cBjA4hNIUlgWF1scX7aNEvq1EDGcy+SwjUiR+J0= | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import base64 | ||
import logging | ||
from pathlib import Path | ||
from unittest.mock import Mock | ||
|
||
import dkim | ||
|
||
|
||
def get_txt_from_test_file(*args, **kwargs): | ||
dns_data_file = Path(__file__).parent / "domainkey-dns.txt" | ||
|
||
return Path(dns_data_file).read_bytes() | ||
|
||
|
||
def _test_email_with_dkim(include_headers): | ||
from yagmail import SMTP | ||
from yagmail.dkim import DKIM | ||
|
||
private_key_path = Path(__file__).parent / "privkey.pem" | ||
|
||
private_key = private_key_path.read_bytes() | ||
|
||
dkim_obj = DKIM( | ||
domain=b"a.com", | ||
selector=b"selector", | ||
private_key=private_key, | ||
include_headers=include_headers, | ||
) | ||
|
||
yag = SMTP( | ||
user="[email protected]", | ||
host="smtp.blabla.com", | ||
port=25, | ||
dkim=dkim_obj, | ||
) | ||
|
||
yag.login = Mock() | ||
|
||
to = "[email protected]" | ||
|
||
recipients, msg_bytes = yag.send( | ||
to=to, | ||
subject="hello from tests", | ||
contents="important message", | ||
preview_only=True | ||
) | ||
|
||
msg_string = msg_bytes.decode("utf8") | ||
|
||
assert recipients == [to] | ||
assert "Subject: hello from tests" in msg_string | ||
text_b64 = base64.b64encode(b"important message").decode("utf8") | ||
assert text_b64 in msg_string | ||
|
||
dkim_string1 = "DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=a.com; [email protected];\n " \ | ||
"q=dns/txt; s=selector; t=" | ||
assert dkim_string1 in msg_string | ||
|
||
l = logging.getLogger() | ||
l.setLevel(level=logging.DEBUG) | ||
logging.basicConfig(level=logging.DEBUG) | ||
|
||
assert dkim.verify( | ||
message=msg_string.encode("utf8"), | ||
logger=l, | ||
dnsfunc=get_txt_from_test_file | ||
) | ||
|
||
return msg_string | ||
|
||
|
||
def test_email_with_dkim(): | ||
msg_string = _test_email_with_dkim(include_headers=[b"To", b"From", b"Subject"]) | ||
|
||
dkim_string2 = "h=to : from : subject;" | ||
assert dkim_string2 in msg_string | ||
|
||
|
||
def test_dkim_without_including_headers(): | ||
msg_string = _test_email_with_dkim(include_headers=None) | ||
|
||
dkim_string_headers = "h=content-type : mime-version :\n date : subject : from : to : message-id : from;\n" | ||
assert dkim_string_headers in msg_string | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from email.mime.base import MIMEBase | ||
from typing import NamedTuple | ||
|
||
try: | ||
import dkim | ||
except ImportError: | ||
dkim = None | ||
pass | ||
|
||
|
||
class DKIM(NamedTuple): | ||
domain: bytes | ||
private_key: bytes | ||
include_headers: list | ||
selector: bytes | ||
|
||
|
||
def add_dkim_sig_to_message(msg: MIMEBase, dkim_obj: DKIM) -> None: | ||
if dkim is None: | ||
raise RuntimeError("dkim package not installed") | ||
|
||
# Based on example from: | ||
# https://github.com/russellballestrini/russell.ballestrini.net/blob/master/content/ | ||
# 2018-06-04-quickstart-to-dkim-sign-email-with-python.rst | ||
sig = dkim.sign( | ||
message=msg.as_bytes(), | ||
selector=dkim_obj.selector, | ||
domain=dkim_obj.domain, | ||
privkey=dkim_obj.private_key, | ||
include_headers=dkim_obj.include_headers, | ||
) | ||
# add the dkim signature to the email message headers. | ||
# decode the signature back to string_type because later on | ||
# the call to msg.as_string() performs it's own bytes encoding... | ||
msg["DKIM-Signature"] = sig[len("DKIM-Signature: "):].decode() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters