Use a specific response code for authentication requests. Recreate authentication request exceptions on the client end.
This commit is contained in:
parent
67ff83360f
commit
b3870ad6dd
|
@ -191,17 +191,6 @@ class Daemon(object):
|
||||||
except twisted.internet.error.ReactorNotRunning:
|
except twisted.internet.error.ReactorNotRunning:
|
||||||
log.debug("Tried to stop the reactor but it is not running..")
|
log.debug("Tried to stop the reactor but it is not running..")
|
||||||
|
|
||||||
@export()
|
|
||||||
def info(self):
|
|
||||||
"""
|
|
||||||
Returns some info from the daemon.
|
|
||||||
|
|
||||||
:returns: str, the version number
|
|
||||||
"""
|
|
||||||
print '\n\ndaemon.info called\n\n'
|
|
||||||
|
|
||||||
return deluge.common.get_version()
|
|
||||||
|
|
||||||
@export()
|
@export()
|
||||||
def get_method_list(self):
|
def get_method_list(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -56,11 +56,12 @@ except ImportError:
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
import deluge.configmanager
|
import deluge.configmanager
|
||||||
from deluge.core.authmanager import AUTH_LEVEL_NONE, AUTH_LEVEL_DEFAULT, AUTH_LEVEL_ADMIN
|
from deluge.core.authmanager import AUTH_LEVEL_NONE, AUTH_LEVEL_DEFAULT, AUTH_LEVEL_ADMIN
|
||||||
from deluge.error import DelugeError, NotAuthorizedError
|
from deluge.error import DelugeError, NotAuthorizedError, AuthenticationRequired
|
||||||
|
|
||||||
RPC_RESPONSE = 1
|
RPC_RESPONSE = 1
|
||||||
RPC_ERROR = 2
|
RPC_ERROR = 2
|
||||||
RPC_EVENT = 3
|
RPC_EVENT = 3
|
||||||
|
RPC_EVENT_AUTH = 4
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -261,6 +262,8 @@ class DelugeRPCProtocol(Protocol):
|
||||||
if ret:
|
if ret:
|
||||||
self.factory.authorized_sessions[self.transport.sessionno] = (ret, args[0])
|
self.factory.authorized_sessions[self.transport.sessionno] = (ret, args[0])
|
||||||
self.factory.session_protocols[self.transport.sessionno] = self
|
self.factory.session_protocols[self.transport.sessionno] = self
|
||||||
|
except AuthenticationRequired, err:
|
||||||
|
self.sendData((RPC_EVENT_AUTH, request_id, err.message, args[0]))
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
sendError()
|
sendError()
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
|
|
|
@ -56,6 +56,23 @@ class BadLoginError(DelugeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AuthenticationRequired(BadLoginError):
|
class AuthenticationRequired(BadLoginError):
|
||||||
|
def _get_message(self):
|
||||||
|
return self._message
|
||||||
|
def _set_message(self, message):
|
||||||
|
self._message = message
|
||||||
|
message = property(_get_message, _set_message)
|
||||||
|
del _get_message, _set_message
|
||||||
|
|
||||||
|
def _get_username(self):
|
||||||
|
return self._username
|
||||||
|
def _set_username(self, username):
|
||||||
|
self._username = username
|
||||||
|
username = property(_get_username, _set_username)
|
||||||
|
del _get_username, _set_username
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, message, username):
|
def __init__(self, message, username):
|
||||||
super(AuthenticationRequired, self).__init__(message)
|
super(AuthenticationRequired, self).__init__(message)
|
||||||
|
self.message = message
|
||||||
self.username = username
|
self.username = username
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@ import zlib
|
||||||
import deluge.common
|
import deluge.common
|
||||||
import deluge.component as component
|
import deluge.component as component
|
||||||
from deluge.log import LOG as log
|
from deluge.log import LOG as log
|
||||||
|
from deluge.error import AuthenticationRequired
|
||||||
|
from deluge.event import known_events
|
||||||
|
|
||||||
if deluge.common.windows_check():
|
if deluge.common.windows_check():
|
||||||
import win32api
|
import win32api
|
||||||
|
@ -55,6 +57,7 @@ else:
|
||||||
RPC_RESPONSE = 1
|
RPC_RESPONSE = 1
|
||||||
RPC_ERROR = 2
|
RPC_ERROR = 2
|
||||||
RPC_EVENT = 3
|
RPC_EVENT = 3
|
||||||
|
RPC_EVENT_AUTH = 4
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -184,6 +187,8 @@ class DelugeRPCProtocol(Protocol):
|
||||||
if message_type == RPC_RESPONSE:
|
if message_type == RPC_RESPONSE:
|
||||||
# Run the callbacks registered with this Deferred object
|
# Run the callbacks registered with this Deferred object
|
||||||
d.callback(request[2])
|
d.callback(request[2])
|
||||||
|
elif message_type == RPC_EVENT_AUTH:
|
||||||
|
d.errback(AuthenticationRequired(request[2], request[3]))
|
||||||
elif message_type == RPC_ERROR:
|
elif message_type == RPC_ERROR:
|
||||||
# Create the DelugeRPCError to pass to the errback
|
# Create the DelugeRPCError to pass to the errback
|
||||||
r = self.__rpc_requests[request_id]
|
r = self.__rpc_requests[request_id]
|
||||||
|
@ -382,8 +387,19 @@ class DaemonSSLProxy(DaemonProxy):
|
||||||
:param error_data: this is passed from the deferred errback with error.value
|
:param error_data: this is passed from the deferred errback with error.value
|
||||||
containing a `:class:DelugeRPCError` object.
|
containing a `:class:DelugeRPCError` object.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
if error_data.check(AuthenticationRequired):
|
||||||
|
print error_data.value.__dict__
|
||||||
|
return error_data
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# print 1234567, error_data
|
||||||
# Get the DelugeRPCError object from the error_data
|
# Get the DelugeRPCError object from the error_data
|
||||||
error = error_data.value
|
error = error_data.value
|
||||||
|
|
||||||
|
# if error.exception_type == "AuthenticationRequired":
|
||||||
|
# return
|
||||||
# Create a delugerpcrequest to print out a nice RPCRequest string
|
# Create a delugerpcrequest to print out a nice RPCRequest string
|
||||||
r = DelugeRPCRequest()
|
r = DelugeRPCRequest()
|
||||||
r.method = error.method
|
r.method = error.method
|
||||||
|
@ -545,7 +561,8 @@ class Client(object):
|
||||||
self.disconnect_callback = None
|
self.disconnect_callback = None
|
||||||
self.__started_in_classic = False
|
self.__started_in_classic = False
|
||||||
|
|
||||||
def connect(self, host="127.0.0.1", port=58846, username="", password=""):
|
def connect(self, host="127.0.0.1", port=58846, username="", password="",
|
||||||
|
skip_authentication=False):
|
||||||
"""
|
"""
|
||||||
Connects to a daemon process.
|
Connects to a daemon process.
|
||||||
|
|
||||||
|
@ -573,7 +590,7 @@ class Client(object):
|
||||||
return result
|
return result
|
||||||
d.addErrback(on_connect_fail)
|
d.addErrback(on_connect_fail)
|
||||||
|
|
||||||
if username or password:
|
if not skip_authentication:
|
||||||
auth_deferred = defer.Deferred()
|
auth_deferred = defer.Deferred()
|
||||||
|
|
||||||
def on_authenticate(result, daemon_info):
|
def on_authenticate(result, daemon_info):
|
||||||
|
|
|
@ -48,6 +48,8 @@ from deluge.ui.client import client
|
||||||
import deluge.ui.client
|
import deluge.ui.client
|
||||||
import deluge.ui.common
|
import deluge.ui.common
|
||||||
from deluge.configmanager import ConfigManager
|
from deluge.configmanager import ConfigManager
|
||||||
|
from deluge.error import AuthenticationRequired
|
||||||
|
from deluge.log import LOG as log
|
||||||
import dialogs
|
import dialogs
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -234,7 +236,11 @@ class ConnectionManager(component.Component):
|
||||||
# Grab the hosts from the liststore
|
# Grab the hosts from the liststore
|
||||||
self.config["hosts"] = []
|
self.config["hosts"] = []
|
||||||
for row in self.liststore:
|
for row in self.liststore:
|
||||||
self.config["hosts"].append((row[HOSTLIST_COL_ID], row[HOSTLIST_COL_HOST], row[HOSTLIST_COL_PORT], row[HOSTLIST_COL_USER], row[HOSTLIST_COL_PASS]))
|
self.config["hosts"].append((row[HOSTLIST_COL_ID],
|
||||||
|
row[HOSTLIST_COL_HOST],
|
||||||
|
row[HOSTLIST_COL_PORT],
|
||||||
|
row[HOSTLIST_COL_USER],
|
||||||
|
row[HOSTLIST_COL_PASS]))
|
||||||
|
|
||||||
self.config.save()
|
self.config.save()
|
||||||
|
|
||||||
|
@ -250,6 +256,7 @@ class ConnectionManager(component.Component):
|
||||||
self.liststore[new_row][HOSTLIST_COL_USER] = host[3]
|
self.liststore[new_row][HOSTLIST_COL_USER] = host[3]
|
||||||
self.liststore[new_row][HOSTLIST_COL_PASS] = host[4]
|
self.liststore[new_row][HOSTLIST_COL_PASS] = host[4]
|
||||||
self.liststore[new_row][HOSTLIST_COL_STATUS] = _("Offline")
|
self.liststore[new_row][HOSTLIST_COL_STATUS] = _("Offline")
|
||||||
|
self.liststore[new_row][HOSTLIST_COL_VERSION] = ""
|
||||||
|
|
||||||
def __get_host_row(self, host_id):
|
def __get_host_row(self, host_id):
|
||||||
"""
|
"""
|
||||||
|
@ -300,7 +307,7 @@ class ConnectionManager(component.Component):
|
||||||
row = self.__get_host_row(host_id)
|
row = self.__get_host_row(host_id)
|
||||||
if row:
|
if row:
|
||||||
row[HOSTLIST_COL_STATUS] = _("Offline")
|
row[HOSTLIST_COL_STATUS] = _("Offline")
|
||||||
# row[HOSTLIST_COL_VERSION] = ""
|
row[HOSTLIST_COL_VERSION] = ""
|
||||||
self.__update_buttons()
|
self.__update_buttons()
|
||||||
|
|
||||||
for row in self.liststore:
|
for row in self.liststore:
|
||||||
|
@ -312,21 +319,15 @@ class ConnectionManager(component.Component):
|
||||||
if client.connected() and \
|
if client.connected() and \
|
||||||
(host, port, "localclient" if not user and host in ("127.0.0.1", "localhost") else user) == client.connection_info():
|
(host, port, "localclient" if not user and host in ("127.0.0.1", "localhost") else user) == client.connection_info():
|
||||||
def on_info(info):
|
def on_info(info):
|
||||||
log.debug("\n\nClient connected, query info: %s:%s\n\n", info, self.running)
|
|
||||||
if not self.running:
|
if not self.running:
|
||||||
return
|
return
|
||||||
|
log.debug("Client connected, query info: %s", info)
|
||||||
row[HOSTLIST_COL_VERSION] = info
|
row[HOSTLIST_COL_VERSION] = info
|
||||||
self.__update_buttons()
|
self.__update_buttons()
|
||||||
print row[HOSTLIST_COL_ID], row[HOSTLIST_COL_HOST], row[HOSTLIST_COL_PORT], row[HOSTLIST_COL_USER], row[HOSTLIST_COL_VERSION]
|
|
||||||
|
|
||||||
def on_info_fail(reason):
|
|
||||||
print '\n\n'
|
|
||||||
log.exception(reason)
|
|
||||||
print '\n\n'
|
|
||||||
|
|
||||||
row[HOSTLIST_COL_STATUS] = _("Connected")
|
row[HOSTLIST_COL_STATUS] = _("Connected")
|
||||||
log.debug("\n\nquery daemons info\n\n")
|
log.debug("\n\nquery daemons info\n\n")
|
||||||
client.daemon.info().addCallback(on_info).addErrback(on_info_fail)
|
client.daemon.info().addCallback(on_info)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Create a new Client instance
|
# Create a new Client instance
|
||||||
|
@ -446,7 +447,8 @@ that you forgot to install the deluged package or it's not in your PATH.")).run(
|
||||||
# Signal handlers
|
# Signal handlers
|
||||||
def __connect(self, host_id, host, port, username, password):
|
def __connect(self, host_id, host, port, username, password):
|
||||||
def do_connect(*args):
|
def do_connect(*args):
|
||||||
d = client.connect(host, port, username, password)
|
d = client.connect(host, port, username, password,
|
||||||
|
skip_authentication=False)
|
||||||
d.addCallback(self.__on_connected, host_id)
|
d.addCallback(self.__on_connected, host_id)
|
||||||
d.addErrback(self.__on_connected_failed, host_id, host, port, username)
|
d.addErrback(self.__on_connected_failed, host_id, host, port, username)
|
||||||
return d
|
return d
|
||||||
|
@ -457,27 +459,19 @@ that you forgot to install the deluged package or it's not in your PATH.")).run(
|
||||||
return do_connect()
|
return do_connect()
|
||||||
|
|
||||||
def __on_connected(self, daemon_info, host_id):
|
def __on_connected(self, daemon_info, host_id):
|
||||||
# log.debug("__on_connected called for hostid: %s connector: %s",
|
|
||||||
# host_id, daemon_info)
|
|
||||||
if self.gtkui_config["autoconnect"]:
|
if self.gtkui_config["autoconnect"]:
|
||||||
self.gtkui_config["autoconnect_host_id"] = host_id
|
self.gtkui_config["autoconnect_host_id"] = host_id
|
||||||
|
|
||||||
# row = self.__get_host_row(host_id)
|
|
||||||
# row[HOSTLIST_COL_STATUS] = _("Connected")
|
|
||||||
# row[HOSTLIST_COL_VERSION] = daemon_info
|
|
||||||
#
|
|
||||||
# # Update the status of the hosts
|
|
||||||
# self.__update_list()
|
|
||||||
|
|
||||||
self.connection_manager.response(gtk.RESPONSE_OK)
|
self.connection_manager.response(gtk.RESPONSE_OK)
|
||||||
|
|
||||||
component.start()
|
component.start()
|
||||||
|
|
||||||
def __on_connected_failed(self, reason, host_id, host, port, user):
|
def __on_connected_failed(self, reason, host_id, host, port, user):
|
||||||
log.exception(reason)
|
log.exception(reason.value)
|
||||||
if reason.value.exception_type == "PasswordRequired":
|
# log.debug(reason.__dict__)
|
||||||
|
# log.debug(reason.value.__dict__)
|
||||||
|
if reason.check(AuthenticationRequired):
|
||||||
log.debug("PasswordRequired exception")
|
log.debug("PasswordRequired exception")
|
||||||
dialog = dialogs.AuthenticationDialog(reason.value.exception_msg)
|
dialog = dialogs.AuthenticationDialog(reason.value.message)
|
||||||
def dialog_finished(response_id, host, port, user):
|
def dialog_finished(response_id, host, port, user):
|
||||||
if response_id == gtk.RESPONSE_OK:
|
if response_id == gtk.RESPONSE_OK:
|
||||||
self.__connect(host_id, host, port, user,
|
self.__connect(host_id, host, port, user,
|
||||||
|
|
|
@ -197,7 +197,7 @@ class AuthenticationDialog(BaseDialog):
|
||||||
When run(), it will return either a gtk.RESPONSE_CANCEL or a
|
When run(), it will return either a gtk.RESPONSE_CANCEL or a
|
||||||
gtk.RESPONSE_OK.
|
gtk.RESPONSE_OK.
|
||||||
"""
|
"""
|
||||||
def __init__(self, err_msg="", parent=None):
|
def __init__(self, err_msg="", username=None, parent=None):
|
||||||
"""
|
"""
|
||||||
:param err_msg: the error message we got back from the server
|
:param err_msg: the error message we got back from the server
|
||||||
:type err_msg: string
|
:type err_msg: string
|
||||||
|
|
Loading…
Reference in New Issue