def getClientAddress(self, incoming): """Attempt to get the client's email address from an incoming email. :type incoming: :api:`twisted.mail.smtp.rfc822.Message` :param incoming: An incoming ``Message``, i.e. as returned from :meth:`getIncomingMessage`. :rtype: ``None`` or :api:`twisted.mail.smtp.Address` :returns: The client's email ``Address``, if it originated from a domain that we accept and the address was well-formed. Otherwise, returns ``None``. """ addrHeader = None try: fromAddr = incoming.getaddr("From")[1] except (IndexError, TypeError, AttributeError): pass else: addrHeader = fromAddr if not addrHeader: logging.warn("No From header on incoming mail.") try: senderHeader = incoming.getaddr("Sender")[1] except (IndexError, TypeError, AttributeError): pass else: addrHeader = senderHeader if not addrHeader: logging.warn("No Sender header on incoming mail.") else: try: client = smtp.Address(addr.normalizeEmail( addrHeader, self.context.domainMap, self.context.domainRules)) except (UnsupportedDomain, BadEmail, smtp.AddressError) as error: logging.warn(error) else: return client
def test_permitted(self): """A valid email address from a permitted domain should return unchanged. """ domainrules = {} domainmap = {'foo.example.com': 'example.com'} emailaddr = '*****@*****.**' normalized = addr.normalizeEmail(emailaddr, domainmap, domainrules) self.assertEqual(emailaddr, normalized)
def test_ignoreDots(self): """A valid email address with a '.' should remove the '.' if 'ignore_dots' is in domainrules. """ domainrules = {'example.com': 'ignore_dots'} domainmap = {'foo.example.com': 'example.com'} emailaddr = '*****@*****.**' normalized = addr.normalizeEmail(emailaddr, domainmap, domainrules) self.assertEqual('*****@*****.**', normalized)
def getMailTo(self): """Attempt to get the client's email address from an incoming email. :rtype: list :returns: A list containing the client's :func:`normalized <bridgedb.parse.addr.normalizeEmail>` email :api:`Address <twisted.mail.smtp.Address>`, if it originated from a domain that we accept and the address was well-formed. Otherwise, returns ``None``. Even though we're likely to respond to only one client at a time, the return value of this method must be a list in order to hook into the rest of :api:`twisted.mail.smtp.SMTPClient` correctly. """ clients = [] addrHeader = None try: fromAddr = email.utils.parseaddr( self.incoming.message.get("From"))[1] except (IndexError, TypeError, AttributeError): pass else: addrHeader = fromAddr if not addrHeader: logging.warn("No From header on incoming mail.") try: senderHeader = email.utils.parseaddr( self.incoming.message.get("Sender"))[1] except (IndexError, TypeError, AttributeError): pass else: addrHeader = senderHeader if not addrHeader: logging.warn("No Sender header on incoming mail.") return clients client = None try: if addrHeader in self.incoming.context.whitelist.keys(): logging.debug("Email address was whitelisted: %s." % addrHeader) client = smtp.Address(addrHeader) else: normalized = addr.normalizeEmail( addrHeader, self.incoming.context.domainMap, self.incoming.context.domainRules) client = smtp.Address(normalized) except (addr.UnsupportedDomain) as error: logging.warn(error) except (addr.BadEmail, smtp.AddressError) as error: logging.warn(error) if client: clients.append(client) return clients
def test_ignorePlus(self): """A valid email address with a '+' and some extra stuff, from a permitted domain, should remove the '+' stuff if 'ignore_plus' is enabled. """ domainrules = {} domainmap = {'foo.example.com': 'example.com'} emailaddr = '*****@*****.**' normalized = addr.normalizeEmail(emailaddr, domainmap, domainrules) self.assertEqual('*****@*****.**', normalized)
def test_dontIgnorePlus(self): """A valid email address with a '+' and some extra stuff, from a permitted domain, should return unchanged if 'ignore_plus' is disabled. """ domainrules = {} domainmap = {'foo.example.com': 'example.com'} emailaddr = '*****@*****.**' normalized = addr.normalizeEmail(emailaddr, domainmap, domainrules, ignorePlus=False) self.assertEqual(emailaddr, normalized)
def getMailTo(self): """Attempt to get the client's email address from an incoming email. :rtype: list :returns: A list containing the client's :func:`normalized <bridgedb.parse.addr.normalizeEmail>` email :api:`Address <twisted.mail.smtp.Address>`, if it originated from a domain that we accept and the address was well-formed. Otherwise, returns ``None``. Even though we're likely to respond to only one client at a time, the return value of this method must be a list in order to hook into the rest of :api:`twisted.mail.smtp.SMTPClient` correctly. """ clients = [] addrHeader = None try: fromAddr = self.incoming.message.getaddr("From")[1] except (IndexError, TypeError, AttributeError): pass else: addrHeader = fromAddr if not addrHeader: logging.warn("No From header on incoming mail.") try: senderHeader = self.incoming.message.getaddr("Sender")[1] except (IndexError, TypeError, AttributeError): pass else: addrHeader = senderHeader if not addrHeader: logging.warn("No Sender header on incoming mail.") return clients client = None try: if addrHeader in self.incoming.context.whitelist.keys(): logging.debug("Email address was whitelisted: %s." % addrHeader) client = smtp.Address(addrHeader) else: normalized = addr.normalizeEmail( addrHeader, self.incoming.context.domainMap, self.incoming.context.domainRules) client = smtp.Address(normalized) except (addr.UnsupportedDomain) as error: logging.warn(error) except (addr.BadEmail, smtp.AddressError) as error: logging.warn(error) if client: clients.append(client) return clients