diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/bitmask/backend.py | 84 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/advanced_key_management.py | 12 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 27 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/preferenceswindow.py | 70 | 
4 files changed, 141 insertions, 52 deletions
| diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py index 6a6b1065..49a5ca0f 100644 --- a/src/leap/bitmask/backend.py +++ b/src/leap/bitmask/backend.py @@ -56,6 +56,8 @@ from leap.bitmask.services.soledad.soledadbootstrapper import \  from leap.common import certs as leap_certs +from leap.soledad.client import NoStorageSecret, PassphraseTooShort +  # Frontend side  from PySide import QtCore @@ -644,14 +646,52 @@ class Soledad(object):              logger.debug("Cancelling soledad defer.")              self._soledad_defer.cancel()              self._soledad_defer = None +            zope.proxy.setProxiedObject(self._soledad_proxy, None)      def close(self):          """          Close soledad database.          """ -        soledad = self._soledad_bootstrapper.soledad -        if soledad is not None: -            soledad.close() +        if not zope.proxy.sameProxiedObjects(self._soledad_proxy, None): +            self._soledad_proxy.close() +            zope.proxy.setProxiedObject(self._soledad_proxy, None) + +    def _change_password_ok(self, _): +        """ +        Password change callback. +        """ +        if self._signaler is not None: +            self._signaler.signal(self._signaler.SOLEDAD_PASSWORD_CHANGE_OK) + +    def _change_password_error(self, failure): +        """ +        Password change errback. + +        :param failure: failure object containing problem. +        :type failure: twisted.python.failure.Failure +        """ +        if failure.check(NoStorageSecret): +            logger.error("No storage secret for password change in Soledad.") +        if failure.check(PassphraseTooShort): +            logger.error("Passphrase too short.") + +        if self._signaler is not None: +            self._signaler.signal(self._signaler.SOLEDAD_PASSWORD_CHANGE_ERROR) + +    def change_password(self, new_password): +        """ +        Change the database's password. + +        :param new_password: the new password. +        :type new_password: unicode + +        :returns: a defer to interact with. +        :rtype: twisted.internet.defer.Deferred +        """ +        d = threads.deferToThread(self._soledad_proxy.change_passphrase, +                                  new_password) +        d.addCallback(self._change_password_ok) +        d.addErrback(self._change_password_error)  class Mail(object): @@ -691,6 +731,9 @@ class Mail(object):          :param download_if_needed: True if it should check for mtime                                     for the file          :type download_if_needed: bool + +        :returns: a defer to interact with. +        :rtype: twisted.internet.defer.Deferred          """          return threads.deferToThread(              self._smtp_bootstrapper.start_smtp_service, @@ -704,6 +747,9 @@ class Mail(object):          :type full_user_id: str          :param offline: whether imap should start in offline mode or not.          :type offline: bool + +        :returns: a defer to interact with. +        :rtype: twisted.internet.defer.Deferred          """          return threads.deferToThread(              self._imap_controller.start_imap_service, @@ -712,6 +758,9 @@ class Mail(object):      def stop_smtp_service(self):          """          Stop the SMTP service. + +        :returns: a defer to interact with. +        :rtype: twisted.internet.defer.Deferred          """          return threads.deferToThread(self._smtp_bootstrapper.stop_smtp_service) @@ -722,6 +771,9 @@ class Mail(object):          :param cv: A condition variable to which we can signal when imap                     indeed stops.          :type cv: threading.Condition + +        :returns: a defer to interact with. +        :rtype: twisted.internet.defer.Deferred          """          return threads.deferToThread(              self._imap_controller.stop_imap_service, cv) @@ -927,6 +979,8 @@ class Signaler(QtCore.QObject):      soledad_offline_finished = QtCore.Signal(object)      soledad_invalid_auth_token = QtCore.Signal(object)      soledad_cancelled_bootstrap = QtCore.Signal(object) +    soledad_password_change_ok = QtCore.Signal(object) +    soledad_password_change_error = QtCore.Signal(object)      # This signal is used to warn the backend user that is doing something      # wrong @@ -1003,6 +1057,9 @@ class Signaler(QtCore.QObject):      SOLEDAD_OFFLINE_FINISHED = "soledad_offline_finished"      SOLEDAD_INVALID_AUTH_TOKEN = "soledad_invalid_auth_token" +    SOLEDAD_PASSWORD_CHANGE_OK = "soledad_password_change_ok" +    SOLEDAD_PASSWORD_CHANGE_ERROR = "soledad_password_change_error" +      SOLEDAD_CANCELLED_BOOTSTRAP = "soledad_cancelled_bootstrap"      BACKEND_BAD_CALL = "backend_bad_call" @@ -1083,6 +1140,9 @@ class Signaler(QtCore.QObject):              self.SOLEDAD_INVALID_AUTH_TOKEN,              self.SOLEDAD_CANCELLED_BOOTSTRAP, +            self.SOLEDAD_PASSWORD_CHANGE_OK, +            self.SOLEDAD_PASSWORD_CHANGE_ERROR, +              self.BACKEND_BAD_CALL,          ] @@ -1470,7 +1530,7 @@ class Backend(object):          """          self._call_queue.put(("authenticate", "cancel_login", None)) -    def change_password(self, current_password, new_password): +    def auth_change_password(self, current_password, new_password):          """          Change the user's password. @@ -1488,6 +1548,22 @@ class Backend(object):          self._call_queue.put(("authenticate", "change_password", None,                                current_password, new_password)) +    def soledad_change_password(self, new_password): +        """ +        Change the database's password. + +        :param new_password: the new password for the user. +        :type new_password: unicode + +        Signals: +            srp_not_logged_in_error +            srp_password_change_ok +            srp_password_change_badpw +            srp_password_change_error +        """ +        self._call_queue.put(("soledad", "change_password", None, +                              new_password)) +      def get_logged_in_status(self):          """          Signal if the user is currently logged in or not. diff --git a/src/leap/bitmask/gui/advanced_key_management.py b/src/leap/bitmask/gui/advanced_key_management.py index be6b4410..1681caca 100644 --- a/src/leap/bitmask/gui/advanced_key_management.py +++ b/src/leap/bitmask/gui/advanced_key_management.py @@ -20,7 +20,6 @@ Advanced Key Management  import logging  from PySide import QtGui -from zope.proxy import sameProxiedObjects  from leap.keymanager import openpgp  from leap.keymanager.errors import KeyAddressMismatch, KeyFingerprintMismatch @@ -34,7 +33,7 @@ class AdvancedKeyManagement(QtGui.QDialog):      """      Advanced Key Management      """ -    def __init__(self, parent, has_mx, user, keymanager, soledad): +    def __init__(self, parent, has_mx, user, keymanager, soledad_started):          """          :param parent: parent object of AdvancedKeyManagement.          :parent type: QWidget @@ -45,8 +44,8 @@ class AdvancedKeyManagement(QtGui.QDialog):          :type user: unicode          :param keymanager: the existing keymanager instance          :type keymanager: KeyManager -        :param soledad: a loaded instance of Soledad -        :type soledad: Soledad +        :param soledad_started: whether soledad has started or not +        :type soledad_started: bool          """          QtGui.QDialog.__init__(self, parent) @@ -56,7 +55,6 @@ class AdvancedKeyManagement(QtGui.QDialog):          # XXX: Temporarily disable the key import.          self.ui.pbImportKeys.setVisible(False) -        # if Soledad is not started yet          if not has_mx:              msg = self.tr("The provider that you are using "                            "does not support {0}.") @@ -64,8 +62,7 @@ class AdvancedKeyManagement(QtGui.QDialog):              self._disable_ui(msg)              return -        # if Soledad is not started yet -        if sameProxiedObjects(soledad, None): +        if not soledad_started:              msg = self.tr("To use this, you need to enable/start {0}.")              msg = msg.format(get_service_display_name(MX_SERVICE))              self._disable_ui(msg) @@ -79,7 +76,6 @@ class AdvancedKeyManagement(QtGui.QDialog):          #     self.ui.lblStatus.setText(msg)          self._keymanager = keymanager -        self._soledad = soledad          self._key = keymanager.get_key(user, openpgp.OpenPGPKey)          self._key_priv = keymanager.get_key( diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index cd3e77c9..e1527bbe 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -189,6 +189,7 @@ class MainWindow(QtGui.QMainWindow):          self._provisional_provider_config = ProviderConfig()          self._already_started_eip = False +        self._soledad_started = False          # This is created once we have a valid provider config          self._srp_auth = None @@ -276,15 +277,9 @@ class MainWindow(QtGui.QMainWindow):          self._bypass_checks = bypass_checks          self._start_hidden = start_hidden -        # We initialize Soledad and Keymanager instances as -        # transparent proxies, so we can pass the reference freely -        # around. -        self._soledad = ProxyBase(None)          self._keymanager = ProxyBase(None)          self._mail_conductor = mail_conductor.MailConductor(self._backend) -        # self._mail_conductor = mail_conductor.MailConductor( -        #     self._soledad, self._keymanager)          self._mail_conductor.connect_mail_signals(self._mail_status)          # Eip machine is a public attribute where the state machine for @@ -603,8 +598,8 @@ class MainWindow(QtGui.QMainWindow):              provider_config = self._get_best_provider_config()              has_mx = provider_config.provides_mx() -        akm = AdvancedKeyManagement( -            self, has_mx, logged_user, self._keymanager, self._soledad) +        akm = AdvancedKeyManagement(self, has_mx, logged_user, +                                    self._keymanager, self._soledad_started)          akm.show()      @QtCore.Slot() @@ -619,8 +614,8 @@ class MainWindow(QtGui.QMainWindow):          user = self._login_widget.get_user()          prov = self._login_widget.get_selected_provider()          preferences = PreferencesWindow( -            self, self._backend, self._provider_config, self._soledad, -            user, prov) +            self, self._backend, self._provider_config, +            self._soledad_started, user, prov)          self.soledad_ready.connect(preferences.set_soledad_ready)          preferences.show() @@ -1265,6 +1260,9 @@ class MainWindow(QtGui.QMainWindow):          self._backend.cancel_setup_provider()          self._backend.cancel_login()          self._backend.cancel_soledad_bootstrap() +        self._backend.close_soledad() + +        self._soledad_started = False      @QtCore.Slot()      def _set_login_cancelled(self): @@ -1419,9 +1417,8 @@ class MainWindow(QtGui.QMainWindow):          """          logger.debug("Done bootstrapping Soledad") -        # Update the proxy objects to point to -        # the initialized instances. -        setProxiedObject(self._soledad, self._backend.get_soledad()) +        # Update the proxy objects to point to the initialized instances. +        # setProxiedObject(self._soledad, self._backend.get_soledad())          setProxiedObject(self._keymanager, self._backend.get_keymanager())          self._soledad_started = True @@ -1930,8 +1927,6 @@ class MainWindow(QtGui.QMainWindow):          Starts the logout sequence          """ -        setProxiedObject(self._soledad, None) -          self._cancel_ongoing_defers()          # XXX: If other defers are doing authenticated stuff, this @@ -2041,8 +2036,6 @@ class MainWindow(QtGui.QMainWindow):          if self._logged_user is not None:              self._backend.logout() -        self._backend.close_soledad() -          logger.debug('Terminating vpn')          self._backend.stop_eip(shutdown=True) diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index 2947c5db..77a3994f 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -23,12 +23,10 @@ import logging  from functools import partial  from PySide import QtCore, QtGui -from zope.proxy import sameProxiedObjects  from leap.bitmask.provider import get_provider_path  from leap.bitmask.config.leapsettings import LeapSettings  from leap.bitmask.gui.ui_preferences import Ui_Preferences -from leap.soledad.client import NoStorageSecret  from leap.bitmask.util.password import basic_password_checks  from leap.bitmask.services import get_supported  from leap.bitmask.config.providerconfig import ProviderConfig @@ -43,8 +41,8 @@ class PreferencesWindow(QtGui.QDialog):      """      preferences_saved = QtCore.Signal() -    def __init__(self, parent, backend, provider_config, -                 soledad, username, domain): +    def __init__(self, parent, backend, provider_config, soledad_started, +                 username, domain):          """          :param parent: parent object of the PreferencesWindow.          :parent type: QWidget @@ -52,8 +50,8 @@ class PreferencesWindow(QtGui.QDialog):          :type backend: Backend          :param provider_config: ProviderConfig object.          :type provider_config: ProviderConfig -        :param soledad: Soledad instance -        :type soledad: Soledad +        :param soledad_started: whether soledad has started or not +        :type soledad_started: bool          :param username: the user set in the login widget          :type username: unicode          :param domain: the selected domain in the login widget @@ -64,8 +62,8 @@ class PreferencesWindow(QtGui.QDialog):          self._backend = backend          self._settings = LeapSettings() -        self._soledad = soledad          self._provider_config = provider_config +        self._soledad_started = soledad_started          self._username = username          self._domain = domain @@ -118,7 +116,7 @@ class PreferencesWindow(QtGui.QDialog):                  pw_enabled = False              else:                  # check if Soledad is bootstrapped -                if sameProxiedObjects(self._soledad, None): +                if not self._soledad_started:                      msg = self.tr(                          "You need to wait until {0} is ready in "                          "order to change the password.".format(mx_name)) @@ -209,10 +207,10 @@ class PreferencesWindow(QtGui.QDialog):              return          self._set_changing_password(True) -        self._backend.change_password(current_password, new_password) +        self._backend.auth_change_password(current_password, new_password)      @QtCore.Slot() -    def _change_password_ok(self): +    def _srp_change_password_ok(self):          """          TRIGGERS:              self._backend.signaler.srp_password_change_ok @@ -221,12 +219,33 @@ class PreferencesWindow(QtGui.QDialog):          """          new_password = self.ui.leNewPassword.text()          logger.debug("SRP password changed successfully.") -        try: -            self._soledad.change_passphrase(new_password) -            logger.debug("Soledad password changed successfully.") -        except NoStorageSecret: -            logger.debug( -                "No storage secret for password change in Soledad.") +        self._backend.soledad_change_password(new_password) + +    @QtCore.Slot(unicode) +    def _srp_change_password_problem(self, msg): +        """ +        TRIGGERS: +            self._backend.signaler.srp_password_change_error +            self._backend.signaler.srp_password_change_badpw + +        Callback used to display an error on changing password. + +        :param msg: the message to show to the user. +        :type msg: unicode +        """ +        logger.error("Error changing password") +        self._set_password_change_status(msg, error=True) +        self._set_changing_password(False) + +    @QtCore.Slot() +    def _soledad_change_password_ok(self): +        """ +        TRIGGERS: +            Signaler.soledad_password_change_ok + +        Callback used to display a successfully changed password. +        """ +        logger.debug("Soledad password changed successfully.")          self._set_password_change_status(              self.tr("Password changed successfully."), success=True) @@ -234,18 +253,17 @@ class PreferencesWindow(QtGui.QDialog):          self._set_changing_password(False)      @QtCore.Slot(unicode) -    def _change_password_problem(self, msg): +    def _soledad_change_password_problem(self, msg):          """          TRIGGERS: -            self._backend.signaler.srp_password_change_error -            self._backend.signaler.srp_password_change_badpw +            Signaler.soledad_password_change_error          Callback used to display an error on changing password.          :param msg: the message to show to the user.          :type msg: unicode          """ -        logger.error("Error changing password") +        logger.error("Error changing soledad password")          self._set_password_change_status(msg, error=True)          self._set_changing_password(False) @@ -418,12 +436,18 @@ class PreferencesWindow(QtGui.QDialog):          sig.srp_status_logged_in.connect(self._is_logged_in)          sig.srp_status_not_logged_in.connect(self._not_logged_in) -        sig.srp_password_change_ok.connect(self._change_password_ok) +        sig.srp_password_change_ok.connect(self._srp_change_password_ok) -        pwd_change_error = lambda: self._change_password_problem( +        pwd_change_error = lambda: self._srp_change_password_problem(              self.tr("There was a problem changing the password."))          sig.srp_password_change_error.connect(pwd_change_error) -        pwd_change_badpw = lambda: self._change_password_problem( +        pwd_change_badpw = lambda: self._srp_change_password_problem(              self.tr("You did not enter a correct current password."))          sig.srp_password_change_badpw.connect(pwd_change_badpw) + +        sig.soledad_password_change_ok.connect( +            self._soledad_change_password_ok) + +        sig.soledad_password_change_error.connect( +            self._soledad_change_password_problem) | 
