Skip to content

Commit 91acc14

Browse files
committed
[PortsPy] Implements connect with auth for sendmail bridges
1 parent a040213 commit 91acc14

File tree

2 files changed

+42
-21
lines changed

2 files changed

+42
-21
lines changed

ports-py/sendmail-python-emails.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import ssl
44
import emails
55
from emails.backend.smtp import SMTPBackend
6+
from emails.backend.response import SMTPResponse
67

78
sendmail_suite = ports.suite("suites/sendmail.ports")
89

@@ -96,7 +97,13 @@ def socket_close(env, socket):
9697

9798
@sendmail_suite.placeholder("sendmail-connect")
9899
def sendmail_connect(env, host, port):
99-
return SMTPBackend(host=host, port=port)
100+
backend = SMTPBackend(host=host, port=port)
101+
return backend
102+
103+
@sendmail_suite.placeholder("sendmail-connect-with-credentials")
104+
def sendmail_connect_with_credentials(env, host, port, username, password):
105+
backend = SMTPBackend(host=host, port=port, user=username, password=password)
106+
return backend
100107

101108
@sendmail_suite.placeholder("sendmail-connect-with-auto-starttls")
102109
def sendmail_connect_with_auto_starttls(env, host, port, automatic_mode):
@@ -127,11 +134,13 @@ def sendmail_secure_connect_with_timeout(env, host, port, cafile, timeout=None):
127134

128135
@sendmail_suite.placeholder("sendmail-disconnect")
129136
def sendmail_disconnect(env, sender):
137+
if not isinstance(sender, SMTPBackend):
138+
return sender
130139
sender.close()
131140

132141
@sendmail_suite.placeholder("sendmail-connected?")
133-
def sendmail_connected(env, sender):
134-
pass
142+
def sendmail_connected(env, backend):
143+
return backend._client is not None and backend._client.sock is not None
135144

136145

137146
#
@@ -158,8 +167,8 @@ def sendmail_success(env, result):
158167
return (not isinstance(result, Exception)) and result.status_code == 250
159168

160169
@sendmail_suite.placeholder("send-error?")
161-
def sendmail_error(env, result):
162-
return isinstance(result, Exception) or result.status_code != 250
170+
def sendmail_error(env, result: SMTPResponse):
171+
return isinstance(result, Exception) or result.status_code != 250 or result.error is not None
163172

164173

165174
#
@@ -168,14 +177,14 @@ def sendmail_error(env, result):
168177

169178
# they do mitigation for addresses but detection for other fields
170179

171-
sendmail_suite.run(#only_capabilities=("root.send-message",),
172-
exclude_capabilities=(
173-
"root.connection",
174-
"root.crlf-injection-detection.detection",
175-
"root.8bitmime",
176-
"root.smtputf8.explicit-options"),
177-
expected_failures=(
178-
# The library should problably automatically detect whether smtputf8 is required
179-
"test_international_sender_mailbox_in_send-message_with_SMTPUTF8_support",
180-
"test_international_recipient_mailbox_in_send-message_with_SMTPUTF8_support",
181-
"test_Send_a_message_with_empty_recipient",))
180+
sendmail_suite.run(
181+
exclude_capabilities=(
182+
"root.connection.eager-connection",
183+
"root.crlf-injection-detection.detection",
184+
"root.8bitmime",
185+
"root.smtputf8.explicit-options"),
186+
expected_failures=(
187+
# The library should problably automatically detect whether smtputf8 is required
188+
"test_international_sender_mailbox_in_send-message_with_SMTPUTF8_support",
189+
"test_international_recipient_mailbox_in_send-message_with_SMTPUTF8_support",
190+
"test_Send_a_message_with_empty_recipient",))

ports-py/sendmail-redmail.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ def sendmail_connect(env, host, port):
9999
sender.connect()
100100
return sender
101101
except Exception as e:
102+
sender.close()
103+
return e
104+
105+
@sendmail_suite.placeholder("sendmail-connect-with-credentials")
106+
def sendmail_connect_with_credentials(env, host, port, username, password):
107+
try:
108+
sender = EmailSender(host=host, port=port, username=username, password=password)
109+
sender.connect()
110+
return sender
111+
except Exception as e:
112+
sender.close()
102113
return e
103114

104115
@sendmail_suite.placeholder("sendmail-connect-with-auto-starttls")
@@ -130,14 +141,16 @@ def sendmail_secure_connect_with_timeout(env, host, port, cafile, timeout=None):
130141

131142
@sendmail_suite.placeholder("sendmail-disconnect")
132143
def sendmail_disconnect(env, sender):
144+
if not isinstance(sender, EmailSender):
145+
return sender
133146
try:
134147
sender.close()
135148
except smtplib.SMTPServerDisconnected:
136149
pass # We are good apparently
137150

138151
@sendmail_suite.placeholder("sendmail-connected?")
139152
def sendmail_connected(env, sender: EmailSender):
140-
return sender.is_alive
153+
return isinstance(sender, EmailSender) and sender.is_alive
141154

142155

143156
#
@@ -176,7 +189,8 @@ def sendmail_error(env, result):
176189
sendmail_suite.run(
177190
exclude=(
178191
"test_CRLF_detection_in_send-message_recipient",
179-
"test_CRLF_mitigation_in_send-message_sender",),
192+
"test_CRLF_mitigation_in_send-message_sender",
193+
"test_Connect_with_invalid_credentials"), # TODO redmail leaks sockets when credentials are invalid
180194
exclude_capabilities=(
181195
"root.8bitmime",
182196
"root.smtputf8.explicit-options"),
@@ -185,6 +199,4 @@ def sendmail_error(env, result):
185199
"test_Handle_421_at_start_of_data_command",
186200
"test_Handle_421_at_the_end_of_data_command",
187201
"test_Handle_421_during_rcpt_command",
188-
"test_Handle_421_during_mail_command",
189-
# redmail does not set the BODY=8BITMIME option
190-
"test_non-ascii_content_in_send-message_with_8BITMIME_support"))
202+
"test_Handle_421_during_mail_command",))

0 commit comments

Comments
 (0)