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: 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):
""" """

View File

@ -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)

View File

@ -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

View File

@ -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):

View File

@ -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,

View File

@ -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