summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/database/types.py6
-rw-r--r--src/mailman/docs/NEWS.rst4
-rw-r--r--src/mailman/email/message.py12
-rw-r--r--src/mailman/mta/docs/authentication.rst2
-rw-r--r--src/mailman/mta/docs/connection.rst2
-rw-r--r--src/mailman/mta/tests/test_connection.py14
-rw-r--r--src/mailman/testing/mta.py41
7 files changed, 59 insertions, 22 deletions
diff --git a/src/mailman/database/types.py b/src/mailman/database/types.py
index f6350f3b9..43c6057dc 100644
--- a/src/mailman/database/types.py
+++ b/src/mailman/database/types.py
@@ -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:
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst
index 5071e24bd..e43132a38 100644
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -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"
==========================
diff --git a/src/mailman/email/message.py b/src/mailman/email/message.py
index 72e67869e..98e6f464e 100644
--- a/src/mailman/email/message.py
+++ b/src/mailman/email/message.py
@@ -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):
diff --git a/src/mailman/mta/docs/authentication.rst b/src/mailman/mta/docs/authentication.rst
index f98c00e1f..d3800ef38 100644
--- a/src/mailman/mta/docs/authentication.rst
+++ b/src/mailman/mta/docs/authentication.rst
@@ -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.
diff --git a/src/mailman/mta/docs/connection.rst b/src/mailman/mta/docs/connection.rst
index f4e0d8107..8b11605cb 100644
--- a/src/mailman/mta/docs/connection.rst
+++ b/src/mailman/mta/docs/connection.rst
@@ -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')
diff --git a/src/mailman/mta/tests/test_connection.py b/src/mailman/mta/tests/test_connection.py
index 6e167497e..a3a830330 100644
--- a/src/mailman/mta/tests/test_connection.py
+++ b/src/mailman/mta/tests/test_connection.py
@@ -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')
diff --git a/src/mailman/testing/mta.py b/src/mailman/testing/mta.py
index 351ef631a..62abc2d88 100644
--- a/src/mailman/testing/mta.py
+++ b/src/mailman/testing/mta.py
@@ -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):