Rev 3759: Add a credential store for '.netrc'. in file:///v/home/vila/src/bzr/experimental/pluggable-credential-stores/

Vincent Ladeuil v.ladeuil+lp at free.fr
Mon Oct 6 11:07:00 BST 2008


At file:///v/home/vila/src/bzr/experimental/pluggable-credential-stores/

------------------------------------------------------------
revno: 3759
revision-id: v.ladeuil+lp at free.fr-20081006100653-m74ulbg7rlfcuqox
parent: v.ladeuil+lp at free.fr-20081005213200-tbgbnnhq6rjabnlz
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: pluggable-credential-stores
timestamp: Mon 2008-10-06 12:06:53 +0200
message:
  Add a credential store for '.netrc'.
  
  * plugins/netrc_credential_store/tests/test_netrc.py: 
  Associated tests.
  
  * plugins/netrc_credential_store/tests/__init__.py: 
  Associated tests.
  
  * plugins/netrc_credential_store/__init__.py: 
  Provides a credential store for .netrc. This also documents how to
  plug a credential store for authentication.conf.
  
  * tests/__init__.py:
  (TestCaseInTempDir.build_tree): Drive-by fix, use assertIsInstance
  instead of assert_ to get a meaningful error message.
-------------- next part --------------
=== added directory 'bzrlib/plugins/netrc_credential_store'
=== added file 'bzrlib/plugins/netrc_credential_store/__init__.py'
--- a/bzrlib/plugins/netrc_credential_store/__init__.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/plugins/netrc_credential_store/__init__.py	2008-10-06 10:06:53 +0000
@@ -0,0 +1,70 @@
+# Copyright (C) 2008 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""Use ~/.netrc as a credential store for authentication.conf."""
+
+from bzrlib import (
+    config,
+    lazy_import,
+    )
+
+lazy_import.lazy_import(globals(), """
+    import errno
+    import netrc
+
+    from bzrlib import (
+        errors,
+        )
+""")
+
+
+class NetrcCredentialStore(config.CredentialStore):
+
+    def __init__(self):
+        super(NetrcCredentialStore, self).__init__()
+        try:
+            self._netrc = netrc.netrc()
+        except IOError, e:
+            if e.args[0] == errno.ENOENT:
+                raise errors.NoSuchFile(e.filename)
+            else:
+                raise
+
+    def decode_password(self, credentials):
+        auth = self._netrc.authenticators(credentials['host'])
+        password = None
+        if auth is not None:
+            user, account, password = auth
+            cred_user = credentials.get('user', None)
+            if cred_user is None or user != cred_user:
+                # We don't use the netrc ability to provide a user since this
+                # is not handled by authentication.conf. So if the user doesn't
+                # match, we don't return a password.
+                password = None
+        return password
+
+
+config.credential_store_registry.register_lazy(
+    'netrc', __name__, 'NetrcCredentialStore', help=__doc__)
+
+
+def load_tests(basic_tests, module, loader):
+    testmod_names = [
+        'tests',
+        ]
+    basic_tests.addTest(loader.loadTestsFromModuleNames(
+            ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
+    return basic_tests

=== added directory 'bzrlib/plugins/netrc_credential_store/tests'
=== added file 'bzrlib/plugins/netrc_credential_store/tests/__init__.py'
--- a/bzrlib/plugins/netrc_credential_store/tests/__init__.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/plugins/netrc_credential_store/tests/__init__.py	2008-10-06 10:06:53 +0000
@@ -0,0 +1,23 @@
+# Copyright (C) 2008 by Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+def load_tests(basic_tests, module, loader):
+    testmod_names = [
+        'test_netrc',
+        ]
+    basic_tests.addTest(loader.loadTestsFromModuleNames(
+            ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
+    return basic_tests

=== added file 'bzrlib/plugins/netrc_credential_store/tests/test_netrc.py'
--- a/bzrlib/plugins/netrc_credential_store/tests/test_netrc.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/plugins/netrc_credential_store/tests/test_netrc.py	2008-10-06 10:06:53 +0000
@@ -0,0 +1,71 @@
+# Copyright (C) 2008 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from bzrlib import (
+    config,
+    errors,
+    osutils,
+    tests,
+    )
+
+from bzrlib.plugins import netrc_credential_store
+
+
+class TestNetrcCSNoNetrc(tests.TestCaseInTempDir):
+
+    def test_home_netrc_does_not_exist(self):
+        self.assertRaises(errors.NoSuchFile,
+                          config.credential_store_registry.get_credential_store,
+                          'netrc')
+
+
+class TestNetrcCS(tests.TestCaseInTempDir):
+
+    def setUp(self):
+        super(TestNetrcCS, self).setUp()
+        # Create a .netrc file
+        netrc_content = """
+machine host login joe password secret
+default login anonymous password joe at home
+"""
+        f = open(osutils.pathjoin(self.test_home_dir, '.netrc'), 'wb')
+        try:
+            f.write(netrc_content)
+        finally:
+            f.close()
+
+    def _get_netrc_cs(self):
+        return  config.credential_store_registry.get_credential_store('netrc')
+
+    def test_not_matching_user(self):
+        cs = self._get_netrc_cs()
+        password = cs.decode_password(dict(host='host', user='jim'))
+        self.assertIs(None, password)
+
+    def test_matching_user(self):
+        cs = self._get_netrc_cs()
+        password = cs.decode_password(dict(host='host', user='joe'))
+        self.assertEquals('secret', password)
+
+    def test_default_password(self):
+        cs = self._get_netrc_cs()
+        password = cs.decode_password(dict(host='other', user='anonymous'))
+        self.assertEquals('joe at home', password)
+
+    def test_default_password_without_user(self):
+        cs = self._get_netrc_cs()
+        password = cs.decode_password(dict(host='other'))
+        self.assertIs(None, password)

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2008-10-01 12:31:03 +0000
+++ b/bzrlib/tests/__init__.py	2008-10-06 10:06:53 +0000
@@ -2136,7 +2136,7 @@
         if transport is None or transport.is_readonly():
             transport = get_transport(".")
         for name in shape:
-            self.assert_(isinstance(name, basestring))
+            self.assertIsInstance(name, basestring)
             if name[-1] == '/':
                 transport.mkdir(urlutils.escape(name[:-1]))
             else:



More information about the bazaar-commits mailing list