def getMailData(self): """Gather all the data for building the response to the client. This method must return a file-like object containing the data of the message to be sent. Lines in the file should be delimited by '\n'. :rtype: ``None`` or :class:`EmailResponse` :returns: An ``EmailResponse``, if we have a response to send in reply to the incoming email, otherwise, returns ``None``. """ clients = self.getMailTo() if not clients: return client = clients[0] # There should have been only one anyway if not self.runChecks(client): return recipient = self.getMailFrom() # Look up the locale part in the 'To:' address, if there is one, and # get the appropriate Translation object: lang = translations.getLocaleFromPlusAddr(recipient) logging.info("Client requested email translation: %s" % lang) body = createResponseBody(self.incoming.lines, self.incoming.context, client, lang) if not body: return # The client was already warned. messageID = self.incoming.message.getheader("Message-ID", None) subject = self.incoming.message.getheader("Subject", None) response = generateResponse(recipient, client, body, subject, messageID, self.incoming.context.gpgContext) return response
def getMailData(self): """Gather all the data for building the response to the client. This method must return a file-like object containing the data of the message to be sent. Lines in the file should be delimited by ``\\n``. :rtype: ``None`` or :class:`EmailResponse` :returns: An ``EmailResponse``, if we have a response to send in reply to the incoming email, otherwise, returns ``None``. """ clients = self.getMailTo() if not clients: return client = clients[0] # There should have been only one anyway # Log the email address that this message came from if SAFELOGGING is # not enabled: if not safelog.safe_logging: logging.debug("Incoming email was from %s ..." % client) if not self.runChecks(client): return recipient = self.getMailFrom() # Look up the locale part in the 'To:' address, if there is one, and # get the appropriate Translation object: lang = translations.getLocaleFromPlusAddr(recipient) logging.info("Client requested email translation: %s" % lang) body = createResponseBody(self.incoming.lines, self.incoming.context, client, lang) # The string EMAIL_MISC_TEXT[1] shows up in an email if BridgeDB # responds with bridges. Everything else we count as an invalid # request. translator = translations.installTranslations(lang) if body is not None and translator.gettext( strings.EMAIL_MISC_TEXT[1]) in body: metrix.recordValidEmailRequest(self) else: metrix.recordInvalidEmailRequest(self) if not body: return # The client was already warned. messageID = self.incoming.message.get("Message-ID", None) subject = self.incoming.message.get("Subject", None) response = generateResponse(recipient, client, body, subject, messageID, self.incoming.context.gpgSignFunc) return response
def test_getLocaleFromPlusAddr_ar(self): emailAddr = '*****@*****.**' replyLocale = translations.getLocaleFromPlusAddr(emailAddr) self.assertEqual('ar', replyLocale)
def reply(self): """Reply to an incoming email. Maybe. If no `response` is returned from :func:`createMailResponse`, then the incoming email will not be responded to at all. This can happen for several reasons, for example: if the DKIM signature was invalid or missing, or if the incoming email came from an unacceptable domain, or if there have been too many emails from this client in the allotted time period. :rtype: :api:`twisted.internet.defer.Deferred` :returns: A ``Deferred`` which will callback when the response has been successfully sent, or errback if an error occurred while sending the email. """ logging.info("Got an email; deciding whether to reply.") def _replyEB(fail): """Errback for a :api:`twisted.mail.smtp.SMTPSenderFactory`. :param fail: A :api:`twisted.python.failure.Failure` which occurred during the transaction. """ logging.debug("_replyToMailEB() called with %r" % fail) error = fail.getTraceback() or "Unknown" logging.error(error) d = defer.Deferred() d.addErrback(_replyEB) incoming = self.getIncomingMessage() recipient = self.getRecipient(incoming) client = self.getClientAddress(incoming) if not client: return d if not self.fromCanonical: self.fromCanonical = self.getCanonicalDomain(client.domain) rules = self.context.domainRules.get(self.fromCanonical, []) if not checkDKIM(incoming, rules): return d clientAddr = '@'.join([client.local, client.domain]) messageID = incoming.getheader("Message-ID", None) subject = incoming.getheader("Subject", None) # Look up the locale part in the 'To:' address, if there is one and # get the appropriate Translation object: lang = translations.getLocaleFromPlusAddr(recipient) logging.info("Client requested email translation: %s" % lang) body = createResponseBody(self.lines, self.context, client, lang) if not body: return d # The client was already warned. response = generateResponse(self.context.fromAddr, clientAddr, body, subject, messageID, self.context.gpgContext) if not response: return d logging.info("Sending reply to %s" % client) factory = smtp.SMTPSenderFactory(self.context.smtpFromAddr, clientAddr, response, d, retries=0, timeout=30) reactor.connectTCP(self.context.smtpServerIP, self.context.smtpServerPort, factory) return d
def test_getLocaleFromPlusAddr_ar(self): emailAddr = '*****@*****.**' replyLocale = translations.getLocaleFromPlusAddr(emailAddr) self.assertEqual('ar', replyLocale)