summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/gui
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2014-01-11 23:10:09 -0400
committerKali Kaneko <kali@leap.se>2014-01-11 23:36:29 -0400
commita1db341a39ec336ab62e89280f9bfb315420bfb5 (patch)
treefecbf3cb3db336bec67bd86c5235e894b9b9bb68 /src/leap/bitmask/gui
parentcbdda58f1e5f74f37489f3b4b67616bd19d6715d (diff)
offline mode
This will skip: * srp authentication with server * remote soledad configuration * keymanager sending key to server * imap fetches. Its main goal is to help us while debugging imap accounts, by cutting almost all communication with server. It will break havoc if you use it without having local keys configured. So, basically, use with care.
Diffstat (limited to 'src/leap/bitmask/gui')
-rw-r--r--src/leap/bitmask/gui/login.py24
-rw-r--r--src/leap/bitmask/gui/mainwindow.py134
2 files changed, 123 insertions, 35 deletions
diff --git a/src/leap/bitmask/gui/login.py b/src/leap/bitmask/gui/login.py
index b21057f0..d0cb20b1 100644
--- a/src/leap/bitmask/gui/login.py
+++ b/src/leap/bitmask/gui/login.py
@@ -19,12 +19,13 @@ Login widget implementation
"""
import logging
-import keyring
-
from PySide import QtCore, QtGui
from ui_login import Ui_LoginWidget
+from leap.bitmask.config import flags
+from leap.bitmask.util import make_address
from leap.bitmask.util.keyring_helpers import has_keyring
+from leap.bitmask.util.keyring_helpers import get_keyring
from leap.common.check import leap_assert_type
logger = logging.getLogger(__name__)
@@ -304,14 +305,15 @@ class LoginWidget(QtGui.QWidget):
if self.get_remember() and has_keyring():
# in the keyring and in the settings
# we store the value 'usename@provider'
- username_domain = (username + '@' + provider).encode("utf8")
+ full_user_id = make_address(username, provider).encode("utf8")
try:
+ keyring = get_keyring()
keyring.set_password(self.KEYRING_KEY,
- username_domain,
+ full_user_id,
password.encode("utf8"))
# Only save the username if it was saved correctly in
# the keyring
- self._settings.set_user(username_domain)
+ self._settings.set_user(full_user_id)
except Exception as e:
logger.exception("Problem saving data to keyring. %r"
% (e,))
@@ -323,15 +325,20 @@ class LoginWidget(QtGui.QWidget):
"""
self.ui.login_widget.hide()
self.ui.logged_widget.show()
- self.ui.lblUser.setText("%s@%s" % (self.get_user(),
- self.get_selected_provider()))
+ self.ui.lblUser.setText(make_address(
+ self.get_user(), self.get_selected_provider()))
self.set_login_status("")
- self.logged_in_signal.emit()
+
+ if flags.OFFLINE is False:
+ self.logged_in_signal.emit()
def logged_out(self):
"""
Sets the widgets to the logged out state
"""
+ # TODO consider "logging out offline" too...
+ # how that would be ???
+
self.ui.login_widget.show()
self.ui.logged_widget.hide()
@@ -396,6 +403,7 @@ class LoginWidget(QtGui.QWidget):
saved_password = None
try:
+ keyring = get_keyring()
saved_password = keyring.get_password(self.KEYRING_KEY,
saved_user
.encode("utf8"))
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py
index 8c512ad2..18ef56e5 100644
--- a/src/leap/bitmask/gui/mainwindow.py
+++ b/src/leap/bitmask/gui/mainwindow.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# mainwindow.py
-# Copyright (C) 2013 LEAP
+# Copyright (C) 2013, 2014 LEAP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@ from zope.proxy import ProxyBase, setProxiedObject
from leap.bitmask import __version__ as VERSION
from leap.bitmask import __version_hash__ as VERSION_HASH
+from leap.bitmask.config import flags
from leap.bitmask.config.leapsettings import LeapSettings
from leap.bitmask.config.providerconfig import ProviderConfig
from leap.bitmask.crypto.srpauth import SRPAuth
@@ -68,6 +69,7 @@ from leap.bitmask.services.eip.darwinvpnlauncher import EIPNoTunKextLoaded
from leap.bitmask.services.soledad.soledadbootstrapper import \
SoledadBootstrapper
+from leap.bitmask.util import make_address
from leap.bitmask.util.keyring_helpers import has_keyring
from leap.bitmask.util.leap_log_handler import LeapLogHandler
@@ -95,6 +97,7 @@ class MainWindow(QtGui.QMainWindow):
# Signals
eip_needs_login = QtCore.Signal([])
+ offline_mode_bypass_login = QtCore.Signal([])
new_updates = QtCore.Signal(object)
raise_window = QtCore.Signal([])
soledad_ready = QtCore.Signal([])
@@ -137,12 +140,11 @@ class MainWindow(QtGui.QMainWindow):
# end register leap events ####################################
self._quit_callback = quit_callback
-
self._updates_content = ""
+ # setup UI
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
-
self._backend = backend.Backend(bypass_checks)
self._backend.start()
@@ -183,6 +185,9 @@ class MainWindow(QtGui.QMainWindow):
self._on_eip_connected)
self._eip_status.eip_connection_connected.connect(
self._maybe_run_soledad_setup_checks)
+ self.offline_mode_bypass_login.connect(
+ self._maybe_run_soledad_setup_checks)
+
self.eip_needs_login.connect(
self._eip_status.disable_eip_start)
self.eip_needs_login.connect(
@@ -204,6 +209,7 @@ class MainWindow(QtGui.QMainWindow):
# This is created once we have a valid provider config
self._srp_auth = None
self._logged_user = None
+ self._logged_in_offline = False
self._backend_connect()
@@ -239,6 +245,8 @@ class MainWindow(QtGui.QMainWindow):
self._soledad_intermediate_stage)
self._soledad_bootstrapper.gen_key.connect(
self._soledad_bootstrapped_stage)
+ self._soledad_bootstrapper.local_only_ready.connect(
+ self._soledad_bootstrapped_stage)
self._soledad_bootstrapper.soledad_timeout.connect(
self._retry_soledad_connection)
self._soledad_bootstrapper.soledad_failed.connect(
@@ -284,8 +292,9 @@ class MainWindow(QtGui.QMainWindow):
self._enabled_services = []
- self._center_window()
+ # last minute UI manipulations
+ self._center_window()
self.ui.lblNewUpdates.setVisible(False)
self.ui.btnMore.setVisible(False)
#########################################
@@ -294,6 +303,8 @@ class MainWindow(QtGui.QMainWindow):
self.ui.btnMore.resize(0, 0)
#########################################
self.ui.btnMore.clicked.connect(self._updates_details)
+ if flags.OFFLINE is True:
+ self._set_label_offline()
# Services signals/slots connection
self.new_updates.connect(self._react_to_new_updates)
@@ -706,6 +717,19 @@ class MainWindow(QtGui.QMainWindow):
self.ui.eipWidget.setVisible(EIP_SERVICE in services)
self.ui.mailWidget.setVisible(MX_SERVICE in services)
+ def _set_label_offline(self):
+ """
+ Set the login label to reflect offline status.
+ """
+ if self._logged_in_offline:
+ provider = ""
+ else:
+ provider = self.ui.lblLoginProvider.text()
+
+ self.ui.lblLoginProvider.setText(
+ provider +
+ self.tr(" (offline mode)"))
+
#
# systray
#
@@ -917,7 +941,6 @@ class MainWindow(QtGui.QMainWindow):
"""
# XXX should rename this provider, name clash.
provider = self._login_widget.get_selected_provider()
-
self._backend.setup_provider(provider)
def _load_provider_config(self, data):
@@ -930,7 +953,7 @@ class MainWindow(QtGui.QMainWindow):
part of the bootstrapping sequence
:param data: result from the last stage of the
- run_provider_select_checks
+ run_provider_select_checks
:type data: dict
"""
if data[self._backend.PASSED_KEY]:
@@ -959,10 +982,21 @@ class MainWindow(QtGui.QMainWindow):
start the SRP authentication, and as the last step
bootstrapping the EIP service
"""
- leap_assert(self._provider_config, "We need a provider config")
-
- if self._login_widget.start_login():
- self._download_provider_config()
+ # TODO most of this could ve handled by the login widget,
+ # but we'd have to move lblLoginProvider into the widget itself,
+ # instead of having it as a top-level attribute.
+ if flags.OFFLINE is True:
+ logger.debug("OFFLINE mode! bypassing remote login")
+ # TODO reminder, we're not handling logout for offline
+ # mode.
+ self._login_widget.logged_in()
+ self._logged_in_offline = True
+ self._set_label_offline()
+ self.offline_mode_bypass_login.emit()
+ else:
+ leap_assert(self._provider_config, "We need a provider config")
+ if self._login_widget.start_login():
+ self._download_provider_config()
def _cancel_login(self):
"""
@@ -1033,8 +1067,8 @@ class MainWindow(QtGui.QMainWindow):
self._logged_user = self._login_widget.get_user()
user = self._logged_user
domain = self._provider_config.get_domain()
- userid = "%s@%s" % (user, domain)
- self._mail_conductor.userid = userid
+ full_user_id = make_address(user, domain)
+ self._mail_conductor.userid = full_user_id
self._login_defer = None
self._start_eip_bootstrap()
else:
@@ -1047,7 +1081,8 @@ class MainWindow(QtGui.QMainWindow):
"""
self._login_widget.logged_in()
- self.ui.lblLoginProvider.setText(self._provider_config.get_domain())
+ provider = self._provider_config.get_domain()
+ self.ui.lblLoginProvider.setText(provider)
self._enabled_services = self._settings.get_enabled_services(
self._provider_config.get_domain())
@@ -1063,17 +1098,42 @@ class MainWindow(QtGui.QMainWindow):
def _maybe_run_soledad_setup_checks(self):
"""
+ Conditionally start Soledad.
"""
- # TODO soledad should check if we want to run only over EIP.
- if self._already_started_soledad is False \
- and self._logged_user is not None:
- self._already_started_soledad = True
- self._soledad_bootstrapper.run_soledad_setup_checks(
- self._provider_config,
- self._login_widget.get_user(),
- self._login_widget.get_password(),
- download_if_needed=True)
+ # TODO split.
+ if self._already_started_soledad is True:
+ return
+
+ username = self._login_widget.get_user()
+ password = unicode(self._login_widget.get_password())
+ provider_domain = self._login_widget.get_selected_provider()
+
+ sb = self._soledad_bootstrapper
+ if flags.OFFLINE is True:
+ provider_domain = self._login_widget.get_selected_provider()
+ sb._password = password
+
+ self._provisional_provider_config.load(
+ provider.get_provider_path(provider_domain))
+
+ full_user_id = make_address(username, provider_domain)
+ uuid = self._settings.get_uuid(full_user_id)
+ self._mail_conductor.userid = full_user_id
+
+ if uuid is None:
+ # We don't need more visibility at the moment,
+ # this is mostly for internal use/debug for now.
+ logger.warning("Sorry! Log-in at least one time.")
+ return
+ fun = sb.load_offline_soledad
+ fun(full_user_id, password, uuid)
+ else:
+ provider_config = self._provider_config
+ if self._logged_user is not None:
+ fun = sb.run_soledad_setup_checks
+ fun(provider_config, username, password,
+ download_if_needed=True)
###################################################################
# Service control methods: soledad
@@ -1119,6 +1179,7 @@ class MainWindow(QtGui.QMainWindow):
SLOT
TRIGGERS:
self._soledad_bootstrapper.gen_key
+ self._soledad_bootstrapper.local_only_ready
If there was a problem, displays it, otherwise it does nothing.
This is used for intermediate bootstrapping stages, in case
@@ -1160,6 +1221,10 @@ class MainWindow(QtGui.QMainWindow):
TRIGGERS:
self.soledad_ready
"""
+ if flags.OFFLINE is True:
+ logger.debug("not starting smtp in offline mode")
+ return
+
# TODO for simmetry, this should be called start_smtp_service
# (and delegate all the checks to the conductor)
if self._provider_config.provides_mx() and \
@@ -1191,9 +1256,24 @@ class MainWindow(QtGui.QMainWindow):
TRIGGERS:
self.soledad_ready
"""
+ # TODO in the OFFLINE mode we should also modify the rules
+ # in the mail state machine so it shows that imap is active
+ # (but not smtp since it's not yet ready for offline use)
+ start_fun = self._mail_conductor.start_imap_service
+ if flags.OFFLINE is True:
+ provider_domain = self._login_widget.get_selected_provider()
+ self._provider_config.load(
+ provider.get_provider_path(provider_domain))
+ provides_mx = self._provider_config.provides_mx()
+
+ if flags.OFFLINE is True and provides_mx:
+ start_fun()
+ return
+
+ enabled_services = self._enabled_services
if self._provider_config.provides_mx() and \
- self._enabled_services.count(MX_SERVICE) > 0:
- self._mail_conductor.start_imap_service()
+ enabled_services.count(MX_SERVICE) > 0:
+ start_fun()
def _on_mail_client_logged_in(self, req):
"""
@@ -1423,8 +1503,9 @@ class MainWindow(QtGui.QMainWindow):
if self._logged_user:
self._eip_status.set_provider(
- "%s@%s" % (self._logged_user,
- self._get_best_provider_config().get_domain()))
+ make_address(
+ self._logged_user,
+ self._get_best_provider_config().get_domain()))
self._eip_status.eip_stopped()
@QtCore.Slot()
@@ -1643,7 +1724,6 @@ class MainWindow(QtGui.QMainWindow):
Starts the logout sequence
"""
-
self._soledad_bootstrapper.cancel_bootstrap()
setProxiedObject(self._soledad, None)