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"])
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))
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
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")