Rev 2911: Make smtp aware of authentication config. in bzr+ssh://v-ladeuil at bazaar.launchpad.net/%7Ev-ladeuil/bzr/auth.ring/

Vincent Ladeuil v.ladeuil+lp at free.fr
Thu Oct 18 21:39:09 BST 2007


At bzr+ssh://v-ladeuil@bazaar.launchpad.net/%7Ev-ladeuil/bzr/auth.ring/

------------------------------------------------------------
revno: 2911
revision-id: v.ladeuil+lp at free.fr-20071018203841-r7mn8u2jgbm985da
parent: v.ladeuil+lp at free.fr-20071018103311-ysh1obz1wo75lzx0
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: auth.ring
timestamp: Thu 2007-10-18 22:38:41 +0200
message:
  Make smtp aware of authentication config.
  
  * bzrlib/smtp_connection.py:
  (SMTPConnection._authenticate): Try the authentication config
  before prompting the user.
  
  * bzrlib/tests/test_smtp_connection.py:
  Fix some imports.
  (everybody_is_welcome): Fake auth smtp server.
  (TestSMTPConnection): Now inherits from tests.TestCaseInTempDir so
  that we can create an authentication.conf in a protected env.
  (TestSMTPConnection.test_smtp_password_from_auth_config): New test.
  (TestSMTPConnectionWithUI): New test for prompting user.
modified:
  bzrlib/smtp_connection.py      smtp_connection.py-20070618204456-nu6wag1ste4biuk2-1
  bzrlib/tests/test_smtp_connection.py test_smtp_connection-20070618204509-wuyxc0r0ztrecv7e-1
-------------- next part --------------
=== modified file 'bzrlib/smtp_connection.py'
--- a/bzrlib/smtp_connection.py	2007-08-10 16:17:30 +0000
+++ b/bzrlib/smtp_connection.py	2007-10-18 20:38:41 +0000
@@ -21,7 +21,10 @@
 import smtplib
 import socket
 
-from bzrlib import ui
+from bzrlib import (
+    config,
+    ui,
+    )
 from bzrlib.errors import (
     NoDestinationAddress,
     SMTPError,
@@ -89,11 +92,20 @@
         if self._smtp_username is None:
             return
 
-        if self._smtp_password is None:
-            self._smtp_password = ui.ui_factory.get_password(
-                'Please enter the SMTP password: %(user)s@%(host)s',
-                user=self._smtp_username,
-                host=self._smtp_server)
+        password = self._smtp_password
+        if password is None:
+            auth = config.AuthenticationConfig()
+            config_credentials = auth.get_credentials('smtp', self._smtp_server,
+                                                      user=self._smtp_username)
+            if config_credentials is not None:
+                password = config_credentials['password']
+            else:
+                password = ui.ui_factory.get_password(
+                    'Please enter the SMTP password: %(user)s@%(host)s',
+                    user=self._smtp_username,
+                    host=self._smtp_server)
+
+        self._smtp_password = password
 
         self._connection.login(self._smtp_username, self._smtp_password)
 

=== modified file 'bzrlib/tests/test_smtp_connection.py'
--- a/bzrlib/tests/test_smtp_connection.py	2007-08-10 16:17:30 +0000
+++ b/bzrlib/tests/test_smtp_connection.py	2007-10-18 20:38:41 +0000
@@ -19,15 +19,16 @@
 import errno
 import smtplib
 import socket
+import sys
 
 from bzrlib import (
     config,
+    email_message,
     errors,
+    smtp_connection,
+    tests,
+    ui,
     )
-from bzrlib.email_message import EmailMessage
-from bzrlib.errors import NoDestinationAddress
-from bzrlib.tests import TestCase
-from bzrlib.smtp_connection import SMTPConnection
 
 
 def connection_refuser():
@@ -38,13 +39,36 @@
     return smtp
 
 
-class TestSMTPConnection(TestCase):
+def everybody_is_welcome():
+    """Fake a smtp server that implements login by accepting anybody."""
+    def connect(server):
+        return (220, "You're so welcome")
+
+    def starttls():
+        pass
+
+    def login(user, password):
+        pass
+
+    smtp = smtplib.SMTP()
+    smtp.connect = connect
+    smtp.starttls = starttls
+    smtp.login = login
+    return smtp
+
+
+def _get_connection(text, smtp_factory=None):
+    my_config = config.GlobalConfig()
+    config_file = StringIO(text)
+    my_config._get_parser(config_file)
+    return smtp_connection.SMTPConnection(my_config,
+                                          _smtp_factory=smtp_factory)
+
+
+class TestSMTPConnection(tests.TestCaseInTempDir):
 
     def get_connection(self, text, smtp_factory=None):
-        my_config = config.GlobalConfig()
-        config_file = StringIO(text)
-        my_config._get_parser(config_file)
-        return SMTPConnection(my_config, _smtp_factory=smtp_factory)
+        return _get_connection(text, smtp_factory)
 
     def test_defaults(self):
         conn = self.get_connection('')
@@ -70,17 +94,34 @@
         conn = self.get_connection('[DEFAULT]\nsmtp_username=joebody\n')
         self.assertEqual(u'joebody', conn._smtp_username)
 
-    def test_smtp_password(self):
+    def test_smtp_password_from_config(self):
         conn = self.get_connection('')
         self.assertIs(None, conn._smtp_password)
 
         conn = self.get_connection('[DEFAULT]\nsmtp_password=mypass\n')
         self.assertEqual(u'mypass', conn._smtp_password)
 
+    def test_smtp_password_from_auth_config(self):
+        user = 'joe'
+        password = 'hispass'
+        conn = self.get_connection('[DEFAULT]\nsmtp_username=%s\n' % user,
+                                   smtp_factory=everybody_is_welcome)
+        self.assertEqual(user, conn._smtp_username)
+        self.assertIs(None, conn._smtp_password)
+        # Create a config file with the right password
+        conf = config.AuthenticationConfig()
+        conf._get_config().update({'smtptest':
+                                       {'scheme': 'smtp', 'user':user,
+                                        'password': password}})
+        conf._save()
+
+        conn._connect()
+        self.assertEqual(password, conn._smtp_password)
+
     def test_get_message_addresses(self):
         msg = Message()
 
-        from_, to = SMTPConnection.get_message_addresses(msg)
+        from_, to = smtp_connection.SMTPConnection.get_message_addresses(msg)
         self.assertEqual('', from_)
         self.assertEqual([], to)
 
@@ -89,22 +130,22 @@
         msg['CC'] = u'Pepe P\xe9rez <pperez at ejemplo.com>'
         msg['Bcc'] = 'user at localhost'
 
-        from_, to = SMTPConnection.get_message_addresses(msg)
+        from_, to = smtp_connection.SMTPConnection.get_message_addresses(msg)
         self.assertEqual('jrandom at example.com', from_)
         self.assertEqual(sorted(['john at doe.com', 'jane at doe.com',
             'pperez at ejemplo.com', 'user at localhost']), sorted(to))
 
         # now with bzrlib's EmailMessage
-        msg = EmailMessage('"J. Random Developer" <jrandom at example.com>', [
-            'John Doe <john at doe.com>', 'Jane Doe <jane at doe.com>',
-            u'Pepe P\xe9rez <pperez at ejemplo.com>', 'user at localhost' ],
+        msg = email_message.EmailMessage(
+            '"J. Random Developer" <jrandom at example.com>',
+            ['John Doe <john at doe.com>', 'Jane Doe <jane at doe.com>',
+             u'Pepe P\xe9rez <pperez at ejemplo.com>', 'user at localhost' ],
             'subject')
 
-        from_, to = SMTPConnection.get_message_addresses(msg)
+        from_, to = smtp_connection.SMTPConnection.get_message_addresses(msg)
         self.assertEqual('jrandom at example.com', from_)
         self.assertEqual(sorted(['john at doe.com', 'jane at doe.com',
             'pperez at ejemplo.com', 'user at localhost']), sorted(to))
-
     def test_destination_address_required(self):
         class FakeConfig:
             def get_user_option(self, option):
@@ -112,13 +153,51 @@
 
         msg = Message()
         msg['From'] = '"J. Random Developer" <jrandom at example.com>'
-        self.assertRaises(NoDestinationAddress,
-                SMTPConnection(FakeConfig()).send_email, msg)
-
-        msg = EmailMessage('from at from.com', '', 'subject')
-        self.assertRaises(NoDestinationAddress,
-                SMTPConnection(FakeConfig()).send_email, msg)
-
-        msg = EmailMessage('from at from.com', [], 'subject')
-        self.assertRaises(NoDestinationAddress,
-                SMTPConnection(FakeConfig()).send_email, msg)
+        self.assertRaises(
+            errors.NoDestinationAddress,
+            smtp_connection.SMTPConnection(FakeConfig()).send_email, msg)
+
+        msg = email_message.EmailMessage('from at from.com', '', 'subject')
+        self.assertRaises(
+            errors.NoDestinationAddress,
+            smtp_connection.SMTPConnection(FakeConfig()).send_email, msg)
+
+        msg = email_message.EmailMessage('from at from.com', [], 'subject')
+        self.assertRaises(
+            errors.NoDestinationAddress,
+            smtp_connection.SMTPConnection(FakeConfig()).send_email, msg)
+
+
+class TestSMTPConnectionWithUI(tests.TestCaseInTempDir):
+
+    def setUp(self):
+        super(TestSMTPConnectionWithUI, self).setUp()
+        self.old_factory = ui.ui_factory
+        # The following has the unfortunate side-effect of hiding any ouput
+        # during the tests (including pdb prompts). Feel free to comment them
+        # for debugging purposes but leave them in place, there are needed to
+        # run the tests without any console
+        self.old_stdout = sys.stdout
+        sys.stdout = tests.StringIOWrapper()
+        self.addCleanup(self.restoreUIFactory)
+
+    def restoreUIFactory(self):
+        ui.ui_factory = self.old_factory
+        sys.stdout = self.old_stdout
+
+    def get_connection(self, text, smtp_factory=None):
+        return _get_connection(text, smtp_factory)
+
+    def test_smtp_password_from_user(self):
+        user = 'joe'
+        password = 'hispass'
+        conn = self.get_connection('[DEFAULT]\nsmtp_username=%s\n' % user,
+                                   smtp_factory=everybody_is_welcome)
+        self.assertIs(None, conn._smtp_password)
+
+        ui.ui_factory = tests.TestUIFactory(stdin=password + '\n')
+        conn._connect()
+        self.assertEqual(password, conn._smtp_password)
+        # stdin should be empty (the provided password have been consumed)
+        self.assertEqual('', ui.ui_factory.stdin.readline())
+



More information about the bazaar-commits mailing list