Permalink
Browse files

Merge remote branch 'jjongsma/http-auth'

  • Loading branch information...
2 parents 55d8141 + 5c52c2f commit ca9301d17cdfa96113d6a55a6a6b5f344a90fa20 @owtaylor owtaylor committed Sep 6, 2010
Showing with 84 additions and 13 deletions.
  1. +84 −13 git-bz
View
97 git-bz
@@ -82,6 +82,7 @@ import traceback
import xmlrpclib
import urlparse
from xml.etree.cElementTree import ElementTree
+import base64
# Globals
# =======
@@ -334,6 +335,24 @@ def tracker_uses_https(tracker):
config = get_config(tracker)
return 'https' in config and config['https'] == 'true'
+def tracker_get_path(tracker):
+ config = get_config(tracker)
+ if 'path' in config:
+ 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)
@@ -356,23 +375,58 @@ 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, 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
+ # something like:
+ # path = bugzilla
+ # instead of the proper form:
+ # path = /bugzilla
+ if self.path and self.path[0] != '/':
+ self.path = '/' + self.path
def get_url(self):
return "%s://%s/show_bug.cgi?id=%s" % ("https" if self.https else "http",
self.host,
self.id)
+ def needs_auth(self):
+ return self.authuser and self.authpwd
+
@staticmethod
def parse(bug_reference):
- m = re.match("http(s?)://([^/]+)/show_bug.cgi\?id=([^&]+)", bug_reference)
- if m:
- return BugHandle(host=m.group(2),
- https=m.group(1) != "",
- id=m.group(3))
+ parseresult = urlparse.urlsplit (bug_reference)
+
+ if parseresult.scheme in ('http', 'https'):
+ 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('/')]
+ m = re.match("id=([^&]+)", parseresult.query)
+
+ if m:
+ return BugHandle(host=parseresult.hostname,
+ path=path,
+ https=parseresult.scheme=="https",
+ id=m.group(1),
+ authuser=user,
+ authpwd=pwd)
colon = bug_reference.find(":")
if colon > 0:
@@ -387,11 +441,14 @@ 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, https=https, id=id)
+ return BugHandle(host=host, path=path, https=https, id=id, authuser=authuser, authpwd=authpwd)
@staticmethod
def parse_or_die(str):
@@ -728,6 +785,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
# ========================
@@ -753,9 +813,12 @@ def get_connection(host, https):
return connections[identifier]
class BugServer(object):
- def __init__(self, host, 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)
@@ -769,6 +832,10 @@ 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
seen_urls = []
connection = get_connection(self.host, self.https)
@@ -891,17 +958,18 @@ 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 = {}
# Note that if we detect that we are redirecting, we may rewrite the
# 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, https):
- identifier = (host, https)
+def get_bug_server(host, path, https, authuser, authpwd):
+ identifier = (host, path, https)
if not identifier in servers:
- servers[identifier] = BugServer(host, https)
+ servers[identifier] = BugServer(host, path, https, authuser, authpwd)
return servers[identifier]
@@ -1149,7 +1217,7 @@ class Bug(object):
@staticmethod
def load(bug_reference, attachmentdata=False):
- server = get_bug_server(bug_reference.host, 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)
@@ -1159,9 +1227,12 @@ class Bug(object):
def create(tracker, product, component, short_desc, comment):
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, https)
+ server = get_bug_server(host, path, https, authuser, authpwd)
bug = Bug(server)
bug._create(product, component, short_desc, comment, default_fields)

0 comments on commit ca9301d

Please sign in to comment.