From 81ba54549f9e63a638627d4b754ccb7b07fbc0f0 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Fri, 19 Apr 2019 09:50:37 +1000 Subject: [PATCH] Added password prompt functionality. Users will be prompted for a password if required using the 'getpass' module. Additionally, the connect string parser has been modified to extract a username without needing a ':' character in the string. --- transmission-remote-cli | 38 ++++++++++++++++++++++++++++++-------- transmission-remote-cli.1 | 2 +- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/transmission-remote-cli b/transmission-remote-cli index 6d3a39d..32a3636 100755 --- a/transmission-remote-cli +++ b/transmission-remote-cli @@ -49,6 +49,7 @@ from subprocess import call, Popen import netrc import operator from distutils.spawn import find_executable +from getpass import getpass try: import httplib @@ -153,6 +154,9 @@ config.set('Colors', 'file_prio_low', 'bg:yellow,fg:black') config.set('Colors', 'file_prio_off', 'bg:blue,fg:black') +class LoginException(Exception): + pass + class ColorManager(object): def __init__(self, config): self.config = dict() @@ -251,6 +255,8 @@ class TransmissionRequest(object): session_id = m.group(1) self.send_request() except AttributeError: + if e.code == 401: + raise LoginException quit(str(msg) + "\n", CONNECTION_ERROR) except urllib2.URLError as msg: @@ -318,15 +324,22 @@ class Transmission(object): self.path = path if username and password: - password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() - password_mgr.add_password(None, create_url(host, port, path), username, password) - authhandler = urllib2.HTTPBasicAuthHandler(password_mgr) - opener = urllib2.build_opener(authhandler) - urllib2.install_opener(opener) + register_credentials(username, password) # check rpc version request = TransmissionRequest(host, port, path, 'session-get', self.TAG_SESSION_GET) - request.send_request() + try: + request.send_request() + except LoginException: + try: + if not username: + username = raw_input('Username: ') + password = getpass() + except: + print('') + exit() + register_credentials(username, password) + request.send_request() response = request.get_response() self.rpc_version = response['arguments']['rpc-version'] @@ -3593,7 +3606,9 @@ def explode_connection_string(connection): try: if connection.count('@') == 1: auth, connection = connection.split('@') - if auth.count(':') == 1: + if auth.count(':') == 0: + username = auth + elif auth.count(':') == 1: username, password = auth.split(':') if connection.count(':') == 1: host, port = connection.split(':') @@ -3638,6 +3653,13 @@ def read_netrc(file=os.environ['HOME'] + '/.netrc', hostname=None): quit("Cannot read %s: %s\n" % (file, msg)) return login, password +def register_credentials(username, password): + password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() + password_mgr.add_password(None, create_url(host, port, path), username, password) + authhandler = urllib2.HTTPBasicAuthHandler(password_mgr) + opener = urllib2.build_opener(authhandler) + urllib2.install_opener(opener) + # create initial config file def create_config(option, opt_str, value, parser): @@ -3704,7 +3726,7 @@ if __name__ == '__main__': parser.add_option("-v", "--version", action="callback", callback=show_version, help="Show version number and supported Transmission versions.") parser.add_option("-c", "--connect", action="store", dest="connection", default="", - help="Point to the server using pattern [username:password@]host[:port]/[path]") + help="Point to the server using pattern [username[:password]@]host[:port]/[path]. User will be prompted for a password if required.") parser.add_option("-s", "--ssl", action="store_true", dest="ssl", default=False, help="Connect to Transmission using SSL.") parser.add_option("-f", "--config", action="store", dest="configfile", default=default_config_path, diff --git a/transmission-remote-cli.1 b/transmission-remote-cli.1 index 169170c..01e1c6e 100644 --- a/transmission-remote-cli.1 +++ b/transmission-remote-cli.1 @@ -27,7 +27,7 @@ Show usage information and a list of options .IP "-c \fICONNECTION\fB --connect=\fICONNECTION\fR" Point to the server. \fICONNECTION\fR must match the following pattern: .br -[username:password@]host[:port][path] +[username[:password]@]host[:port][path] .br Default: localhost:9091 .B