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 subprocess
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
from functools import cmp_to_key
|
from functools import cmp_to_key
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
try:
|
|
||||||
import requests
|
|
||||||
except ImportError:
|
|
||||||
import urllib.request
|
|
||||||
|
|
||||||
|
|
||||||
# cmp() is not available in Python 3, define it manually
|
# cmp() is not available in Python 3, define it manually
|
||||||
# See https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
|
# 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
|
return reviews
|
||||||
|
|
||||||
|
|
||||||
def fetch_query_via_http(remote_url, query):
|
def build_query_url(remote_url, query, auth):
|
||||||
if "requests" in sys.modules:
|
p = urllib.parse.urlparse(remote_url)._asdict()
|
||||||
auth = None
|
p["path"] = ("/a" if auth else "") + "/changes"
|
||||||
if os.path.isfile(os.getenv("HOME") + "/.gerritrc"):
|
p["query"] = urllib.parse.urlencode(
|
||||||
f = open(os.getenv("HOME") + "/.gerritrc", "r")
|
{
|
||||||
for line in f:
|
"q": query,
|
||||||
parts = line.rstrip().split("|")
|
"o": ["CURRENT_REVISION", "ALL_REVISIONS", "ALL_COMMITS"],
|
||||||
if parts[0] in remote_url:
|
},
|
||||||
auth = requests.auth.HTTPBasicAuth(
|
doseq=True,
|
||||||
username=parts[1], password=parts[2]
|
)
|
||||||
)
|
return urllib.parse.urlunparse(urllib.parse.ParseResult(**p))
|
||||||
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 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:
|
for review in reviews:
|
||||||
review["number"] = review.pop("_number")
|
review["number"] = review.pop("_number")
|
||||||
|
|
||||||
@@ -165,7 +172,7 @@ def fetch_query(remote_url, query):
|
|||||||
if remote_url[0:3] == "ssh":
|
if remote_url[0:3] == "ssh":
|
||||||
return fetch_query_via_ssh(remote_url, query)
|
return fetch_query_via_ssh(remote_url, query)
|
||||||
elif remote_url[0:4] == "http":
|
elif remote_url[0:4] == "http":
|
||||||
return fetch_query_via_http(remote_url, query.replace(" ", "+"))
|
return fetch_query_via_http(remote_url, query)
|
||||||
else:
|
else:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
"Gerrit URL should be in the form http[s]://hostname/ or ssh://[user@]host[:port]"
|
"Gerrit URL should be in the form http[s]://hostname/ or ssh://[user@]host[:port]"
|
||||||
|
Reference in New Issue
Block a user