Beispiel #1
0
    def _smtp_connect(self):
        """Sets self.smtp to an instance of `smtplib.SMTP`
        and connects using configuration in config.DRIVERS.smtp
        Returns:
            None
        """
        config = self.config.DRIVERS["smtp"]
        if "ssl" in config and config["ssl"] is True:
            self.smtp = smtplib.SMTP_SSL("{0}:{1}".format(
                config["host"], config["port"]))
        else:
            self.smtp = smtplib.SMTP("{0}:{1}".format(config["host"],
                                                      config["port"]))

        # Check if TLS enabled
        if "tls" in config and config["tls"] is True:
            # Define secure TLS connection
            context = ssl.create_default_context()
            context.check_hostname = False

            # Check if correct response code for starttls is received from the server
            if self.smtp.starttls(context=context)[0] != 220:
                raise smtplib.SMTPNotSupportedError(
                    "Server is using untrusted protocol.")

        if config.get("login", True):
            self.smtp.login(config["username"], config["password"])
Beispiel #2
0
    def send(self, message_contents=None):
        """Send the message through SMTP.

        Keyword Arguments:
            message {string} -- The message to be sent to SMTP. (default: {None})

        Returns:
            None
        """
        config = self.config.DRIVERS['smtp']

        message = MIMEMultipart('alternative')

        if not message_contents:
            message_contents = self.message_body

        message_contents = MIMEText(message_contents, 'html')

        message['Subject'] = self.message_subject
        message['From'] = '{0} <{1}>'.format(self.config.FROM['name'],
                                             self.config.FROM['address'])
        message['To'] = self.to_address
        message['Reply-To'] = self.message_reply_to
        message.attach(message_contents)

        # Send the message via our own SMTP server.
        if 'ssl' in config and config['ssl'] is True:
            self.smtp = smtplib.SMTP_SSL('{0}:{1}'.format(
                config['host'], config['port']))
        else:
            self.smtp = smtplib.SMTP('{0}:{1}'.format(config['host'],
                                                      config['port']))

        # Check if TLS enabled
        if 'tls' in config and config['tls'] is True:
            # Define secure TLS connection
            context = ssl.create_default_context()
            context.check_hostname = False

            # Check if correct response code for starttls is received from the server
            if self.smtp.starttls(context=context)[0] != 220:
                raise smtplib.SMTPNotSupportedError(
                    "Server is using untrusted protocol.")

        if config.get('login', True):
            self.smtp.login(config['username'], config['password'])

        if self._queue:
            from wsgi import container
            from ... import Queue
            container.make(Queue).push(self._send_mail,
                                       args=(self.config.FROM['name'],
                                             self.to_address,
                                             message.as_string()))
            return

        self._send_mail(self.config.FROM['name'], self.to_address,
                        message.as_string())
    def test_expecting_auth_command_not_supported_error(self) -> None:
        check = UnitTestSmtpCredentials._create_mocked_method_raising(
            smtplib.SMTPNotSupportedError())

        status, message = UnitTestSmtpCredentials._run_mocked_check(
            self.test_expecting_auth_command_not_supported_error.__name__,
            check)

        self.assertEqual((status, message), (
            False,
            smtpcheck.Messages.SMTP_AUTH_METHOD_NOT_SUPPORTED_BY_SERVER.value))
Beispiel #4
0
    def make_connection(self):
        options = self.options
        if options.get("ssl"):
            smtp = smtplib.SMTP_SSL("{0}:{1}".format(options["host"],
                                                     options["port"]))
        else:
            smtp = smtplib.SMTP("{0}:{1}".format(options["host"],
                                                 int(options["port"])))

        if options.get("tls"):
            context = ssl.create_default_context()
            context.check_hostname = False

            # Check if correct response code for starttls is received from the server
            if smtp.starttls(context=context)[0] != 220:
                raise smtplib.SMTPNotSupportedError(
                    "Server is using untrusted protocol.")

        if options.get("username") and options.get("password"):
            smtp.login(options.get("username"), options.get("password"))

        return smtp
        def login(connection, user, password, *, initial_response_ok=True):
            # self.set_debuglevel(True)
            connection.ehlo_or_helo_if_needed()
            if not connection.has_extn("auth"):
                raise smtplib.SMTPNotSupportedError(
                    "SMTP AUTH extension not supported by server.")

            connection.user, connection.password = user, password

            # Authentication methods the server claims to support
            advertised_authlist = connection.esmtp_features["auth"].split()

            if connection.auth_method not in advertised_authlist:
                raise smtplib.SMTPException(
                    "No suitable authentication method found.")

            try:
                auth_object = _get_oauth2_object(self.user, user,
                                                 self.provider)
            except ValueError as e:
                raise smtplib.SMTPAuthenticationError(
                    code=-1, msg='failed get stored token') from e
            except OAuth2Error as e:
                raise smtplib.SMTPAuthenticationError(code=-1,
                                                      msg=str(e)) from e
            try:
                if auth_object is None:
                    raise smtplib.SMTPAuthenticationError(
                        code=-1, msg='no token stored')
                code, resp = connection.auth(
                    connection.auth_method,
                    auth_object,
                    initial_response_ok=initial_response_ok)
                return code, resp
            except smtplib.SMTPAuthenticationError as e:
                raise e
Beispiel #6
0
    def test_mail_mail_send_exceptions_raise_management(self):
        """ Test various use case with exceptions and errors and see how they are
        managed and stored at mail and notification level. """
        mail, notification = self.test_mail, self.test_notification
        mail.write({
            'email_from': '*****@*****.**',
            'email_to': '*****@*****.**'
        })

        # SMTP connecting issues
        with self.mock_mail_gateway():
            _connect_current = self.connect_mocked.side_effect

            # classic errors that may be raised during sending, just to test their current support
            for error, msg in [
                (smtplib.SMTPServerDisconnected('SMTPServerDisconnected'),
                 'SMTPServerDisconnected'),
                (smtplib.SMTPResponseException('code',
                                               'SMTPResponseException'),
                 'code\nSMTPResponseException'),
                (smtplib.SMTPNotSupportedError('SMTPNotSupportedError'),
                 'SMTPNotSupportedError'),
                (smtplib.SMTPException('SMTPException'), 'SMTPException'),
                (SSLError('SSLError'), 'SSLError'),
                (gaierror('gaierror'), 'gaierror'),
                (timeout('timeout'), 'timeout')
            ]:

                def _connect(*args, **kwargs):
                    raise error

                self.connect_mocked.side_effect = _connect

                mail.send(raise_exception=False)
                self.assertFalse(mail.failure_type)
                self.assertEqual(mail.failure_reason, msg)
                self.assertEqual(mail.state, 'exception')
                self.assertEqual(notification.failure_type, 'mail_smtp')
                self.assertEqual(notification.notification_status, 'exception')
                self._reset_data()

        self.connect_mocked.side_effect = _connect_current

        # SMTP sending issues
        with self.mock_mail_gateway():
            _send_current = self.send_email_mocked.side_effect
            self._reset_data()
            mail.write({'email_to': '*****@*****.**'})

            # should always raise for those errors, even with raise_exception=False
            for error, error_class in [
                (smtplib.SMTPServerDisconnected("Some exception"),
                 smtplib.SMTPServerDisconnected),
                (MemoryError("Some exception"), MemoryError)
            ]:

                def _send_email(*args, **kwargs):
                    raise error

                self.send_email_mocked.side_effect = _send_email

                with self.assertRaises(error_class):
                    mail.send(raise_exception=False)
                self.assertFalse(
                    mail.failure_reason,
                    'SMTPServerDisconnected/MemoryError during Send raises and lead to a rollback'
                )
                self.assertFalse(
                    mail.failure_type,
                    'SMTPServerDisconnected/MemoryError during Send raises and lead to a rollback'
                )
                self.assertEqual(
                    mail.state, 'outgoing',
                    'SMTPServerDisconnected/MemoryError during Send raises and lead to a rollback'
                )
                self.assertFalse(
                    notification.failure_type,
                    'SMTPServerDisconnected/MemoryError during Send raises and lead to a rollback'
                )
                self.assertEqual(
                    notification.notification_status, 'ready',
                    'SMTPServerDisconnected/MemoryError during Send raises and lead to a rollback'
                )

            # MailDeliveryException: should be catched; other issues are sub-catched under
            # a MailDeliveryException and are catched
            for error, msg in [
                (MailDeliveryException("Some exception"), 'Some exception'),
                (ValueError("Unexpected issue"), 'Unexpected issue')
            ]:

                def _send_email(*args, **kwargs):
                    raise error

                self.send_email_mocked.side_effect = _send_email

                self._reset_data()
                mail.send(raise_exception=False)
                self.assertEqual(mail.failure_reason, msg)
                self.assertFalse(mail.failure_type,
                                 'Mail: unlogged failure type to fix')
                self.assertEqual(mail.state, 'exception')
                self.assertEqual(notification.failure_type, 'unknown',
                                 'Mail: generic failure type')
                self.assertEqual(notification.notification_status, 'exception')

            self.send_email_mocked.side_effect = _send_current
 def open(self):
     self.server = smtplib.SMTP(self.address,port=self.port)
     if self.server.starttls()[0] != 220:
         raise smtplib.SMTPNotSupportedError("can't activate starttls")
     self.server.login(self.user, self.password)
     print("Login erfolgreich")