summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/bitmask/backend.py84
-rw-r--r--src/leap/bitmask/gui/advanced_key_management.py12
-rw-r--r--src/leap/bitmask/gui/mainwindow.py27
-rw-r--r--src/leap/bitmask/gui/preferenceswindow.py70
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)