Skip to content
Snippets Groups Projects
Commit 01c85a2a authored by Barry Warsaw's avatar Barry Warsaw
Browse files

Port to Python 3.5.

parent fd29c455
No related branches found
No related tags found
1 merge request!22Testing Please Ignore
Pipeline #
......@@ -77,10 +77,8 @@ class UUID(TypeDecorator):
return str(value)
else:
if not isinstance(value, uuid.UUID):
return "%.32x" % uuid.UUID(value)
else:
# hexstring
return "%.32x" % value
value = uuid.UUID(value)
return '%.32x' % value.int
def process_result_value(self, value, dialect):
if value is None:
......
......@@ -52,6 +52,10 @@ REST
isn't linked, the address is linked to the new user. Given by Aurélien
Bompard.
Other
-----
* The test suite is now Python 3.5 compatible.
3.0.0 -- "Show Don't Tell"
==========================
......
......@@ -41,16 +41,10 @@ from mailman.config import config
COMMASPACE = ', '
VERSION = tuple(int(v) for v in email.__version__.split('.'))
class Message(email.message.Message):
def __init__(self):
# We need a version number so that we can optimize __setstate__().
self.__version__ = VERSION
email.message.Message.__init__(self)
# BAW: For debugging w/ bin/dumpdb. Apparently pprint uses repr.
def __repr__(self):
return self.__str__()
......@@ -62,12 +56,6 @@ class Message(email.message.Message):
# safer for pickling, so we handle such changes here. Note that we're
# using Python 2.6's email package version 4.0.1 as a base line here.
self.__dict__ = values
# The pickled instance should have an __version__ string, but it may
# not if it's an email package message.
version = values.get('__version__', (0, 0, 0))
values['__version__'] = version
# There's really nothing to check; there's nothing newer than email
# 4.0.1 at the moment.
@property
def sender(self):
......
......@@ -45,7 +45,7 @@ Attempting delivery first must authorize with the mail server.
{}
>>> print(smtpd.get_authentication_credentials())
PLAIN AHRlc3R1c2VyAHRlc3RwYXNz
AHRlc3R1c2VyAHRlc3RwYXNz
>>> config.pop('auth')
But if the user name and password does not match, the connection will fail.
......
......@@ -70,7 +70,7 @@ will authenticate with the mail server after each new connection.
... """)
{}
>>> print(smtpd.get_authentication_credentials())
PLAIN AHRlc3R1c2VyAHRlc3RwYXNz
AHRlc3R1c2VyAHRlc3RwYXNz
>>> reset()
>>> config.pop('auth')
......
......@@ -49,3 +49,17 @@ Subject: aardvarks
""")
self.assertEqual(cm.exception.smtp_code, 571)
self.assertEqual(cm.exception.smtp_error, b'Bad authentication')
def test_authentication_good_path(self):
# Logging in with the correct user name and password succeeds.
connection = Connection(
config.mta.smtp_host, int(config.mta.smtp_port), 0,
'testuser', 'testpass')
connection.sendmail('anne@example.com', ['bart@example.com'], """\
From: anne@example.com
To: bart@example.com
Subject: aardvarks
""")
self.assertEqual(self.layer.smtpd.get_authentication_credentials(),
'AHRlc3R1c2VyAHRlc3RwYXNz')
......@@ -53,6 +53,11 @@ class FakeMTA:
class StatisticsChannel(Channel):
"""A channel that can answers to the fake STAT command."""
def __init__(self, server, connection, address):
super().__init__(server, connection, address)
self._auth_response = None
self._waiting_for_auth_response = False
def smtp_EHLO(self, arg):
if not arg:
self.push('501 Syntax: HELO hostname')
......@@ -69,12 +74,28 @@ class StatisticsChannel(Channel):
self._server.send_statistics()
self.push('250 Ok')
def _check_auth(self, response):
# Base 64 for "testuser:testpass"
if response == 'AHRlc3R1c2VyAHRlc3RwYXNz':
self.push('235 Ok')
self._server.send_auth(response)
else:
self.push('571 Bad authentication')
def smtp_AUTH(self, arg):
"""Record that the AUTH occurred."""
if arg == 'PLAIN AHRlc3R1c2VyAHRlc3RwYXNz':
# testuser:testpass
self.push('235 Ok')
self._server.send_auth(arg)
args = arg.split()
if args[0].lower() == 'plain':
if len(args) == 2:
# The second argument is the AUTH PLAIN <initial-response>
# which must be equal to the base 64 equivalent of the
# expected login string "testuser:testpass".
self._check_auth(args[1])
else:
assert len(args) == 1, args
# Send a challenge and set us up to wait for the response.
self.push('334 ')
self._waiting_for_auth_response = True
else:
self.push('571 Bad authentication')
......@@ -100,6 +121,18 @@ class StatisticsChannel(Channel):
# the exception we expect smtplib.SMTP to raise.
self.push('%d Error: SMTPResponseException' % code)
def found_terminator(self):
# Are we're waiting for the AUTH challenge response?
if self._waiting_for_auth_response:
line = self._emptystring.join(self.received_lines)
self._auth_response = line
self._waiting_for_auth_response = False
self.received_lines = []
# Now check to see if they authenticated correctly.
self._check_auth(line)
else:
super().found_terminator()
class ConnectionCountingServer(QueueServer):
......
[tox]
envlist = py34
envlist = py34,py35
recreate = True
[testenv]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment