diff --git a/deluge/common.py b/deluge/common.py index 7246cd3fe..ef9a5aad7 100644 --- a/deluge/common.py +++ b/deluge/common.py @@ -631,3 +631,43 @@ class VersionSplit(object): v1 = [self.version, self.suffix or 'z', self.dev] v2 = [ver.version, ver.suffix or 'z', ver.dev] return cmp(v1, v2) + + +# Common AUTH stuff +AUTH_LEVEL_NONE = 0 +AUTH_LEVEL_READONLY = 1 +AUTH_LEVEL_NORMAL = 5 +AUTH_LEVEL_ADMIN = 10 +AUTH_LEVEL_DEFAULT = AUTH_LEVEL_NORMAL + +def create_auth_file(): + import stat, configmanager + auth_file = configmanager.get_config_dir("auth") + # Check for auth file and create if necessary + if not os.path.exists(auth_file): + fd = open(auth_file, "w") + fd.flush() + os.fsync(fd.fileno()) + fd.close() + # Change the permissions on the file so only this user can read/write it + os.chmod(auth_file, stat.S_IREAD | stat.S_IWRITE) + +def create_localclient_account(): + import configmanager, random + auth_file = configmanager.get_config_dir("auth") + if not os.path.exists(auth_file): + create_auth_file() + + try: + from hashlib import sha1 as sha_hash + except ImportError: + from sha import new as sha_hash + fd = open(auth_file, "w") + fd.write(":".join([ + "localclient", + sha_hash(str(random.random())).hexdigest(), + str(AUTH_LEVEL_ADMIN) + ]) + '\n') + fd.flush() + os.fsync(fd.fileno()) + fd.close() diff --git a/deluge/core/authmanager.py b/deluge/core/authmanager.py index 3ec723b43..1f9528fcc 100644 --- a/deluge/core/authmanager.py +++ b/deluge/core/authmanager.py @@ -42,17 +42,14 @@ import logging import deluge.component as component import deluge.configmanager as configmanager +from deluge.common import (AUTH_LEVEL_ADMIN, AUTH_LEVEL_NONE, AUTH_LEVEL_NORMAL, + AUTH_LEVEL_READONLY, AUTH_LEVEL_DEFAULT, + create_auth_file, create_localclient_account) + from deluge.error import AuthManagerError, AuthenticationRequired, BadLoginError log = logging.getLogger(__name__) -AUTH_LEVEL_NONE = 0 -AUTH_LEVEL_READONLY = 1 -AUTH_LEVEL_NORMAL = 5 -AUTH_LEVEL_ADMIN = 10 - -AUTH_LEVEL_DEFAULT = AUTH_LEVEL_NORMAL - AUTH_LEVELS_MAPPING = { 'NONE': AUTH_LEVEL_NONE, 'READONLY': AUTH_LEVEL_READONLY, @@ -218,28 +215,13 @@ class AuthManager(component.Component): self.__load_auth_file() - def __create_localclient_account(self): - """ - Returns the string. - """ - # We create a 'localclient' account with a random password - try: - from hashlib import sha1 as sha_hash - except ImportError: - from sha import new as sha_hash - self.__auth["localclient"] = Account( - "localclient", - sha_hash(str(random.random())).hexdigest(), - AUTH_LEVEL_ADMIN - ) - def __load_auth_file(self): save_and_reload = False auth_file = configmanager.get_config_dir("auth") # Check for auth file and create if necessary if not os.path.exists(auth_file): - self.__create_auth_file() - self.__create_localclient_account() + create_auth_file() + create_localclient_account() self.write_auth_file() auth_file_modification_time = os.stat(auth_file).st_mtime @@ -295,7 +277,7 @@ class AuthManager(component.Component): self.__auth[username] = Account(username, password, authlevel) if "localclient" not in self.__auth: - self.__create_localclient_account() + create_localclient_account() self.write_auth_file() if save_and_reload: @@ -303,14 +285,3 @@ class AuthManager(component.Component): self.write_auth_file() self.__auth_modification_time = auth_file_modification_time - - def __create_auth_file(self): - auth_file = configmanager.get_config_dir("auth") - # Check for auth file and create if necessary - if not os.path.exists(auth_file): - fd = open(auth_file, "w") - fd.flush() - os.fsync(fd.fileno()) - fd.close() - # Change the permissions on the file so only this user can read/write it - os.chmod(auth_file, stat.S_IREAD | stat.S_IWRITE) diff --git a/deluge/core/daemon.py b/deluge/core/daemon.py index 383264dbd..0343febe5 100644 --- a/deluge/core/daemon.py +++ b/deluge/core/daemon.py @@ -54,7 +54,9 @@ class Daemon(object): if os.path.isfile(deluge.configmanager.get_config_dir("deluged.pid")): # Get the PID and the port of the supposedly running daemon try: - (pid, port) = open(deluge.configmanager.get_config_dir("deluged.pid")).read().strip().split(";") + (pid, port) = open( + deluge.configmanager.get_config_dir("deluged.pid") + ).read().strip().split(";") pid = int(pid) port = int(port) except ValueError: @@ -93,7 +95,10 @@ class Daemon(object): else: # This is a deluged! s.close() - raise deluge.error.DaemonRunningError("There is a deluge daemon running with this config directory!") + raise deluge.error.DaemonRunningError( + "There is a deluge daemon running with this config " + "directory!" + ) # Initialize gettext try: diff --git a/deluge/ui/client.py b/deluge/ui/client.py index e59df470d..a6b17b922 100644 --- a/deluge/ui/client.py +++ b/deluge/ui/client.py @@ -515,6 +515,7 @@ class DaemonClassicProxy(DaemonProxy): self.__daemon.core.eventmanager.register_event_handler(event, handler) def disconnect(self): + self.connected = False self.__daemon = None def call(self, method, *args, **kwargs): diff --git a/deluge/ui/common.py b/deluge/ui/common.py index fb9048d01..239bb84c9 100644 --- a/deluge/ui/common.py +++ b/deluge/ui/common.py @@ -407,26 +407,28 @@ def get_localhost_auth(): :rtype: tuple """ auth_file = deluge.configmanager.get_config_dir("auth") - if os.path.exists(auth_file): - for line in open(auth_file): - if line.startswith("#"): - # This is a comment line - continue - line = line.strip() - try: - lsplit = line.split(":") - except Exception, e: - log.error("Your auth file is malformed: %s", e) - continue + if not os.path.exists(auth_file): + from deluge.common import create_localclient_account + create_localclient_account() - if len(lsplit) == 2: - username, password = lsplit - elif len(lsplit) == 3: - username, password, level = lsplit - else: - log.error("Your auth file is malformed: Incorrect number of fields!") - continue + for line in open(auth_file): + if line.startswith("#"): + # This is a comment line + continue + line = line.strip() + try: + lsplit = line.split(":") + except Exception, e: + log.error("Your auth file is malformed: %s", e) + continue - if username == "localclient": - return (username, password) - return ("", "") + if len(lsplit) == 2: + username, password = lsplit + elif len(lsplit) == 3: + username, password, level = lsplit + else: + log.error("Your auth file is malformed: Incorrect number of fields!") + continue + + if username == "localclient": + return (username, password) diff --git a/deluge/ui/gtkui/connectionmanager.py b/deluge/ui/gtkui/connectionmanager.py index bbe7e42e8..e28c0b751 100644 --- a/deluge/ui/gtkui/connectionmanager.py +++ b/deluge/ui/gtkui/connectionmanager.py @@ -33,6 +33,7 @@ # # +import os import gtk import pkg_resources import time @@ -56,11 +57,6 @@ log = logging.getLogger(__name__) DEFAULT_HOST = "127.0.0.1" DEFAULT_PORT = 58846 -DEFAULT_CONFIG = { - "hosts": [(hashlib.sha1(str(time.time())).hexdigest(), DEFAULT_HOST, - DEFAULT_PORT, "localclient", "")] -} - HOSTLIST_COL_ID = 0 HOSTLIST_COL_HOST = 1 HOSTLIST_COL_PORT = 2 @@ -99,15 +95,11 @@ class ConnectionManager(component.Component): def __init__(self): component.Component.__init__(self, "ConnectionManager") self.gtkui_config = ConfigManager("gtkui.conf") - - self.config = ConfigManager("hostlist.conf.1.2", DEFAULT_CONFIG) - self.config.run_converter((0, 1), 2, self.__migrate_config_1_to_2) - self.running = False # Component overrides def start(self): - pass + self.config = self.__load_config() def stop(self): # Close this dialog when we are shutting down @@ -117,6 +109,26 @@ class ConnectionManager(component.Component): def shutdown(self): pass + def __load_config(self): + auth_file = deluge.configmanager.get_config_dir("auth") + if not os.path.exists(auth_file): + from deluge.common import create_localclient_account + create_localclient_account() + + localclient_username, localclient_password = get_localhost_auth() + DEFAULT_CONFIG = { + "hosts": [( + hashlib.sha1(str(time.time())).hexdigest(), + DEFAULT_HOST, + DEFAULT_PORT, + localclient_username, + localclient_password + )] + } + config = ConfigManager("hostlist.conf.1.2", DEFAULT_CONFIG) + config.run_converter((0, 1), 2, self.__migrate_config_1_to_2) + return config + # Public methods def show(self): """ diff --git a/deluge/ui/gtkui/preferences.py b/deluge/ui/gtkui/preferences.py index 83f681f76..d40e486ab 100644 --- a/deluge/ui/gtkui/preferences.py +++ b/deluge/ui/gtkui/preferences.py @@ -546,6 +546,8 @@ class Preferences(component.Component): except ImportError: from sha import new as sha_hash + classic_mode_was_set = self.gtkui_config["classic_mode"] + # Get the values from the dialog new_core_config = {} new_gtkui_config = {} @@ -666,8 +668,10 @@ class Preferences(component.Component): self.glade.get_widget("txt_tray_password").get_text()).hexdigest() if passhex != "c07eb5a8c0dc7bb81c217b67f11c3b7a5e95ffd7": new_gtkui_config["tray_password"] = passhex - new_gtkui_config["classic_mode"] = \ - self.glade.get_widget("chk_classic_mode").get_active() + + new_gtkui_in_classic_mode = self.glade.get_widget("chk_classic_mode").get_active() + new_gtkui_config["classic_mode"] = new_gtkui_in_classic_mode + new_gtkui_config["show_rate_in_title"] = \ self.glade.get_widget("chk_show_rate_in_title").get_active() @@ -763,6 +767,32 @@ class Preferences(component.Component): # Re-show the dialog to make sure everything has been updated self.show() + if classic_mode_was_set==True and new_gtkui_in_classic_mode==False: + def on_response(response): + if response == gtk.RESPONSE_NO: + # Set each changed config value in the core + self.gtkui_config["classic_mode"] = True + client.core.set_config({"classic_mode": True}) + client.force_call(True) + # Update the configuration + self.core_config.update({"classic_mode": True}) + self.glade.get_widget("chk_classic_mode").set_active(True) + else: + client.disconnect() + if client.is_classicmode(): + component.stop() + dialog = dialogs.YesNoDialog( + _("Attention"), + _("Your current session will be stopped. Continue?") + ) + dialog.run().addCallback(on_response) + elif classic_mode_was_set==False and new_gtkui_in_classic_mode==True: + dialog = dialogs.InformationDialog( + _("Attention"), + _("You must now restart the deluge UI") + ) + dialog.run() + def hide(self): self.glade.get_widget("port_img").hide() self.pref_dialog.hide()