~0x44/nova/bug838466

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/mail/relay.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.mail.test.test_mail -*-
 
2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
 
 
6
"""Support for relaying mail for twisted.mail"""
 
7
 
 
8
from twisted.mail import smtp
 
9
from twisted.python import log
 
10
from twisted.internet.address import UNIXAddress
 
11
 
 
12
import os
 
13
 
 
14
try:
 
15
    import cPickle as pickle
 
16
except ImportError:
 
17
    import pickle
 
18
 
 
19
class DomainQueuer:
 
20
    """An SMTP domain which add messages to a queue intended for relaying."""
 
21
 
 
22
    def __init__(self, service, authenticated=False):
 
23
        self.service = service
 
24
        self.authed = authenticated
 
25
 
 
26
    def exists(self, user):
 
27
        """Check whether we will relay
 
28
 
 
29
        Call overridable willRelay method
 
30
        """
 
31
        if self.willRelay(user.dest, user.protocol):
 
32
            # The most cursor form of verification of the addresses
 
33
            orig = filter(None, str(user.orig).split('@', 1))
 
34
            dest = filter(None, str(user.dest).split('@', 1))
 
35
            if len(orig) == 2 and len(dest) == 2:
 
36
                return lambda: self.startMessage(user)
 
37
        raise smtp.SMTPBadRcpt(user)
 
38
 
 
39
    def willRelay(self, address, protocol):
 
40
        """Check whether we agree to relay
 
41
 
 
42
        The default is to relay for all connections over UNIX
 
43
        sockets and all connections from localhost.
 
44
        """
 
45
        peer = protocol.transport.getPeer()
 
46
        return self.authed or isinstance(peer, UNIXAddress) or peer.host == '127.0.0.1'
 
47
 
 
48
    def startMessage(self, user):
 
49
        """Add envelope to queue and returns ISMTPMessage."""
 
50
        queue = self.service.queue
 
51
        envelopeFile, smtpMessage = queue.createNewMessage()
 
52
        try:
 
53
            log.msg('Queueing mail %r -> %r' % (str(user.orig), str(user.dest)))
 
54
            pickle.dump([str(user.orig), str(user.dest)], envelopeFile)
 
55
        finally:
 
56
            envelopeFile.close()
 
57
        return smtpMessage
 
58
 
 
59
class RelayerMixin:
 
60
 
 
61
    # XXX - This is -totally- bogus
 
62
    # It opens about a -hundred- -billion- files
 
63
    # and -leaves- them open!
 
64
 
 
65
    def loadMessages(self, messagePaths):
 
66
        self.messages = []
 
67
        self.names = []
 
68
        for message in messagePaths:
 
69
            fp = open(message+'-H')
 
70
            try:
 
71
                messageContents = pickle.load(fp)
 
72
            finally:
 
73
                fp.close()
 
74
            fp = open(message+'-D')
 
75
            messageContents.append(fp)
 
76
            self.messages.append(messageContents)
 
77
            self.names.append(message)
 
78
    
 
79
    def getMailFrom(self):
 
80
        if not self.messages:
 
81
            return None
 
82
        return self.messages[0][0]
 
83
 
 
84
    def getMailTo(self):
 
85
        if not self.messages:
 
86
            return None
 
87
        return [self.messages[0][1]]
 
88
 
 
89
    def getMailData(self):
 
90
        if not self.messages:
 
91
            return None
 
92
        return self.messages[0][2]
 
93
 
 
94
    def sentMail(self, code, resp, numOk, addresses, log):
 
95
        """Since we only use one recipient per envelope, this
 
96
        will be called with 0 or 1 addresses. We probably want
 
97
        to do something with the error message if we failed.
 
98
        """
 
99
        if code in smtp.SUCCESS:
 
100
            # At least one, i.e. all, recipients successfully delivered
 
101
            os.remove(self.names[0]+'-D')
 
102
            os.remove(self.names[0]+'-H')
 
103
        del self.messages[0]
 
104
        del self.names[0]
 
105
 
 
106
class SMTPRelayer(RelayerMixin, smtp.SMTPClient):
 
107
    def __init__(self, messagePaths, *args, **kw):
 
108
        smtp.SMTPClient.__init__(self, *args, **kw)
 
109
        self.loadMessages(messagePaths)
 
110
 
 
111
class ESMTPRelayer(RelayerMixin, smtp.ESMTPClient):
 
112
    def __init__(self, messagePaths, *args, **kw):
 
113
        smtp.ESMTPClient.__init__(self, *args, **kw)
 
114
        self.loadMessages(messagePaths)