[PATCH] allow http authentication information to be specified in the configuration
Sune Foldager
cryo at cyanite.org
Wed Apr 22 06:37:48 CDT 2009
Changed to a config style inspired by [merge-tools], as discussed with tonfa and djc on IRC.
# HG changeset patch
# User Sune Foldager <cryo at cyanite.org>
# Date 1240398504 -7200
# Node ID 6f75c801af5647f3667d358d002f3f1ff35eb2c1
# Parent 28a72f620cdef2883d1332a5edcc14b05224fd7b
allow http authentication information to be specified in the configuration
diff --git a/doc/hgrc.5.txt b/doc/hgrc.5.txt
--- a/doc/hgrc.5.txt
+++ b/doc/hgrc.5.txt
@@ -100,6 +100,41 @@
Mercurial "hgrc" file, the purpose of each section, its possible
keys, and their possible values.
+[[auth]]
+auth:
+ Authentication credentials for HTTP authentication.
+ Each line has the following format:
+
+ <name>.<argument> = <value>
+
+ where <name> is used to group arguments into authentication entries.
+ Example:
+
+ foo.prefix = hg.intevation.org/mercurial
+ foo.credentials = foo:bar
+ foo.schemas = http https
+
+ Supported arguments:
+
+ prefix;;
+ Either '*' or an URI prefix without the schema part. The authentication
+ entry with the longest matching prefix is used (where '*' matches
+ everything and counts as a match of length 1).
+ If this argument is not given, the authentication entry is skipped.
+ credentials;;
+ The username-password pair to authenticiate with, in the same format
+ used in URIs. Password is optional and if left out, the user will be
+ prompted for it.
+ If this argument is not given, the authentication entry is skipped.
+ schemas;;
+ The space-separated list of URI-schemas to use this authentication
+ entry with. Supported schemas are http and https. They will match
+ static-http and static-https respectively, as well.
+ Default: https.
+
+ If no suitable authentication entry is found, the user is prompted for
+ credentials as usual if required by the remote.
+
[[decode]]
decode/encode::
Filters for transforming files on checkout/checkin. This would
diff --git a/mercurial/url.py b/mercurial/url.py
--- a/mercurial/url.py
+++ b/mercurial/url.py
@@ -105,24 +105,61 @@
self, realm, authuri)
user, passwd = authinfo
if user and passwd:
+ self._writedebug(user, passwd)
return (user, passwd)
- if not self.ui.interactive:
- raise util.Abort(_('http authorization required'))
+ user, passwd = self._readauthtoken(authuri)
+ if not user or not passwd:
+ if not self.ui.interactive:
+ raise util.Abort(_('http authorization required'))
- self.ui.write(_("http authorization required\n"))
- self.ui.status(_("realm: %s\n") % realm)
- if user:
- self.ui.status(_("user: %s\n") % user)
- else:
- user = self.ui.prompt(_("user:"), default=None)
+ self.ui.write(_("http authorization required\n"))
+ self.ui.status(_("realm: %s\n") % realm)
+ if user:
+ self.ui.status(_("user: %s\n") % user)
+ else:
+ user = self.ui.prompt(_("user:"), default=None)
- if not passwd:
- passwd = self.ui.getpass()
+ if not passwd:
+ passwd = self.ui.getpass()
self.add_password(realm, authuri, user, passwd)
+ self._writedebug(user, passwd)
return (user, passwd)
+ def _writedebug(self, user, passwd):
+ self.ui.debug(_('http auth: user %s, password %s\n') %
+ (user, passwd and '*' * len(passwd) or 'not set'))
+
+ def _readauthconfig(self):
+ config = dict()
+ for key, val in self.ui.configitems('auth'):
+ group, setting = key.split('.', 1)
+ if group in config:
+ d = config[group]
+ else:
+ config[group] = d = dict()
+ d[setting] = val
+ return config
+
+ def _readauthtoken(self, uri):
+ config = self._readauthconfig()
+ schema, hostpath = uri.split('://', 1)
+ bestlen = 0
+ bestauth = None
+
+ for auth in config.itervalues():
+ prefix = auth.get('prefix')
+ if not prefix: continue
+ schemas = (auth.get('schemas') or 'https').split()
+ if (prefix == '*' or hostpath.startswith(prefix)) and len(prefix) > bestlen and schema in schemas:
+ bestlen = len(prefix)
+ bestauth = auth.get('credentials')
+
+ if bestauth:
+ return netlocsplit(bestauth + '@dummy')[2:4]
+ return None, None
+
class proxyhandler(urllib2.ProxyHandler):
def __init__(self, ui):
proxyurl = ui.config("http_proxy", "host") or os.getenv('http_proxy')
@@ -285,9 +322,6 @@
passmgr = passwordmgr(ui)
if authinfo is not None:
passmgr.add_password(*authinfo)
- user, passwd = authinfo[2:4]
- ui.debug(_('http auth: user %s, password %s\n') %
- (user, passwd and '*' * len(passwd) or 'not set'))
handlers.extend((urllib2.HTTPBasicAuthHandler(passmgr),
httpdigestauthhandler(passmgr)))
More information about the Mercurial-devel
mailing list