Fix cloning private repos with basic auth or token

This commit is contained in:
Kazuki Suda
2016-03-24 17:56:22 +09:00
parent a511bb2b49
commit 79726c360d

View File

@@ -16,6 +16,7 @@ import select
import subprocess import subprocess
import sys import sys
import time import time
import urlparse
import urllib import urllib
import urllib2 import urllib2
@@ -95,6 +96,15 @@ def mkdir_p(*args):
else: else:
raise raise
def mask_password(url, secret='*****'):
parsed = urlparse.urlparse(url)
if not parsed.password:
return url
elif parsed.password == 'x-oauth-basic':
return url.replace(parsed.username, secret)
return url.replace(parsed.password, secret)
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description='Backup a github account', parser = argparse.ArgumentParser(description='Backup a github account',
@@ -221,20 +231,26 @@ def parse_args():
return parser.parse_args() return parser.parse_args()
def get_auth(args): def get_auth(args, encode=True):
if args.token: auth = None
return base64.b64encode(args.token + ':' + 'x-oauth-basic')
if args.username: if args.token:
auth = args.token + ':' + 'x-oauth-basic'
elif args.username:
if not args.password: if not args.password:
args.password = getpass.getpass() args.password = getpass.getpass()
return base64.b64encode(args.username + ':' + args.password) auth = args.username + ':' + args.password
elif args.password:
if args.password:
log_error('You must specify a username for basic auth') log_error('You must specify a username for basic auth')
if not auth:
return None return None
if encode == False:
return auth
return base64.b64encode(auth)
def get_github_api_host(args): def get_github_api_host(args):
if args.github_host: if args.github_host:
@@ -245,7 +261,7 @@ def get_github_api_host(args):
return host return host
def get_github_ssh_host(args): def get_github_host(args):
if args.github_host: if args.github_host:
host = args.github_host host = args.github_host
else: else:
@@ -253,6 +269,21 @@ def get_github_ssh_host(args):
return host return host
def get_github_repo_url(args, repository):
if args.prefer_ssh:
return repository['ssh_url']
auth = get_auth(args, False)
if auth:
repo_url = 'https://{0}@{1}/{2}/{3}.git'.format(
auth,
get_github_host(args),
args.user,
repository['name'])
else:
repo_url = repository['clone_url']
return repo_url
def retrieve_data(args, template, query_args=None, single_request=False): def retrieve_data(args, template, query_args=None, single_request=False):
auth = get_auth(args) auth = get_auth(args)
@@ -432,11 +463,7 @@ def backup_repositories(args, output_directory, repositories):
backup_cwd = os.path.join(output_directory, 'repositories') backup_cwd = os.path.join(output_directory, 'repositories')
repo_cwd = os.path.join(backup_cwd, repository['name']) repo_cwd = os.path.join(backup_cwd, repository['name'])
repo_dir = os.path.join(repo_cwd, 'repository') repo_dir = os.path.join(repo_cwd, 'repository')
repo_url = get_github_repo_url(args, repository)
if args.prefer_ssh:
repo_url = repository['ssh_url']
else:
repo_url = repository['clone_url']
if args.include_repository or args.include_everything: if args.include_repository or args.include_everything:
fetch_repository(repository['name'], fetch_repository(repository['name'],
@@ -626,12 +653,14 @@ def fetch_repository(name, remote_url, local_dir, skip_existing=False):
if clone_exists and skip_existing: if clone_exists and skip_existing:
return return
masked_remote_url = mask_password(remote_url)
initalized = subprocess.call('git ls-remote ' + remote_url, initalized = subprocess.call('git ls-remote ' + remote_url,
stdout=FNULL, stdout=FNULL,
stderr=FNULL, stderr=FNULL,
shell=True) shell=True)
if initalized == 128: if initalized == 128:
log_info("Skipping {0} ({1}) since it's not initalized".format(name, remote_url)) log_info("Skipping {0} ({1}) since it's not initalized".format(name, masked_remote_url))
return return
if clone_exists: if clone_exists:
@@ -644,7 +673,7 @@ def fetch_repository(name, remote_url, local_dir, skip_existing=False):
logging_subprocess(git_command, None, cwd=local_dir) logging_subprocess(git_command, None, cwd=local_dir)
else: else:
log_info('Cloning {0} repository from {1} to {2}'.format(name, log_info('Cloning {0} repository from {1} to {2}'.format(name,
remote_url, masked_remote_url,
local_dir)) local_dir))
git_command = ['git', 'clone', remote_url, local_dir] git_command = ['git', 'clone', remote_url, local_dir]
logging_subprocess(git_command, None) logging_subprocess(git_command, None)