Module: deluge
Branch: chunked-sessionproxy-and-gtkui-speedups
Commit: 0ba0e013b54c033227fbc2329e0b01acf7846218

Author: Pedro Algarvio <pe...@algarvio.me>
Date:   Sun May 15 22:18:38 2011 +0100

Force backwards incompatibility.

Force clients prior to 1.4 to fail authentication, this was we might reduce 
tickets like #1852.

---

 deluge/core/rpcserver.py    |   10 +++++-
 deluge/error.py             |    3 ++
 deluge/tests/test_client.py |   76 +++++++++++++++++++++++++++++++++++++++++-
 deluge/ui/client.py         |    6 +--
 4 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/deluge/core/rpcserver.py b/deluge/core/rpcserver.py
index 274aeae..5536d28 100644
--- a/deluge/core/rpcserver.py
+++ b/deluge/core/rpcserver.py
@@ -56,7 +56,8 @@ 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, _PassthroughError
+from deluge.error import (DelugeError, NotAuthorizedError, _PassthroughError,
+                          IncompatibleClient)
 
 RPC_RESPONSE = 1
 RPC_ERROR = 2
@@ -261,6 +262,13 @@ class DelugeRPCProtocol(Protocol):
             # We need to authenticate the user here
             log.debug("RPC dispatch daemon.login")
             try:
+                client_version = kwargs.pop('client_version', None)
+                if client_version is None:
+                    raise IncompatibleClient(
+                        "Your deluge client is not compatible with the daemon. 
"
+                        "Please upgrade your client to %s" %
+                        deluge.common.get_version()
+                    )
                 ret = component.get("AuthManager").authorize(*args, **kwargs)
                 if ret:
                     self.factory.authorized_sessions[self.transport.sessionno] 
= (ret, args[0])
diff --git a/deluge/error.py b/deluge/error.py
index d9669ec..2e3c783 100644
--- a/deluge/error.py
+++ b/deluge/error.py
@@ -65,6 +65,9 @@ class _PassthroughError(DelugeError):
         inst._kwargs = kwargs
         return inst
 
+class IncompatibleClient(_PassthroughError):
+    pass
+
 class NotAuthorizedError(_PassthroughError):
 
     def __init__(self, current_level, required_level):
diff --git a/deluge/tests/test_client.py b/deluge/tests/test_client.py
index 82171ee..0e9bf5c 100644
--- a/deluge/tests/test_client.py
+++ b/deluge/tests/test_client.py
@@ -1,11 +1,65 @@
 
 import common
 
+from twisted.internet import defer
 from twisted.trial import unittest
 
 from deluge import error
-from deluge.core.authmanager import AUTH_LEVEL_ADMIN, AUTH_LEVEL_DEFAULT
-from deluge.ui.client import client
+from deluge.core.authmanager import AUTH_LEVEL_ADMIN
+from deluge.ui.client import client, Client, DaemonSSLProxy
+
+
+class NoVersionSendingDaemonSSLProxy(DaemonSSLProxy):
+    def authenticate(self, username, password):
+        self.login_deferred = defer.Deferred()
+        d = self.call("daemon.login", username, password)
+        d.addCallback(self.__on_login, username)
+        d.addErrback(self.__on_login_fail)
+        return self.login_deferred
+
+    def __on_login(self, result, username):
+        self.login_deferred.callback(result)
+
+    def __on_login_fail(self, result):
+        self.login_deferred.errback(result)
+
+class NoVersionSendingClient(Client):
+
+    def connect(self, host="127.0.0.1", port=58846, username="", password="",
+                skip_authentication=False):
+        self._daemon_proxy = NoVersionSendingDaemonSSLProxy()
+        self._daemon_proxy.set_disconnect_callback(self.__on_disconnect)
+
+        d = self._daemon_proxy.connect(host, port)
+
+        def on_connect_fail(reason):
+            self.disconnect()
+            return reason
+
+        def on_authenticate(result, daemon_info):
+            return result
+
+        def on_authenticate_fail(reason):
+            return reason
+
+        def on_connected(daemon_version):
+            return daemon_version
+
+        def authenticate(daemon_version, username, password):
+            d = self._daemon_proxy.authenticate(username, password)
+            d.addCallback(on_authenticate, daemon_version)
+            d.addErrback(on_authenticate_fail)
+            return d
+
+        d.addCallback(on_connected)
+        d.addErrback(on_connect_fail)
+        if not skip_authentication:
+            d.addCallback(authenticate, username, password)
+        return d
+
+    def __on_disconnect(self):
+        if self.disconnect_callback:
+            self.disconnect_callback()
 
 class ClientTestCase(unittest.TestCase):
 
@@ -78,3 +132,21 @@ class ClientTestCase(unittest.TestCase):
 
         d.addErrback(on_failure)
         return d
+
+    def test_connect_without_sending_client_version_fails(self):
+        from deluge.ui import common
+        username, password = common.get_localhost_auth()
+        no_version_sending_client = NoVersionSendingClient()
+        d = no_version_sending_client.connect(
+            "localhost", 58846, username=username, password=password
+        )
+
+        def on_failure(failure):
+            self.assertEqual(
+                failure.trap(error.IncompatibleClient),
+                error.IncompatibleClient
+            )
+            self.addCleanup(no_version_sending_client.disconnect)
+
+        d.addErrback(on_failure)
+        return d
diff --git a/deluge/ui/client.py b/deluge/ui/client.py
index e281a30..e2105f2 100644
--- a/deluge/ui/client.py
+++ b/deluge/ui/client.py
@@ -46,7 +46,6 @@ import zlib
 
 import deluge.common
 from deluge import error
-from deluge.log import LOG as log
 from deluge.event import known_events
 
 if deluge.common.windows_check():
@@ -299,8 +298,6 @@ class DaemonSSLProxy(DaemonProxy):
 
         :param host: str, the host to connect to
         :param port: int, the listening port on the daemon
-        :param username: str, the username to login as
-        :param password: str, the password to login with
 
         :returns: twisted.Deferred
 
@@ -451,7 +448,8 @@ class DaemonSSLProxy(DaemonProxy):
     def authenticate(self, username, password):
         log.debug("%s.authenticate: %s", self.__class__.__name__, username)
         self.login_deferred = defer.Deferred()
-        d = self.call("daemon.login", username, password)
+        d = self.call("daemon.login", username, password,
+                      client_version=deluge.common.get_version())
         d.addCallback(self.__on_login, username)
         d.addErrback(self.__on_login_fail)
         return self.login_deferred

-- 
You received this message because you are subscribed to the Google Groups 
"deluge-commit" group.
To post to this group, send email to deluge-commit@googlegroups.com.
To unsubscribe from this group, send email to 
deluge-commit+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/deluge-commit?hl=en.

Reply via email to