From 86d973d24ec6771504c37eddc535dff8e03c724f Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Fri, 24 Aug 2012 10:21:02 +0900 Subject: [PATCH] sync: Support authentication to manifest server with .netrc When using the --smart-sync or --smart-tag option, and the specified manifest server is hosted on a server that requires authentication, repo sync fails with the error: HTTP 401 Unauthorized. Add support for getting the credentials from the .netrc file. If a .netrc file exists in the user's home directory, and it contains credentials for the hostname of the manifest server specified in the manifest, use the credentials to authenticate with the manifest server using the URL syntax extension for Basic Authentication: http://user:password@host:port/path Credentials from the .netrc file are only used if the manifest server URL specified in the manifest does not already include credentials. Change-Id: I06e6586e8849d0cd12fa9746789e8d45d5b1f848 --- subcmds/sync.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/subcmds/sync.py b/subcmds/sync.py index cbf0decc..b75bedc1 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -13,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import netrc from optparse import SUPPRESS_HELP import os import re @@ -21,6 +22,7 @@ import socket import subprocess import sys import time +import urlparse import xmlrpclib try: @@ -365,8 +367,34 @@ uncommitted changes are present' % project.relpath print >>sys.stderr, \ 'error: cannot smart sync: no manifest server defined in manifest' sys.exit(1) + + manifest_server = self.manifest.manifest_server + if not '@' in manifest_server: + try: + info = netrc.netrc() + except IOError: + print >>sys.stderr, '.netrc file does not exist or could not be opened' + else: + try: + parse_result = urlparse.urlparse(manifest_server) + if parse_result.hostname: + username, _account, password = \ + info.authenticators(parse_result.hostname) + except TypeError: + # TypeError is raised when the given hostname is not present + # in the .netrc file. + print >>sys.stderr, 'No credentials found for %s in .netrc' % \ + parse_result.hostname + except netrc.NetrcParseError as e: + print >>sys.stderr, 'Error parsing .netrc file: %s' % e + else: + if (username and password): + manifest_server = manifest_server.replace('://', '://%s:%s@' % + (username, password), + 1) + try: - server = xmlrpclib.Server(self.manifest.manifest_server) + server = xmlrpclib.Server(manifest_server) if opt.smart_sync: p = self.manifest.manifestProject b = p.GetBranch(p.CurrentBranch)