summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathon Jongsma <jonathon@quotidian.org>2009-09-10 23:35:25 -0500
committerJonathon Jongsma <jonathon@quotidian.org>2009-09-11 00:14:38 -0500
commit9e026a19f7d3d7acc3ac8a82a9fc56512d80452c (patch)
treefe7b9b24913194069d9d196c8b623df1771d7c3d
parentd385649106fef9901dd33f63efb550d19c7204d4 (diff)
downloadgit-bz-9e026a19f7d3d7acc3ac8a82a9fc56512d80452c.tar.gz
Add support for bugzilla installations that require http auth
This patch should support http authentication credentials specified in url form (e.g. https://user:password@foo.com) or in a configuration file. The additional configure options are: - bz-tracker.<alias>.authuser - bz-tracker.<alias>.authpwd
-rwxr-xr-xgit-bz58
1 files changed, 50 insertions, 8 deletions
diff --git a/git-bz b/git-bz
index dbcd618..8f9e8dc 100755
--- a/git-bz
+++ b/git-bz
@@ -79,6 +79,7 @@ import traceback
import xmlrpclib
import urlparse
from xml.etree.cElementTree import ElementTree
+import base64
# Globals
# =======
@@ -335,6 +336,18 @@ def tracker_get_path(tracker):
return config['path']
return None
+def tracker_get_auth_user(tracker):
+ config = get_config(tracker)
+ if 'path' in config:
+ return config['authuser']
+ return None
+
+def tracker_get_auth_password(tracker):
+ config = get_config(tracker)
+ if 'path' in config:
+ return config['authpwd']
+ return None
+
def get_default_fields(tracker):
config = get_config(tracker)
@@ -357,11 +370,13 @@ class BugParseError(Exception):
# uniquely identifies a bug on a server, though until we try
# to load it (and create a Bug) we don't know if it actually exists.
class BugHandle:
- def __init__(self, host, path, https, id):
+ def __init__(self, host, path, https, id, authuser=None, authpwd=None):
self.host = host
self.path = path
self.https = https
self.id = id
+ self.authuser = authuser
+ self.authpwd = authpwd
# ensure that the path to the bugzilla installation is an absolute path
# so that it will still work even if their config option specifies
@@ -377,10 +392,23 @@ class BugHandle:
self.host,
self.id)
+ def needs_auth(self):
+ return self.authuser and self.authpwd
+
@staticmethod
def parse(bug_reference):
parseresult = urlparse.urlsplit (bug_reference)
+ user = parseresult.username
+ pwd = parseresult.password
+ # if the url did not specify http auth credentials in the form
+ # https://user:pwd@host.com, check to see whether the config file
+ # specifies any auth credentials for this host
+ if not user:
+ user = tracker_get_auth_user(parseresult.hostname)
+ if not pwd:
+ pwd = tracker_get_auth_password(parseresult.hostname)
+
# strip off everything after the last '/', so '/bugzilla/show_bug.cgi'
# will simply become '/bugzilla'
path = parseresult.path[:parseresult.path.rfind('/')]
@@ -390,7 +418,9 @@ class BugHandle:
return BugHandle(host=parseresult.hostname,
path=path,
https=parseresult.scheme=="https",
- id=m.group(1))
+ id=m.group(1),
+ authuser=user,
+ authpwd=pwd)
colon = bug_reference.find(":")
if colon > 0:
@@ -406,11 +436,13 @@ class BugHandle:
host = resolve_host_alias(tracker)
https = tracker_uses_https(tracker)
path = tracker_get_path(tracker)
+ authuser = tracker_get_auth_user(tracker)
+ authpwd = tracker_get_auth_password(tracker)
if not re.match(r"^.*\.[a-zA-Z]{2,}$", host):
raise BugParseError("'%s' doesn't look like a valid bugzilla host or alias" % host)
- return BugHandle(host=host, path=path, https=https, id=id)
+ return BugHandle(host=host, path=path, https=https, id=id, authuser=authuser, authpwd=authpwd)
@staticmethod
def parse_or_die(str):
@@ -712,6 +744,9 @@ def die(message):
print >>sys.stderr, message
sys.exit(1)
+def http_auth_header(user, password):
+ return 'Basic ' + base64.encodestring("%s:%s" % (user, password)).strip()
+
# Classes for bug handling
# ========================
@@ -737,10 +772,12 @@ def get_connection(host, https):
return connections[identifier]
class BugServer(object):
- def __init__(self, host, path, https):
+ def __init__(self, host, path, https, authuser=None, authpwd=None):
self.host = host
self.path = path
self.https = https
+ self.authuser = authuser
+ self.authpwd = authpwd
self.cookies = get_bugzilla_cookies(host)
@@ -754,6 +791,8 @@ class BugServer(object):
headers = dict(headers)
headers['Cookie'] = self.get_cookie_string()
headers['User-Agent'] = "git-bz"
+ if self.authuser and self.authpwd:
+ headers['Authorization'] = http_auth_header(self.authuser, self.authpwd)
if self.path:
url = self.path + url
@@ -880,6 +919,7 @@ class BugTransport(xmlrpclib.Transport):
def send_request(self, connection, *args):
xmlrpclib.Transport.send_request(self, connection, *args)
connection.putheader("Cookie", self.server.get_cookie_string())
+ connection.putheader("Authorization", http_auth_header(self.server.authuser, self.server.authpwd))
servers = {}
@@ -887,10 +927,10 @@ servers = {}
# host/https of the server to avoid doing too many redirections, and
# so the host,https we connect to may be different than what we use
# to look up the server.
-def get_bug_server(host, path, https):
+def get_bug_server(host, path, https, authuser, authpwd):
identifier = (host, path, https)
if not identifier in servers:
- servers[identifier] = BugServer(host, path, https)
+ servers[identifier] = BugServer(host, path, https, authuser, authpwd)
return servers[identifier]
@@ -1138,7 +1178,7 @@ class Bug(object):
@staticmethod
def load(bug_reference, attachmentdata=False):
- server = get_bug_server(bug_reference.host, bug_reference.path, bug_reference.https)
+ server = get_bug_server(bug_reference.host, bug_reference.path, bug_reference.https, bug_reference.authuser, bug_reference.authpwd)
bug = Bug(server)
bug._load(bug_reference.id, attachmentdata)
@@ -1149,9 +1189,11 @@ class Bug(object):
host = resolve_host_alias(tracker)
https = tracker_uses_https(tracker)
path = tracker_get_path(tracker)
+ authuser = tracker_get_auth_user(tracker)
+ authpwd = tracker_get_auth_password(tracker)
default_fields = get_default_fields(tracker)
- server = get_bug_server(host, path, https)
+ server = get_bug_server(host, path, https, authuser, authpwd)
bug = Bug(server)
bug._create(product, component, short_desc, comment, default_fields)