Open Media Library Platform

This commit is contained in:
j 2013-10-11 19:28:32 +02:00
commit 411ad5b16f
5849 changed files with 1778641 additions and 0 deletions

View file

@ -0,0 +1 @@
"Tests for twistd.mail"

View file

@ -0,0 +1,314 @@
#!/usr/bin/env python
# -*- test-case-name: twisted.mail.test.test_pop3client -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.internet.protocol import Factory
from twisted.protocols import basic
from twisted.internet import reactor
import sys, time
USER = "test"
PASS = "twisted"
PORT = 1100
SSL_SUPPORT = True
UIDL_SUPPORT = True
INVALID_SERVER_RESPONSE = False
INVALID_CAPABILITY_RESPONSE = False
INVALID_LOGIN_RESPONSE = False
DENY_CONNECTION = False
DROP_CONNECTION = False
BAD_TLS_RESPONSE = False
TIMEOUT_RESPONSE = False
TIMEOUT_DEFERRED = False
SLOW_GREETING = False
"""Commands"""
CONNECTION_MADE = "+OK POP3 localhost v2003.83 server ready"
CAPABILITIES = [
"TOP",
"LOGIN-DELAY 180",
"USER",
"SASL LOGIN"
]
CAPABILITIES_SSL = "STLS"
CAPABILITIES_UIDL = "UIDL"
INVALID_RESPONSE = "-ERR Unknown request"
VALID_RESPONSE = "+OK Command Completed"
AUTH_DECLINED = "-ERR LOGIN failed"
AUTH_ACCEPTED = "+OK Mailbox open, 0 messages"
TLS_ERROR = "-ERR server side error start TLS handshake"
LOGOUT_COMPLETE = "+OK quit completed"
NOT_LOGGED_IN = "-ERR Unknown AUHORIZATION state command"
STAT = "+OK 0 0"
UIDL = "+OK Unique-ID listing follows\r\n."
LIST = "+OK Mailbox scan listing follows\r\n."
CAP_START = "+OK Capability list follows:"
class POP3TestServer(basic.LineReceiver):
def __init__(self, contextFactory = None):
self.loggedIn = False
self.caps = None
self.tmpUser = None
self.ctx = contextFactory
def sendSTATResp(self, req):
self.sendLine(STAT)
def sendUIDLResp(self, req):
self.sendLine(UIDL)
def sendLISTResp(self, req):
self.sendLine(LIST)
def sendCapabilities(self):
if self.caps is None:
self.caps = [CAP_START]
if UIDL_SUPPORT:
self.caps.append(CAPABILITIES_UIDL)
if SSL_SUPPORT:
self.caps.append(CAPABILITIES_SSL)
for cap in CAPABILITIES:
self.caps.append(cap)
resp = '\r\n'.join(self.caps)
resp += "\r\n."
self.sendLine(resp)
def connectionMade(self):
if DENY_CONNECTION:
self.disconnect()
return
if SLOW_GREETING:
reactor.callLater(20, self.sendGreeting)
else:
self.sendGreeting()
def sendGreeting(self):
self.sendLine(CONNECTION_MADE)
def lineReceived(self, line):
"""Error Conditions"""
uline = line.upper()
find = lambda s: uline.find(s) != -1
if TIMEOUT_RESPONSE:
# Do not respond to clients request
return
if DROP_CONNECTION:
self.disconnect()
return
elif find("CAPA"):
if INVALID_CAPABILITY_RESPONSE:
self.sendLine(INVALID_RESPONSE)
else:
self.sendCapabilities()
elif find("STLS") and SSL_SUPPORT:
self.startTLS()
elif find("USER"):
if INVALID_LOGIN_RESPONSE:
self.sendLine(INVALID_RESPONSE)
return
resp = None
try:
self.tmpUser = line.split(" ")[1]
resp = VALID_RESPONSE
except:
resp = AUTH_DECLINED
self.sendLine(resp)
elif find("PASS"):
resp = None
try:
pwd = line.split(" ")[1]
if self.tmpUser is None or pwd is None:
resp = AUTH_DECLINED
elif self.tmpUser == USER and pwd == PASS:
resp = AUTH_ACCEPTED
self.loggedIn = True
else:
resp = AUTH_DECLINED
except:
resp = AUTH_DECLINED
self.sendLine(resp)
elif find("QUIT"):
self.loggedIn = False
self.sendLine(LOGOUT_COMPLETE)
self.disconnect()
elif INVALID_SERVER_RESPONSE:
self.sendLine(INVALID_RESPONSE)
elif not self.loggedIn:
self.sendLine(NOT_LOGGED_IN)
elif find("NOOP"):
self.sendLine(VALID_RESPONSE)
elif find("STAT"):
if TIMEOUT_DEFERRED:
return
self.sendLine(STAT)
elif find("LIST"):
if TIMEOUT_DEFERRED:
return
self.sendLine(LIST)
elif find("UIDL"):
if TIMEOUT_DEFERRED:
return
elif not UIDL_SUPPORT:
self.sendLine(INVALID_RESPONSE)
return
self.sendLine(UIDL)
def startTLS(self):
if self.ctx is None:
self.getContext()
if SSL_SUPPORT and self.ctx is not None:
self.sendLine('+OK Begin TLS negotiation now')
self.transport.startTLS(self.ctx)
else:
self.sendLine('-ERR TLS not available')
def disconnect(self):
self.transport.loseConnection()
def getContext(self):
try:
from twisted.internet import ssl
except ImportError:
self.ctx = None
else:
self.ctx = ssl.ClientContextFactory()
self.ctx.method = ssl.SSL.TLSv1_METHOD
usage = """popServer.py [arg] (default is Standard POP Server with no messages)
no_ssl - Start with no SSL support
no_uidl - Start with no UIDL support
bad_resp - Send a non-RFC compliant response to the Client
bad_cap_resp - send a non-RFC compliant response when the Client sends a 'CAPABILITY' request
bad_login_resp - send a non-RFC compliant response when the Client sends a 'LOGIN' request
deny - Deny the connection
drop - Drop the connection after sending the greeting
bad_tls - Send a bad response to a STARTTLS
timeout - Do not return a response to a Client request
to_deferred - Do not return a response on a 'Select' request. This
will test Deferred callback handling
slow - Wait 20 seconds after the connection is made to return a Server Greeting
"""
def printMessage(msg):
print "Server Starting in %s mode" % msg
def processArg(arg):
if arg.lower() == 'no_ssl':
global SSL_SUPPORT
SSL_SUPPORT = False
printMessage("NON-SSL")
elif arg.lower() == 'no_uidl':
global UIDL_SUPPORT
UIDL_SUPPORT = False
printMessage("NON-UIDL")
elif arg.lower() == 'bad_resp':
global INVALID_SERVER_RESPONSE
INVALID_SERVER_RESPONSE = True
printMessage("Invalid Server Response")
elif arg.lower() == 'bad_cap_resp':
global INVALID_CAPABILITY_RESPONSE
INVALID_CAPABILITY_RESPONSE = True
printMessage("Invalid Capability Response")
elif arg.lower() == 'bad_login_resp':
global INVALID_LOGIN_RESPONSE
INVALID_LOGIN_RESPONSE = True
printMessage("Invalid Capability Response")
elif arg.lower() == 'deny':
global DENY_CONNECTION
DENY_CONNECTION = True
printMessage("Deny Connection")
elif arg.lower() == 'drop':
global DROP_CONNECTION
DROP_CONNECTION = True
printMessage("Drop Connection")
elif arg.lower() == 'bad_tls':
global BAD_TLS_RESPONSE
BAD_TLS_RESPONSE = True
printMessage("Bad TLS Response")
elif arg.lower() == 'timeout':
global TIMEOUT_RESPONSE
TIMEOUT_RESPONSE = True
printMessage("Timeout Response")
elif arg.lower() == 'to_deferred':
global TIMEOUT_DEFERRED
TIMEOUT_DEFERRED = True
printMessage("Timeout Deferred Response")
elif arg.lower() == 'slow':
global SLOW_GREETING
SLOW_GREETING = True
printMessage("Slow Greeting")
elif arg.lower() == '--help':
print usage
sys.exit()
else:
print usage
sys.exit()
def main():
if len(sys.argv) < 2:
printMessage("POP3 with no messages")
else:
args = sys.argv[1:]
for arg in args:
processArg(arg)
f = Factory()
f.protocol = POP3TestServer
reactor.listenTCP(PORT, f)
reactor.run()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,86 @@
Return-Path: <twisted-commits-admin@twistedmatrix.com>
Delivered-To: exarkun@meson.dyndns.org
Received: from localhost [127.0.0.1]
by localhost with POP3 (fetchmail-6.2.1)
for exarkun@localhost (single-drop); Thu, 20 Mar 2003 14:50:20 -0500 (EST)
Received: from pyramid.twistedmatrix.com (adsl-64-123-27-105.dsl.austtx.swbell.net [64.123.27.105])
by intarweb.us (Postfix) with ESMTP id 4A4A513EA4
for <exarkun@meson.dyndns.org>; Thu, 20 Mar 2003 14:49:27 -0500 (EST)
Received: from localhost ([127.0.0.1] helo=pyramid.twistedmatrix.com)
by pyramid.twistedmatrix.com with esmtp (Exim 3.35 #1 (Debian))
id 18w648-0007Vl-00; Thu, 20 Mar 2003 13:51:04 -0600
Received: from acapnotic by pyramid.twistedmatrix.com with local (Exim 3.35 #1 (Debian))
id 18w63j-0007VK-00
for <twisted-commits@twistedmatrix.com>; Thu, 20 Mar 2003 13:50:39 -0600
To: twisted-commits@twistedmatrix.com
From: etrepum CVS <etrepum@twistedmatrix.com>
Reply-To: twisted-python@twistedmatrix.com
X-Mailer: CVSToys
Message-Id: <E18w63j-0007VK-00@pyramid.twistedmatrix.com>
Subject: [Twisted-commits] rebuild now works on python versions from 2.2.0 and up.
Sender: twisted-commits-admin@twistedmatrix.com
Errors-To: twisted-commits-admin@twistedmatrix.com
X-BeenThere: twisted-commits@twistedmatrix.com
X-Mailman-Version: 2.0.11
Precedence: bulk
List-Help: <mailto:twisted-commits-request@twistedmatrix.com?subject=help>
List-Post: <mailto:twisted-commits@twistedmatrix.com>
List-Subscribe: <http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits>,
<mailto:twisted-commits-request@twistedmatrix.com?subject=subscribe>
List-Id: <twisted-commits.twistedmatrix.com>
List-Unsubscribe: <http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits>,
<mailto:twisted-commits-request@twistedmatrix.com?subject=unsubscribe>
List-Archive: <http://twistedmatrix.com/pipermail/twisted-commits/>
Date: Thu, 20 Mar 2003 13:50:39 -0600
Modified files:
Twisted/twisted/python/rebuild.py 1.19 1.20
Log message:
rebuild now works on python versions from 2.2.0 and up.
ViewCVS links:
http://twistedmatrix.com/users/jh.twistd/viewcvs/cgi/viewcvs.cgi/twisted/python/rebuild.py.diff?r1=text&tr1=1.19&r2=text&tr2=1.20&cvsroot=Twisted
Index: Twisted/twisted/python/rebuild.py
diff -u Twisted/twisted/python/rebuild.py:1.19 Twisted/twisted/python/rebuild.py:1.20
--- Twisted/twisted/python/rebuild.py:1.19 Fri Jan 17 13:50:49 2003
+++ Twisted/twisted/python/rebuild.py Thu Mar 20 11:50:08 2003
@@ -206,15 +206,27 @@
clazz.__dict__.clear()
clazz.__getattr__ = __getattr__
clazz.__module__ = module.__name__
+ if newclasses:
+ import gc
+ if (2, 2, 0) <= sys.version_info[:3] < (2, 2, 2):
+ hasBrokenRebuild = 1
+ gc_objects = gc.get_objects()
+ else:
+ hasBrokenRebuild = 0
for nclass in newclasses:
ga = getattr(module, nclass.__name__)
if ga is nclass:
log.msg("WARNING: new-class %s not replaced by reload!" % reflect.qual(nclass))
else:
- import gc
- for r in gc.get_referrers(nclass):
- if isinstance(r, nclass):
+ if hasBrokenRebuild:
+ for r in gc_objects:
+ if not getattr(r, '__class__', None) is nclass:
+ continue
r.__class__ = ga
+ else:
+ for r in gc.get_referrers(nclass):
+ if getattr(r, '__class__', None) is nclass:
+ r.__class__ = ga
if doLog:
log.msg('')
log.msg(' (fixing %s): ' % str(module.__name__))
_______________________________________________
Twisted-commits mailing list
Twisted-commits@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-commits

View file

@ -0,0 +1,36 @@
-----BEGIN CERTIFICATE-----
MIIDBjCCAm+gAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJTRzER
MA8GA1UEChMITTJDcnlwdG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQD
ExtNMkNyeXB0byBDZXJ0aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5n
cHNAcG9zdDEuY29tMB4XDTAwMDkxMDA5NTEzMFoXDTAyMDkxMDA5NTEzMFowUzEL
MAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIwEAYDVQQDEwlsb2NhbGhv
c3QxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tMFwwDQYJKoZIhvcNAQEB
BQADSwAwSAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAaOCAQQwggEAMAkGA1UdEwQC
MAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
MB0GA1UdDgQWBBTPhIKSvnsmYsBVNWjj0m3M2z0qVTCBpQYDVR0jBIGdMIGagBT7
hyNp65w6kxXlxb8pUU/+7Sg4AaF/pH0wezELMAkGA1UEBhMCU0cxETAPBgNVBAoT
CE0yQ3J5cHRvMRQwEgYDVQQLEwtNMkNyeXB0byBDQTEkMCIGA1UEAxMbTTJDcnlw
dG8gQ2VydGlmaWNhdGUgTWFzdGVyMR0wGwYJKoZIhvcNAQkBFg5uZ3BzQHBvc3Qx
LmNvbYIBADANBgkqhkiG9w0BAQQFAAOBgQA7/CqT6PoHycTdhEStWNZde7M/2Yc6
BoJuVwnW8YxGO8Sn6UJ4FeffZNcYZddSDKosw8LtPOeWoK3JINjAk5jiPQ2cww++
7QGG/g5NDjxFZNDJP1dGiLAxPW6JXwov4v0FmdzfLOZ01jDcgQQZqEpYlgpuI5JE
WUQ9Ho4EzbYCOQ==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBAKy+e3dulvXzV7zoTZWc5TzgApr8DmeQHTYC8ydfzH7EECe4R1Xh
5kwIzOuuFfn178FBiS84gngaNcrFi0Z5fAkCAwEAAQJBAIqm/bz4NA1H++Vx5Ewx
OcKp3w19QSaZAwlGRtsUxrP7436QjnREM3Bm8ygU11BjkPVmtrKm6AayQfCHqJoT
ZIECIQDW0BoMoL0HOYM/mrTLhaykYAVqgIeJsPjvkEhTFXWBuQIhAM3deFAvWNu4
nklUQ37XsCT2c9tmNt1LAT+slG2JOTTRAiAuXDtC/m3NYVwyHfFm+zKHRzHkClk2
HjubeEgjpj32AQIhAJqMGTaZVOwevTXvvHwNEH+vRWsAYU/gbx+OQB+7VOcBAiEA
oolb6NMg/R3enNPvS1O4UU1H8wpaF77L4yiSWlE0p4w=
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
MIIBDTCBuAIBADBTMQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQ
BgNVBAMTCWxvY2FsaG9zdDEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20w
XDANBgkqhkiG9w0BAQEFAANLADBIAkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5Ad
NgLzJ1/MfsQQJ7hHVeHmTAjM664V+fXvwUGJLziCeBo1ysWLRnl8CQIDAQABoAAw
DQYJKoZIhvcNAQEEBQADQQA7uqbrNTjVWpF6By5ZNPvhZ4YdFgkeXFVWi5ao/TaP
Vq4BG021fJ9nlHRtr4rotpgHDX1rr+iWeHKsx4+5DRSy
-----END CERTIFICATE REQUEST-----

View file

@ -0,0 +1,32 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""Test cases for bounce message generation
"""
from twisted.trial import unittest
from twisted.mail import bounce
import rfc822, cStringIO
class BounceTestCase(unittest.TestCase):
"""
testcases for bounce message generation
"""
def testBounceFormat(self):
from_, to, s = bounce.generateBounce(cStringIO.StringIO('''\
From: Moshe Zadka <moshez@example.com>
To: nonexistant@example.org
Subject: test
'''), 'moshez@example.com', 'nonexistant@example.org')
self.assertEqual(from_, '')
self.assertEqual(to, 'moshez@example.com')
mess = rfc822.Message(cStringIO.StringIO(s))
self.assertEqual(mess['To'], 'moshez@example.com')
self.assertEqual(mess['From'], 'postmaster@example.org')
self.assertEqual(mess['subject'], 'Returned Mail: see transcript for details')
def testBounceMIME(self):
pass

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,75 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Tests for L{twisted.mail.scripts.mailmail}, the implementation of the
command line program I{mailmail}.
"""
import sys
from StringIO import StringIO
from twisted.trial.unittest import TestCase
from twisted.mail.scripts.mailmail import parseOptions
class OptionsTests(TestCase):
"""
Tests for L{parseOptions} which parses command line arguments and reads
message text from stdin to produce an L{Options} instance which can be
used to send a message.
"""
def test_unspecifiedRecipients(self):
"""
If no recipients are given in the argument list and there is no
recipient header in the message text, L{parseOptions} raises
L{SystemExit} with a string describing the problem.
"""
self.addCleanup(setattr, sys, 'stdin', sys.stdin)
sys.stdin = StringIO(
'Subject: foo\n'
'\n'
'Hello, goodbye.\n')
exc = self.assertRaises(SystemExit, parseOptions, [])
self.assertEqual(exc.args, ('No recipients specified.',))
def test_listQueueInformation(self):
"""
The I{-bp} option for listing queue information is unsupported and
if it is passed to L{parseOptions}, L{SystemExit} is raised.
"""
exc = self.assertRaises(SystemExit, parseOptions, ['-bp'])
self.assertEqual(exc.args, ("Unsupported option.",))
def test_stdioTransport(self):
"""
The I{-bs} option for using stdin and stdout as the SMTP transport
is unsupported and if it is passed to L{parseOptions}, L{SystemExit}
is raised.
"""
exc = self.assertRaises(SystemExit, parseOptions, ['-bs'])
self.assertEqual(exc.args, ("Unsupported option.",))
def test_ignoreFullStop(self):
"""
The I{-i} and I{-oi} options for ignoring C{"."} by itself on a line
are unsupported and if either is passed to L{parseOptions},
L{SystemExit} is raised.
"""
exc = self.assertRaises(SystemExit, parseOptions, ['-i'])
self.assertEqual(exc.args, ("Unsupported option.",))
exc = self.assertRaises(SystemExit, parseOptions, ['-oi'])
self.assertEqual(exc.args, ("Unsupported option.",))
def test_copyAliasedSender(self):
"""
The I{-om} option for copying the sender if they appear in an alias
expansion is unsupported and if it is passed to L{parseOptions},
L{SystemExit} is raised.
"""
exc = self.assertRaises(SystemExit, parseOptions, ['-om'])
self.assertEqual(exc.args, ("Unsupported option.",))

View file

@ -0,0 +1,247 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Tests for L{twisted.mail.tap}.
"""
from twisted.trial.unittest import TestCase
from twisted.python.usage import UsageError
from twisted.mail import protocols
from twisted.mail.tap import Options, makeService
from twisted.python.filepath import FilePath
from twisted.internet import endpoints, defer
from twisted.python import util
try:
import OpenSSL
except ImportError, e:
sslSkip = str(e)
else:
sslSkip = None
class OptionsTestCase(TestCase):
"""
Tests for the command line option parser used for I{twistd mail}.
"""
def setUp(self):
self.aliasFilename = self.mktemp()
aliasFile = file(self.aliasFilename, 'w')
aliasFile.write('someuser:\tdifferentuser\n')
aliasFile.close()
def testAliasesWithoutDomain(self):
"""
Test that adding an aliases(5) file before adding a domain raises a
UsageError.
"""
self.assertRaises(
UsageError,
Options().parseOptions,
['--aliases', self.aliasFilename])
def testAliases(self):
"""
Test that adding an aliases(5) file to an IAliasableDomain at least
doesn't raise an unhandled exception.
"""
Options().parseOptions([
'--maildirdbmdomain', 'example.com=example.com',
'--aliases', self.aliasFilename])
def test_barePort(self):
"""
A bare port passed to I{--pop3} results in deprecation warning in
addition to a TCP4ServerEndpoint.
"""
options = Options()
options.parseOptions(['--pop3', '8110'])
self.assertEqual(len(options['pop3']), 1)
self.assertIsInstance(
options['pop3'][0], endpoints.TCP4ServerEndpoint)
warnings = self.flushWarnings([options.opt_pop3])
self.assertEqual(len(warnings), 1)
self.assertEqual(warnings[0]['category'], DeprecationWarning)
self.assertEqual(
warnings[0]['message'],
"Specifying plain ports and/or a certificate is deprecated since "
"Twisted 11.0; use endpoint descriptions instead.")
def _endpointTest(self, service):
"""
Use L{Options} to parse a single service configuration parameter and
verify that an endpoint of the correct type is added to the list for
that service.
"""
options = Options()
options.parseOptions(['--' + service, 'tcp:1234'])
self.assertEqual(len(options[service]), 1)
self.assertIsInstance(
options[service][0], endpoints.TCP4ServerEndpoint)
def test_endpointSMTP(self):
"""
When I{--smtp} is given a TCP endpoint description as an argument, a
TCPServerEndpoint is added to the list of SMTP endpoints.
"""
self._endpointTest('smtp')
def test_endpointPOP3(self):
"""
When I{--pop3} is given a TCP endpoint description as an argument, a
TCPServerEndpoint is added to the list of POP3 endpoints.
"""
self._endpointTest('pop3')
def test_protoDefaults(self):
"""
POP3 and SMTP each listen on a TCP4ServerEndpoint by default.
"""
options = Options()
options.parseOptions([])
self.assertEqual(len(options['pop3']), 1)
self.assertIsInstance(
options['pop3'][0], endpoints.TCP4ServerEndpoint)
self.assertEqual(len(options['smtp']), 1)
self.assertIsInstance(
options['smtp'][0], endpoints.TCP4ServerEndpoint)
def test_protoDisable(self):
"""
The I{--no-pop3} and I{--no-smtp} options disable POP3 and SMTP
respectively.
"""
options = Options()
options.parseOptions(['--no-pop3'])
self.assertEqual(options._getEndpoints(None, 'pop3'), [])
self.assertNotEquals(options._getEndpoints(None, 'smtp'), [])
options = Options()
options.parseOptions(['--no-smtp'])
self.assertNotEquals(options._getEndpoints(None, 'pop3'), [])
self.assertEqual(options._getEndpoints(None, 'smtp'), [])
def test_allProtosDisabledError(self):
"""
If all protocols are disabled, L{UsageError} is raised.
"""
options = Options()
self.assertRaises(
UsageError, options.parseOptions, (['--no-pop3', '--no-smtp']))
def test_pop3sBackwardCompatibility(self):
"""
The deprecated I{--pop3s} and I{--certificate} options set up a POP3 SSL
server.
"""
cert = FilePath(__file__).sibling("server.pem")
options = Options()
options.parseOptions(['--pop3s', '8995',
'--certificate', cert.path])
self.assertEqual(len(options['pop3']), 2)
self.assertIsInstance(
options['pop3'][0], endpoints.SSL4ServerEndpoint)
self.assertIsInstance(
options['pop3'][1], endpoints.TCP4ServerEndpoint)
warnings = self.flushWarnings([options.postOptions])
self.assertEqual(len(warnings), 1)
self.assertEqual(warnings[0]['category'], DeprecationWarning)
self.assertEqual(
warnings[0]['message'],
"Specifying plain ports and/or a certificate is deprecated since "
"Twisted 11.0; use endpoint descriptions instead.")
if sslSkip is not None:
test_pop3sBackwardCompatibility.skip = sslSkip
def test_esmtpWithoutHostname(self):
"""
If I{--esmtp} is given without I{--hostname}, L{Options.parseOptions}
raises L{UsageError}.
"""
options = Options()
exc = self.assertRaises(UsageError, options.parseOptions, ['--esmtp'])
self.assertEqual("--esmtp requires --hostname", str(exc))
def test_auth(self):
"""
Tests that the --auth option registers a checker.
"""
options = Options()
options.parseOptions(['--auth', 'memory:admin:admin:bob:password'])
self.assertEqual(len(options['credCheckers']), 1)
checker = options['credCheckers'][0]
interfaces = checker.credentialInterfaces
registered_checkers = options.service.smtpPortal.checkers
for iface in interfaces:
self.assertEqual(checker, registered_checkers[iface])
class SpyEndpoint(object):
"""
SpyEndpoint remembers what factory it is told to listen with.
"""
listeningWith = None
def listen(self, factory):
self.listeningWith = factory
return defer.succeed(None)
class MakeServiceTests(TestCase):
"""
Tests for L{twisted.mail.tap.makeService}
"""
def _endpointServerTest(self, key, factoryClass):
"""
Configure a service with two endpoints for the protocol associated with
C{key} and verify that when the service is started a factory of type
C{factoryClass} is used to listen on each of them.
"""
cleartext = SpyEndpoint()
secure = SpyEndpoint()
config = Options()
config[key] = [cleartext, secure]
service = makeService(config)
service.privilegedStartService()
service.startService()
self.addCleanup(service.stopService)
self.assertIsInstance(cleartext.listeningWith, factoryClass)
self.assertIsInstance(secure.listeningWith, factoryClass)
def test_pop3(self):
"""
If one or more endpoints is included in the configuration passed to
L{makeService} for the C{"pop3"} key, a service for starting a POP3
server is constructed for each of them and attached to the returned
service.
"""
self._endpointServerTest("pop3", protocols.POP3Factory)
def test_smtp(self):
"""
If one or more endpoints is included in the configuration passed to
L{makeService} for the C{"smtp"} key, a service for starting an SMTP
server is constructed for each of them and attached to the returned
service.
"""
self._endpointServerTest("smtp", protocols.SMTPFactory)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,620 @@
# -*- test-case-name: twisted.mail.test.test_pop3client -*-
# Copyright (c) 2001-2004 Divmod Inc.
# See LICENSE for details.
import sys
import inspect
from zope.interface import directlyProvides
from twisted.mail.pop3 import AdvancedPOP3Client as POP3Client
from twisted.mail.pop3 import InsecureAuthenticationDisallowed
from twisted.mail.pop3 import ServerErrorResponse
from twisted.protocols import loopback
from twisted.internet import reactor, defer, error, protocol, interfaces
from twisted.python import log
from twisted.trial import unittest
from twisted.test.proto_helpers import StringTransport
from twisted.protocols import basic
from twisted.mail.test import pop3testserver
try:
from twisted.test.ssl_helpers import ClientTLSContext, ServerTLSContext
except ImportError:
ClientTLSContext = ServerTLSContext = None
class StringTransportWithConnectionLosing(StringTransport):
def loseConnection(self):
self.protocol.connectionLost(error.ConnectionDone())
capCache = {"TOP": None, "LOGIN-DELAY": "180", "UIDL": None, \
"STLS": None, "USER": None, "SASL": "LOGIN"}
def setUp(greet=True):
p = POP3Client()
# Skip the CAPA login will issue if it doesn't already have a
# capability cache
p._capCache = capCache
t = StringTransportWithConnectionLosing()
t.protocol = p
p.makeConnection(t)
if greet:
p.dataReceived('+OK Hello!\r\n')
return p, t
def strip(f):
return lambda result, f=f: f()
class POP3ClientLoginTestCase(unittest.TestCase):
def testNegativeGreeting(self):
p, t = setUp(greet=False)
p.allowInsecureLogin = True
d = p.login("username", "password")
p.dataReceived('-ERR Offline for maintenance\r\n')
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "Offline for maintenance"))
def testOkUser(self):
p, t = setUp()
d = p.user("username")
self.assertEqual(t.value(), "USER username\r\n")
p.dataReceived("+OK send password\r\n")
return d.addCallback(self.assertEqual, "send password")
def testBadUser(self):
p, t = setUp()
d = p.user("username")
self.assertEqual(t.value(), "USER username\r\n")
p.dataReceived("-ERR account suspended\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "account suspended"))
def testOkPass(self):
p, t = setUp()
d = p.password("password")
self.assertEqual(t.value(), "PASS password\r\n")
p.dataReceived("+OK you're in!\r\n")
return d.addCallback(self.assertEqual, "you're in!")
def testBadPass(self):
p, t = setUp()
d = p.password("password")
self.assertEqual(t.value(), "PASS password\r\n")
p.dataReceived("-ERR go away\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "go away"))
def testOkLogin(self):
p, t = setUp()
p.allowInsecureLogin = True
d = p.login("username", "password")
self.assertEqual(t.value(), "USER username\r\n")
p.dataReceived("+OK go ahead\r\n")
self.assertEqual(t.value(), "USER username\r\nPASS password\r\n")
p.dataReceived("+OK password accepted\r\n")
return d.addCallback(self.assertEqual, "password accepted")
def testBadPasswordLogin(self):
p, t = setUp()
p.allowInsecureLogin = True
d = p.login("username", "password")
self.assertEqual(t.value(), "USER username\r\n")
p.dataReceived("+OK waiting on you\r\n")
self.assertEqual(t.value(), "USER username\r\nPASS password\r\n")
p.dataReceived("-ERR bogus login\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "bogus login"))
def testBadUsernameLogin(self):
p, t = setUp()
p.allowInsecureLogin = True
d = p.login("username", "password")
self.assertEqual(t.value(), "USER username\r\n")
p.dataReceived("-ERR bogus login\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "bogus login"))
def testServerGreeting(self):
p, t = setUp(greet=False)
p.dataReceived("+OK lalala this has no challenge\r\n")
self.assertEqual(p.serverChallenge, None)
def testServerGreetingWithChallenge(self):
p, t = setUp(greet=False)
p.dataReceived("+OK <here is the challenge>\r\n")
self.assertEqual(p.serverChallenge, "<here is the challenge>")
def testAPOP(self):
p, t = setUp(greet=False)
p.dataReceived("+OK <challenge string goes here>\r\n")
d = p.login("username", "password")
self.assertEqual(t.value(), "APOP username f34f1e464d0d7927607753129cabe39a\r\n")
p.dataReceived("+OK Welcome!\r\n")
return d.addCallback(self.assertEqual, "Welcome!")
def testInsecureLoginRaisesException(self):
p, t = setUp(greet=False)
p.dataReceived("+OK Howdy\r\n")
d = p.login("username", "password")
self.failIf(t.value())
return self.assertFailure(
d, InsecureAuthenticationDisallowed)
def testSSLTransportConsideredSecure(self):
"""
If a server doesn't offer APOP but the transport is secured using
SSL or TLS, a plaintext login should be allowed, not rejected with
an InsecureAuthenticationDisallowed exception.
"""
p, t = setUp(greet=False)
directlyProvides(t, interfaces.ISSLTransport)
p.dataReceived("+OK Howdy\r\n")
d = p.login("username", "password")
self.assertEqual(t.value(), "USER username\r\n")
t.clear()
p.dataReceived("+OK\r\n")
self.assertEqual(t.value(), "PASS password\r\n")
p.dataReceived("+OK\r\n")
return d
class ListConsumer:
def __init__(self):
self.data = {}
def consume(self, (item, value)):
self.data.setdefault(item, []).append(value)
class MessageConsumer:
def __init__(self):
self.data = []
def consume(self, line):
self.data.append(line)
class POP3ClientListTestCase(unittest.TestCase):
def testListSize(self):
p, t = setUp()
d = p.listSize()
self.assertEqual(t.value(), "LIST\r\n")
p.dataReceived("+OK Here it comes\r\n")
p.dataReceived("1 3\r\n2 2\r\n3 1\r\n.\r\n")
return d.addCallback(self.assertEqual, [3, 2, 1])
def testListSizeWithConsumer(self):
p, t = setUp()
c = ListConsumer()
f = c.consume
d = p.listSize(f)
self.assertEqual(t.value(), "LIST\r\n")
p.dataReceived("+OK Here it comes\r\n")
p.dataReceived("1 3\r\n2 2\r\n3 1\r\n")
self.assertEqual(c.data, {0: [3], 1: [2], 2: [1]})
p.dataReceived("5 3\r\n6 2\r\n7 1\r\n")
self.assertEqual(c.data, {0: [3], 1: [2], 2: [1], 4: [3], 5: [2], 6: [1]})
p.dataReceived(".\r\n")
return d.addCallback(self.assertIdentical, f)
def testFailedListSize(self):
p, t = setUp()
d = p.listSize()
self.assertEqual(t.value(), "LIST\r\n")
p.dataReceived("-ERR Fatal doom server exploded\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "Fatal doom server exploded"))
def testListUID(self):
p, t = setUp()
d = p.listUID()
self.assertEqual(t.value(), "UIDL\r\n")
p.dataReceived("+OK Here it comes\r\n")
p.dataReceived("1 abc\r\n2 def\r\n3 ghi\r\n.\r\n")
return d.addCallback(self.assertEqual, ["abc", "def", "ghi"])
def testListUIDWithConsumer(self):
p, t = setUp()
c = ListConsumer()
f = c.consume
d = p.listUID(f)
self.assertEqual(t.value(), "UIDL\r\n")
p.dataReceived("+OK Here it comes\r\n")
p.dataReceived("1 xyz\r\n2 abc\r\n5 mno\r\n")
self.assertEqual(c.data, {0: ["xyz"], 1: ["abc"], 4: ["mno"]})
p.dataReceived(".\r\n")
return d.addCallback(self.assertIdentical, f)
def testFailedListUID(self):
p, t = setUp()
d = p.listUID()
self.assertEqual(t.value(), "UIDL\r\n")
p.dataReceived("-ERR Fatal doom server exploded\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "Fatal doom server exploded"))
class POP3ClientMessageTestCase(unittest.TestCase):
def testRetrieve(self):
p, t = setUp()
d = p.retrieve(7)
self.assertEqual(t.value(), "RETR 8\r\n")
p.dataReceived("+OK Message incoming\r\n")
p.dataReceived("La la la here is message text\r\n")
p.dataReceived("..Further message text tra la la\r\n")
p.dataReceived(".\r\n")
return d.addCallback(
self.assertEqual,
["La la la here is message text",
".Further message text tra la la"])
def testRetrieveWithConsumer(self):
p, t = setUp()
c = MessageConsumer()
f = c.consume
d = p.retrieve(7, f)
self.assertEqual(t.value(), "RETR 8\r\n")
p.dataReceived("+OK Message incoming\r\n")
p.dataReceived("La la la here is message text\r\n")
p.dataReceived("..Further message text\r\n.\r\n")
return d.addCallback(self._cbTestRetrieveWithConsumer, f, c)
def _cbTestRetrieveWithConsumer(self, result, f, c):
self.assertIdentical(result, f)
self.assertEqual(c.data, ["La la la here is message text",
".Further message text"])
def testPartialRetrieve(self):
p, t = setUp()
d = p.retrieve(7, lines=2)
self.assertEqual(t.value(), "TOP 8 2\r\n")
p.dataReceived("+OK 2 lines on the way\r\n")
p.dataReceived("Line the first! Woop\r\n")
p.dataReceived("Line the last! Bye\r\n")
p.dataReceived(".\r\n")
return d.addCallback(
self.assertEqual,
["Line the first! Woop",
"Line the last! Bye"])
def testPartialRetrieveWithConsumer(self):
p, t = setUp()
c = MessageConsumer()
f = c.consume
d = p.retrieve(7, f, lines=2)
self.assertEqual(t.value(), "TOP 8 2\r\n")
p.dataReceived("+OK 2 lines on the way\r\n")
p.dataReceived("Line the first! Woop\r\n")
p.dataReceived("Line the last! Bye\r\n")
p.dataReceived(".\r\n")
return d.addCallback(self._cbTestPartialRetrieveWithConsumer, f, c)
def _cbTestPartialRetrieveWithConsumer(self, result, f, c):
self.assertIdentical(result, f)
self.assertEqual(c.data, ["Line the first! Woop",
"Line the last! Bye"])
def testFailedRetrieve(self):
p, t = setUp()
d = p.retrieve(0)
self.assertEqual(t.value(), "RETR 1\r\n")
p.dataReceived("-ERR Fatal doom server exploded\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "Fatal doom server exploded"))
def test_concurrentRetrieves(self):
"""
Issue three retrieve calls immediately without waiting for any to
succeed and make sure they all do succeed eventually.
"""
p, t = setUp()
messages = [
p.retrieve(i).addCallback(
self.assertEqual,
["First line of %d." % (i + 1,),
"Second line of %d." % (i + 1,)])
for i
in range(3)]
for i in range(1, 4):
self.assertEqual(t.value(), "RETR %d\r\n" % (i,))
t.clear()
p.dataReceived("+OK 2 lines on the way\r\n")
p.dataReceived("First line of %d.\r\n" % (i,))
p.dataReceived("Second line of %d.\r\n" % (i,))
self.assertEqual(t.value(), "")
p.dataReceived(".\r\n")
return defer.DeferredList(messages, fireOnOneErrback=True)
class POP3ClientMiscTestCase(unittest.TestCase):
def testCapability(self):
p, t = setUp()
d = p.capabilities(useCache=0)
self.assertEqual(t.value(), "CAPA\r\n")
p.dataReceived("+OK Capabilities on the way\r\n")
p.dataReceived("X\r\nY\r\nZ\r\nA 1 2 3\r\nB 1 2\r\nC 1\r\n.\r\n")
return d.addCallback(
self.assertEqual,
{"X": None, "Y": None, "Z": None,
"A": ["1", "2", "3"],
"B": ["1", "2"],
"C": ["1"]})
def testCapabilityError(self):
p, t = setUp()
d = p.capabilities(useCache=0)
self.assertEqual(t.value(), "CAPA\r\n")
p.dataReceived("-ERR This server is lame!\r\n")
return d.addCallback(self.assertEqual, {})
def testStat(self):
p, t = setUp()
d = p.stat()
self.assertEqual(t.value(), "STAT\r\n")
p.dataReceived("+OK 1 1212\r\n")
return d.addCallback(self.assertEqual, (1, 1212))
def testStatError(self):
p, t = setUp()
d = p.stat()
self.assertEqual(t.value(), "STAT\r\n")
p.dataReceived("-ERR This server is lame!\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "This server is lame!"))
def testNoop(self):
p, t = setUp()
d = p.noop()
self.assertEqual(t.value(), "NOOP\r\n")
p.dataReceived("+OK No-op to you too!\r\n")
return d.addCallback(self.assertEqual, "No-op to you too!")
def testNoopError(self):
p, t = setUp()
d = p.noop()
self.assertEqual(t.value(), "NOOP\r\n")
p.dataReceived("-ERR This server is lame!\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "This server is lame!"))
def testRset(self):
p, t = setUp()
d = p.reset()
self.assertEqual(t.value(), "RSET\r\n")
p.dataReceived("+OK Reset state\r\n")
return d.addCallback(self.assertEqual, "Reset state")
def testRsetError(self):
p, t = setUp()
d = p.reset()
self.assertEqual(t.value(), "RSET\r\n")
p.dataReceived("-ERR This server is lame!\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "This server is lame!"))
def testDelete(self):
p, t = setUp()
d = p.delete(3)
self.assertEqual(t.value(), "DELE 4\r\n")
p.dataReceived("+OK Hasta la vista\r\n")
return d.addCallback(self.assertEqual, "Hasta la vista")
def testDeleteError(self):
p, t = setUp()
d = p.delete(3)
self.assertEqual(t.value(), "DELE 4\r\n")
p.dataReceived("-ERR Winner is not you.\r\n")
return self.assertFailure(
d, ServerErrorResponse).addCallback(
lambda exc: self.assertEqual(exc.args[0], "Winner is not you."))
class SimpleClient(POP3Client):
def __init__(self, deferred, contextFactory = None):
self.deferred = deferred
self.allowInsecureLogin = True
def serverGreeting(self, challenge):
self.deferred.callback(None)
class POP3HelperMixin:
serverCTX = None
clientCTX = None
def setUp(self):
d = defer.Deferred()
self.server = pop3testserver.POP3TestServer(contextFactory=self.serverCTX)
self.client = SimpleClient(d, contextFactory=self.clientCTX)
self.client.timeout = 30
self.connected = d
def tearDown(self):
del self.server
del self.client
del self.connected
def _cbStopClient(self, ignore):
self.client.transport.loseConnection()
def _ebGeneral(self, failure):
self.client.transport.loseConnection()
self.server.transport.loseConnection()
return failure
def loopback(self):
return loopback.loopbackTCP(self.server, self.client, noisy=False)
class TLSServerFactory(protocol.ServerFactory):
class protocol(basic.LineReceiver):
context = None
output = []
def connectionMade(self):
self.factory.input = []
self.output = self.output[:]
map(self.sendLine, self.output.pop(0))
def lineReceived(self, line):
self.factory.input.append(line)
map(self.sendLine, self.output.pop(0))
if line == 'STLS':
self.transport.startTLS(self.context)
class POP3TLSTestCase(unittest.TestCase):
"""
Tests for POP3Client's support for TLS connections.
"""
def test_startTLS(self):
"""
POP3Client.startTLS starts a TLS session over its existing TCP
connection.
"""
sf = TLSServerFactory()
sf.protocol.output = [
['+OK'], # Server greeting
['+OK', 'STLS', '.'], # CAPA response
['+OK'], # STLS response
['+OK', '.'], # Second CAPA response
['+OK'] # QUIT response
]
sf.protocol.context = ServerTLSContext()
port = reactor.listenTCP(0, sf, interface='127.0.0.1')
self.addCleanup(port.stopListening)
H = port.getHost().host
P = port.getHost().port
connLostDeferred = defer.Deferred()
cp = SimpleClient(defer.Deferred(), ClientTLSContext())
def connectionLost(reason):
SimpleClient.connectionLost(cp, reason)
connLostDeferred.callback(None)
cp.connectionLost = connectionLost
cf = protocol.ClientFactory()
cf.protocol = lambda: cp
conn = reactor.connectTCP(H, P, cf)
def cbConnected(ignored):
log.msg("Connected to server; starting TLS")
return cp.startTLS()
def cbStartedTLS(ignored):
log.msg("Started TLS; disconnecting")
return cp.quit()
def cbDisconnected(ign):
log.msg("Disconnected; asserting correct input received")
self.assertEqual(
sf.input,
['CAPA', 'STLS', 'CAPA', 'QUIT'])
def cleanup(result):
log.msg("Asserted correct input; disconnecting client and shutting down server")
conn.disconnect()
return connLostDeferred
cp.deferred.addCallback(cbConnected)
cp.deferred.addCallback(cbStartedTLS)
cp.deferred.addCallback(cbDisconnected)
cp.deferred.addBoth(cleanup)
return cp.deferred
class POP3TimeoutTestCase(POP3HelperMixin, unittest.TestCase):
def testTimeout(self):
def login():
d = self.client.login('test', 'twisted')
d.addCallback(loggedIn)
d.addErrback(timedOut)
return d
def loggedIn(result):
self.fail("Successfully logged in!? Impossible!")
def timedOut(failure):
failure.trap(error.TimeoutError)
self._cbStopClient(None)
def quit():
return self.client.quit()
self.client.timeout = 0.01
# Tell the server to not return a response to client. This
# will trigger a timeout.
pop3testserver.TIMEOUT_RESPONSE = True
methods = [login, quit]
map(self.connected.addCallback, map(strip, methods))
self.connected.addCallback(self._cbStopClient)
self.connected.addErrback(self._ebGeneral)
return self.loopback()
if ClientTLSContext is None:
for case in (POP3TLSTestCase,):
case.skip = "OpenSSL not present"
elif interfaces.IReactorSSL(reactor, None) is None:
for case in (POP3TLSTestCase,):
case.skip = "Reactor doesn't support SSL"
import twisted.mail.pop3client
class POP3ClientMiscTestCase(unittest.TestCase):
"""
Miscellaneous tests more to do with module/package structure than
anything to do with the POP3 client.
"""
def test_all(self):
"""
twisted.mail.pop3client.__all__ should be empty because all classes
should be imported through twisted.mail.pop3.
"""
self.assertEqual(twisted.mail.pop3client.__all__, [])
def test_import(self):
"""
Every public class in twisted.mail.pop3client should be available as a
member of twisted.mail.pop3 with the exception of
twisted.mail.pop3client.POP3Client which should be available as
twisted.mail.pop3.AdvancedClient.
"""
publicClasses = [c[0] for c in inspect.getmembers(
sys.modules['twisted.mail.pop3client'],
inspect.isclass)
if not c[0][0] == '_']
for pc in publicClasses:
if not pc == 'POP3Client':
self.failUnless(hasattr(twisted.mail.pop3, pc))
else:
self.failUnless(hasattr(twisted.mail.pop3,
'AdvancedPOP3Client'))

View file

@ -0,0 +1,18 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Tests for the command-line mailer tool provided by Twisted Mail.
"""
from twisted.trial.unittest import TestCase
from twisted.scripts.test.test_scripts import ScriptTestsMixin
class ScriptTests(TestCase, ScriptTestsMixin):
"""
Tests for all one of mail's scripts.
"""
def test_mailmail(self):
self.scriptTest("mail/mailmail")

File diff suppressed because it is too large Load diff