Skip to content

Commit

Permalink
Merge pull request #139 from piotrsz/develop
Browse files Browse the repository at this point in the history
PLAIN security mode
  • Loading branch information
awdeorio authored Feb 15, 2023
2 parents 2284abb + 3de19a6 commit 578217d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
8 changes: 8 additions & 0 deletions mailmerge/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,14 @@ def create_sample_input_files(template_path, database_path, config_path):
# username = YOUR_USERNAME_HERE
# ratelimit = 0
# Example: Plain security
# [smtp_server]
# host = newman.eecs.umich.edu
# port = 25
# security = PLAIN
# username = YOUR_USERNAME_HERE
# ratelimit = 0
# Example: No security
# [smtp_server]
# host = newman.eecs.umich.edu
Expand Down
6 changes: 5 additions & 1 deletion mailmerge/sendmail_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def read_config(self):
security = None

# Verify security type
if security not in [None, "SSL/TLS", "STARTTLS"]:
if security not in [None, "SSL/TLS", "STARTTLS", "PLAIN"]:
raise exceptions.MailmergeError(
f"{self.config_path}: unrecognized security type: '{security}'"
)
Expand Down Expand Up @@ -100,6 +100,10 @@ def sendmail(self, sender, recipients, message):
smtp.ehlo()
smtp.login(self.config.username, self.password)
smtp.sendmail(sender, recipients, message_flattened)
elif self.config.security == "PLAIN":
with smtplib.SMTP(host, port) as smtp:
smtp.login(self.config.username, self.password)
smtp.sendmail(sender, recipients, message_flattened)
elif self.config.security is None:
with smtplib.SMTP(host, port) as smtp:
smtp.sendmail(sender, recipients, message_flattened)
Expand Down
42 changes: 42 additions & 0 deletions tests/test_sendmail_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,48 @@ def test_security_starttls(mocker, tmp_path):
assert smtp.sendmail.call_count == 1


def test_security_plain(mocker, tmp_path):
"""Verify plain security configuration."""
# Config for Plain SMTP server
config_path = tmp_path/"server.conf"
config_path.write_text(textwrap.dedent("""\
[smtp_server]
host = newman.eecs.umich.edu
port = 25
security = PLAIN
username = YOUR_USERNAME_HERE
"""))

# Simple template
sendmail_client = SendmailClient(config_path, dry_run=False)
message = email.message_from_string("Hello world")

# Mock SMTP
mock_smtp = mocker.patch('smtplib.SMTP')
mock_smtp_ssl = mocker.patch('smtplib.SMTP_SSL')

# Mock the password entry
mock_getpass = mocker.patch('getpass.getpass')
mock_getpass.return_value = "password"

# Send a message
sendmail_client.sendmail(
sender="[email protected]",
recipients=["[email protected]"],
message=message,
)

# Verify SMTP library calls
assert mock_getpass.call_count == 1
assert mock_smtp.call_count == 1
assert mock_smtp_ssl.call_count == 0
smtp = mock_smtp.return_value.__enter__.return_value
assert smtp.ehlo.call_count == 0
assert smtp.starttls.call_count == 0
assert smtp.login.call_count == 1
assert smtp.sendmail.call_count == 1


def test_security_ssl(mocker, tmp_path):
"""Verify open (Never) security configuration."""
# Config for SSL SMTP server
Expand Down

0 comments on commit 578217d

Please sign in to comment.