From e98607248eec2b149d84efe944c12cbef419b82e Mon Sep 17 00:00:00 2001 From: JoonCheol Park Date: Thu, 11 Oct 2012 02:31:44 +0900 Subject: [PATCH] Support HTTP authentication using user input as fallback If repo could not find authentication credentials from ~/.netrc, this patch tries to get user and password from user's console input. This could be a good choice if user doesn't want to save his plain password in ~/.netrc or if user doesn't know about the netrc usage. The user will be prompted only if authentication infomation does not exist in the password manager. Since main.py firstly loads auth infomation from ~/.netrc, this will be executed only as fallback mechanism. Example: $ repo upload . Upload project xxx/ to remote branch master: branch yyy ( 1 commit, ...): to https://review.zzz.com/gerrit/ (y/N)? y (repo may try to access to https://review.zzz.com/gerrit/ssh_info and will get the 401 HTTP Basic Authentication response from server. If no authentication info in ~/.netrc, This patch will ask username/passwd) Authorization Required (Message from Web Server) User: pororo Password: .... [OK ] xxx/ Change-Id: Ia348a4609ac40060d9093c7dc8d7c2560020455a --- main.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/main.py b/main.py index 665a655b..34dd27dc 100755 --- a/main.py +++ b/main.py @@ -22,6 +22,7 @@ if __name__ == '__main__': del sys.argv[-1] del magic +import getpass import netrc import optparse import os @@ -276,7 +277,25 @@ class _UserAgentHandler(urllib2.BaseHandler): req.add_header('User-Agent', _UserAgent()) return req +def _AddPasswordFromUserInput(handler, msg, req): + # If repo could not find auth info from netrc, try to get it from user input + url = req.get_full_url() + user, password = handler.passwd.find_user_password(None, url) + if user is None: + print msg + try: + user = raw_input('User: ') + password = getpass.getpass() + except KeyboardInterrupt: + return + handler.passwd.add_password(None, url, user, password) + class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler): + def http_error_401(self, req, fp, code, msg, headers): + _AddPasswordFromUserInput(self, msg, req) + return urllib2.HTTPBasicAuthHandler.http_error_401( + self, req, fp, code, msg, headers) + def http_error_auth_reqed(self, authreq, host, req, headers): try: old_add_header = req.add_header @@ -295,6 +314,11 @@ class _BasicAuthHandler(urllib2.HTTPBasicAuthHandler): raise class _DigestAuthHandler(urllib2.HTTPDigestAuthHandler): + def http_error_401(self, req, fp, code, msg, headers): + _AddPasswordFromUserInput(self, msg, req) + return urllib2.HTTPDigestAuthHandler.http_error_401( + self, req, fp, code, msg, headers) + def http_error_auth_reqed(self, auth_header, host, req, headers): try: old_add_header = req.add_header