Commit 01c85a2a authored by Barry Warsaw's avatar Barry Warsaw
Browse files

Port to Python 3.5.

parent fd29c455
Pipeline #49847 failed with stage
......@@ -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]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment