diff options
-rwxr-xr-x | git-bz | 97 |
1 files changed, 84 insertions, 13 deletions
@@ -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,6 +958,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 = {} @@ -898,10 +966,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, 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) |