repopick: Use the builtin urllib to handle HTTP basic authentication
Also do proper URL encode while at it. Change-Id: I64c0913eed535b109af2adc830288b3dd17c0cbb
This commit is contained in:
committed by
Bruno Martins
parent
6f048e37fd
commit
6682b3f35a
@@ -27,14 +27,11 @@ import re
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from functools import cmp_to_key
|
||||
from xml.etree import ElementTree
|
||||
|
||||
try:
|
||||
import requests
|
||||
except ImportError:
|
||||
import urllib.request
|
||||
|
||||
|
||||
# cmp() is not available in Python 3, define it manually
|
||||
# See https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
|
||||
@@ -121,39 +118,49 @@ def fetch_query_via_ssh(remote_url, query):
|
||||
return reviews
|
||||
|
||||
|
||||
def fetch_query_via_http(remote_url, query):
|
||||
if "requests" in sys.modules:
|
||||
auth = None
|
||||
if os.path.isfile(os.getenv("HOME") + "/.gerritrc"):
|
||||
f = open(os.getenv("HOME") + "/.gerritrc", "r")
|
||||
for line in f:
|
||||
parts = line.rstrip().split("|")
|
||||
if parts[0] in remote_url:
|
||||
auth = requests.auth.HTTPBasicAuth(
|
||||
username=parts[1], password=parts[2]
|
||||
)
|
||||
status_code = "-1"
|
||||
if auth:
|
||||
url = "{0}/a/changes/?q={1}&o=CURRENT_REVISION&o=ALL_REVISIONS&o=ALL_COMMITS".format(
|
||||
remote_url, query
|
||||
)
|
||||
data = requests.get(url, auth=auth)
|
||||
status_code = str(data.status_code)
|
||||
if status_code != "200":
|
||||
# They didn't get good authorization or data, Let's try the old way
|
||||
url = "{0}/changes/?q={1}&o=CURRENT_REVISION&o=ALL_REVISIONS&o=ALL_COMMITS".format(
|
||||
remote_url, query
|
||||
)
|
||||
data = requests.get(url)
|
||||
reviews = json.loads(data.text[5:])
|
||||
else:
|
||||
"""Given a query, fetch the change numbers via http"""
|
||||
url = "{0}/changes/?q={1}&o=CURRENT_REVISION&o=ALL_REVISIONS&o=ALL_COMMITS".format(
|
||||
remote_url, query
|
||||
)
|
||||
data = urllib.request.urlopen(url).read().decode("utf-8")
|
||||
reviews = json.loads(data[5:])
|
||||
def build_query_url(remote_url, query, auth):
|
||||
p = urllib.parse.urlparse(remote_url)._asdict()
|
||||
p["path"] = ("/a" if auth else "") + "/changes"
|
||||
p["query"] = urllib.parse.urlencode(
|
||||
{
|
||||
"q": query,
|
||||
"o": ["CURRENT_REVISION", "ALL_REVISIONS", "ALL_COMMITS"],
|
||||
},
|
||||
doseq=True,
|
||||
)
|
||||
return urllib.parse.urlunparse(urllib.parse.ParseResult(**p))
|
||||
|
||||
|
||||
def fetch_query_via_http(remote_url, query, auth=True):
|
||||
"""Given a query, fetch the change numbers via http"""
|
||||
if auth:
|
||||
gerritrc = os.path.expanduser("~/.gerritrc")
|
||||
username = password = ""
|
||||
if os.path.isfile(gerritrc):
|
||||
with open(gerritrc, "r") as f:
|
||||
for line in f:
|
||||
parts = line.rstrip().split("|")
|
||||
if parts[0] in remote_url:
|
||||
username, password = parts[1], parts[2]
|
||||
|
||||
if username and password:
|
||||
url = build_query_url(remote_url, query, auth)
|
||||
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
|
||||
password_mgr.add_password(None, url, username, password)
|
||||
auth_handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
|
||||
opener = urllib.request.build_opener(auth_handler)
|
||||
response = opener.open(url)
|
||||
if response.getcode() != 200:
|
||||
# They didn't get good authorization or data, Let's try the old way
|
||||
return fetch_query_via_http(remote_url, query, False)
|
||||
else:
|
||||
return fetch_query_via_http(remote_url, query, False)
|
||||
else:
|
||||
url = build_query_url(remote_url, query, auth)
|
||||
response = urllib.request.urlopen(url)
|
||||
|
||||
data = response.read().decode("utf-8")
|
||||
reviews = json.loads(data[5:])
|
||||
for review in reviews:
|
||||
review["number"] = review.pop("_number")
|
||||
|
||||
@@ -165,7 +172,7 @@ def fetch_query(remote_url, query):
|
||||
if remote_url[0:3] == "ssh":
|
||||
return fetch_query_via_ssh(remote_url, query)
|
||||
elif remote_url[0:4] == "http":
|
||||
return fetch_query_via_http(remote_url, query.replace(" ", "+"))
|
||||
return fetch_query_via_http(remote_url, query)
|
||||
else:
|
||||
raise Exception(
|
||||
"Gerrit URL should be in the form http[s]://hostname/ or ssh://[user@]host[:port]"
|
||||
|
Reference in New Issue
Block a user