Use a specific response code for authentication requests. Recreate authentication request exceptions on the client end.

This commit is contained in:
Pedro Algarvio 2010-12-21 02:58:06 +00:00
parent 67ff83360f
commit b3870ad6dd
6 changed files with 59 additions and 39 deletions

View File

@ -191,17 +191,6 @@ class Daemon(object):
except twisted.internet.error.ReactorNotRunning:
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()
def get_method_list(self):
"""

View File

@ -56,11 +56,12 @@ except ImportError:
import deluge.component as component
import deluge.configmanager
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_ERROR = 2
RPC_EVENT = 3
RPC_EVENT_AUTH = 4
log = logging.getLogger(__name__)
@ -261,6 +262,8 @@ class DelugeRPCProtocol(Protocol):
if ret:
self.factory.authorized_sessions[self.transport.sessionno] = (ret, args[0])
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:
sendError()
log.exception(e)

View File

@ -56,6 +56,23 @@ class BadLoginError(DelugeError):
pass
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):
super(AuthenticationRequired, self).__init__(message)
self.message = message
self.username = username

View File

@ -46,6 +46,8 @@ import zlib
import deluge.common
import deluge.component as component
from deluge.log import LOG as log
from deluge.error import AuthenticationRequired
from deluge.event import known_events
if deluge.common.windows_check():
import win32api
@ -55,6 +57,7 @@ else:
RPC_RESPONSE = 1
RPC_ERROR = 2
RPC_EVENT = 3
RPC_EVENT_AUTH = 4
log = logging.getLogger(__name__)
@ -184,6 +187,8 @@ class DelugeRPCProtocol(Protocol):
if message_type == RPC_RESPONSE:
# Run the callbacks registered with this Deferred object
d.callback(request[2])
elif message_type == RPC_EVENT_AUTH:
d.errback(AuthenticationRequired(request[2], request[3]))
elif message_type == RPC_ERROR:
# Create the DelugeRPCError to pass to the errback
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
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
error = error_data.value
# if error.exception_type == "AuthenticationRequired":
# return
# Create a delugerpcrequest to print out a nice RPCRequest string
r = DelugeRPCRequest()
r.method = error.method
@ -545,7 +561,8 @@ class Client(object):
self.disconnect_callback = None
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.
@ -573,7 +590,7 @@ class Client(object):
return result
d.addErrback(on_connect_fail)
if username or password:
if not skip_authentication:
auth_deferred = defer.Deferred()
def on_authenticate(result, daemon_info):

View File

@ -48,6 +48,8 @@ from deluge.ui.client import client
import deluge.ui.client
import deluge.ui.common
from deluge.configmanager import ConfigManager
from deluge.error import AuthenticationRequired
from deluge.log import LOG as log
import dialogs
log = logging.getLogger(__name__)
@ -234,7 +236,11 @@ class ConnectionManager(component.Component):
# Grab the hosts from the liststore
self.config["hosts"] = []
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()
@ -250,6 +256,7 @@ class ConnectionManager(component.Component):
self.liststore[new_row][HOSTLIST_COL_USER] = host[3]
self.liststore[new_row][HOSTLIST_COL_PASS] = host[4]
self.liststore[new_row][HOSTLIST_COL_STATUS] = _("Offline")
self.liststore[new_row][HOSTLIST_COL_VERSION] = ""
def __get_host_row(self, host_id):
"""
@ -300,7 +307,7 @@ class ConnectionManager(component.Component):
row = self.__get_host_row(host_id)
if row:
row[HOSTLIST_COL_STATUS] = _("Offline")
# row[HOSTLIST_COL_VERSION] = ""
row[HOSTLIST_COL_VERSION] = ""
self.__update_buttons()
for row in self.liststore:
@ -312,21 +319,15 @@ class ConnectionManager(component.Component):
if client.connected() and \
(host, port, "localclient" if not user and host in ("127.0.0.1", "localhost") else user) == client.connection_info():
def on_info(info):
log.debug("\n\nClient connected, query info: %s:%s\n\n", info, self.running)
if not self.running:
return
log.debug("Client connected, query info: %s", info)
row[HOSTLIST_COL_VERSION] = info
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")
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
# 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
def __connect(self, host_id, host, port, username, password):
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.addErrback(self.__on_connected_failed, host_id, host, port, username)
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()
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"]:
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)
component.start()
def __on_connected_failed(self, reason, host_id, host, port, user):
log.exception(reason)
if reason.value.exception_type == "PasswordRequired":
log.exception(reason.value)
# log.debug(reason.__dict__)
# log.debug(reason.value.__dict__)
if reason.check(AuthenticationRequired):
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):
if response_id == gtk.RESPONSE_OK:
self.__connect(host_id, host, port, user,

View File

@ -197,7 +197,7 @@ class AuthenticationDialog(BaseDialog):
When run(), it will return either a gtk.RESPONSE_CANCEL or a
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
:type err_msg: string