summaryrefslogtreecommitdiff
path: root/src/leap/gui
diff options
context:
space:
mode:
authorTomás Touceda <chiiph@leap.se>2013-03-07 19:05:11 -0300
committerTomás Touceda <chiiph@leap.se>2013-03-07 19:05:11 -0300
commit751638b4eb8208e1eaa1beaaed284da6b412bca7 (patch)
tree58a517d1f22a45a581fcca3ff2766663974de3fa /src/leap/gui
parent6d6600a495ef48e0f04cb78bedca8fb913bada2a (diff)
Change asserts for a custom leap_assert method
Also: - Make SRPAuth and the Bootstrappers be a QObject instead of a QThread so we can use them inside another more generic thread - Add a generic CheckerThread that runs checks or whatever operation as long as it returns a boolean value - Closes the whole application if the wizard is rejected at the first run - Do not fail when the config directory doesn't exist - Set the wizard pixmap logo as LEAP's logo - Improve wizard checks - Make SRPRegister play nice with the CheckerThread
Diffstat (limited to 'src/leap/gui')
-rw-r--r--src/leap/gui/mainwindow.py91
-rw-r--r--src/leap/gui/ui/wizard.ui5
-rw-r--r--src/leap/gui/wizard.py91
3 files changed, 115 insertions, 72 deletions
diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py
index 1821e4a6..50a03fb9 100644
--- a/src/leap/gui/mainwindow.py
+++ b/src/leap/gui/mainwindow.py
@@ -31,6 +31,8 @@ from leap.services.eip.providerbootstrapper import ProviderBootstrapper
from leap.services.eip.eipbootstrapper import EIPBootstrapper
from leap.services.eip.eipconfig import EIPConfig
from leap.gui.wizard import Wizard
+from leap.util.check import leap_assert
+from leap.util.checkerthread import CheckerThread
logger = logging.getLogger(__name__)
@@ -44,6 +46,9 @@ class MainWindow(QtGui.QMainWindow):
LOGIN_INDEX = 0
EIP_STATUS_INDEX = 1
+ GEOMETRY_KEY = "Geometry"
+ WINDOWSTATE_KEY = "WindowState"
+
def __init__(self):
QtGui.QMainWindow.__init__(self)
@@ -69,6 +74,9 @@ class MainWindow(QtGui.QMainWindow):
# This is created once we have a valid provider config
self._srp_auth = None
+ self._checker_thread = CheckerThread()
+ self._checker_thread.start()
+
# This thread is always running, although it's quite
# lightweight when it's done setting up provider
# configuration and certificate.
@@ -110,11 +118,7 @@ class MainWindow(QtGui.QMainWindow):
QtCore.QCoreApplication.instance().connect(
QtCore.QCoreApplication.instance(),
QtCore.SIGNAL("aboutToQuit()"),
- self._provider_bootstrapper.set_should_quit)
- QtCore.QCoreApplication.instance().connect(
- QtCore.QCoreApplication.instance(),
- QtCore.SIGNAL("aboutToQuit()"),
- self._eip_bootstrapper.set_should_quit)
+ self._checker_thread.set_should_quit)
self.ui.action_sign_out.setEnabled(False)
self.ui.action_sign_out.triggered.connect(self._logout)
@@ -131,17 +135,26 @@ class MainWindow(QtGui.QMainWindow):
self._center_window()
self._wizard = None
+ self._wizard_firstrun = False
if self._first_run():
- self._wizard = Wizard()
+ self._wizard_firstrun = True
+ self._wizard = Wizard(self._checker_thread)
# Give this window time to finish init and then show the wizard
QtCore.QTimer.singleShot(1, self._launch_wizard)
- self._wizard.finished.connect(self._finish_init)
+ self._wizard.accepted.connect(self._finish_init)
+ self._wizard.rejected.connect(self._rejected_wizard)
+ else:
+ self._finish_init()
+
+ def _rejected_wizard(self):
+ if self._wizard_firstrun:
+ self.quit()
else:
self._finish_init()
def _launch_wizard(self):
if self._wizard is None:
- self._wizard = Wizard()
+ self._wizard = Wizard(self._checker_thread)
self._wizard.exec_()
def _finish_init(self):
@@ -187,14 +200,23 @@ class MainWindow(QtGui.QMainWindow):
"""
Centers the mainwindow based on the desktop geometry
"""
- app = QtGui.QApplication.instance()
- width = app.desktop().width()
- height = app.desktop().height()
- window_width = self.size().width()
- window_height = self.size().height()
- x = (width / 2.0) - (window_width / 2.0)
- y = (height / 2.0) - (window_height / 2.0)
- self.move(x, y)
+ settings = QtCore.QSettings()
+ geometry = settings.value(self.GEOMETRY_KEY, None)
+ state = settings.value(self.WINDOWSTATE_KEY, None)
+ if geometry is None:
+ app = QtGui.QApplication.instance()
+ width = app.desktop().width()
+ height = app.desktop().height()
+ window_width = self.size().width()
+ window_height = self.size().height()
+ x = (width / 2.0) - (window_width / 2.0)
+ y = (height / 2.0) - (window_height / 2.0)
+ self.move(x, y)
+ else:
+ self.restoreGeometry(geometry)
+
+ if state is not None:
+ self.restoreState(state)
def _about(self):
"""
@@ -236,6 +258,9 @@ class MainWindow(QtGui.QMainWindow):
self._toggle_visible()
e.ignore()
return
+ settings = QtCore.QSettings()
+ settings.setValue(self.GEOMETRY_KEY, self.saveGeometry())
+ settings.setValue(self.WINDOWSTATE_KEY, self.saveState())
QtGui.QMainWindow.closeEvent(self, e)
def _configured_providers(self):
@@ -244,10 +269,16 @@ class MainWindow(QtGui.QMainWindow):
@rtype: list
"""
- providers = os.listdir(
- os.path.join(self._provider_config.get_path_prefix(),
- "leap",
- "providers"))
+ providers = []
+ try:
+ providers = os.listdir(
+ os.path.join(self._provider_config.get_path_prefix(),
+ "leap",
+ "providers"))
+ except Exception as e:
+ logger.debug("Error listing providers, assume there are none. %r"
+ % (e,))
+
return providers
def _first_run(self):
@@ -303,8 +334,8 @@ class MainWindow(QtGui.QMainWindow):
"""
provider = self.ui.cmbProviders.currentText()
- self._provider_bootstrapper.start()
self._provider_bootstrapper.run_provider_select_checks(
+ self._checker_thread,
provider,
download_if_needed=True)
@@ -329,6 +360,7 @@ class MainWindow(QtGui.QMainWindow):
provider,
"provider.json")):
self._provider_bootstrapper.run_provider_setup_checks(
+ self._checker_thread,
self._provider_config,
download_if_needed=True)
else:
@@ -350,7 +382,7 @@ class MainWindow(QtGui.QMainWindow):
start the SRP authentication, and as the last step
bootstrapping the EIP service
"""
- assert self._provider_config, "We need a provider config"
+ leap_assert(self._provider_config, "We need a provider config")
username = self.ui.lnUser.text()
password = self.ui.lnPassword.text()
@@ -381,9 +413,7 @@ class MainWindow(QtGui.QMainWindow):
Once the provider configuration is loaded, this starts the SRP
authentication
"""
- assert self._provider_config, "We need a provider config!"
-
- self._provider_bootstrapper.set_should_quit()
+ leap_assert(self._provider_config, "We need a provider config!")
if data[self._provider_bootstrapper.PASSED_KEY]:
username = self.ui.lnUser.text()
@@ -431,14 +461,14 @@ class MainWindow(QtGui.QMainWindow):
"""
Starts the EIP bootstrapping sequence
"""
- assert self._eip_bootstrapper, "We need an eip bootstrapper!"
- assert self._provider_config, "We need a provider config"
+ leap_assert(self._eip_bootstrapper, "We need an eip bootstrapper!")
+ leap_assert(self._provider_config, "We need a provider config")
self._set_eip_status("Checking configuration, please wait...")
if self._provider_config.provides_eip():
- self._eip_bootstrapper.start()
self._eip_bootstrapper.run_eip_setup_checks(
+ self._checker_thread,
self._provider_config,
download_if_needed=True)
else:
@@ -503,10 +533,9 @@ class MainWindow(QtGui.QMainWindow):
Starts the VPN thread if the eip configuration is properly
loaded
"""
- assert self._eip_config, "We need an eip config!"
- assert self._provider_config, "We need a provider config!"
+ leap_assert(self._eip_config, "We need an eip config!")
+ leap_assert(self._provider_config, "We need a provider config!")
- self._eip_bootstrapper.set_should_quit()
if self._eip_config.loaded() or \
self._eip_config.load(os.path.join("leap",
"providers",
diff --git a/src/leap/gui/ui/wizard.ui b/src/leap/gui/ui/wizard.ui
index 86f8d458..2d9cb441 100644
--- a/src/leap/gui/ui/wizard.ui
+++ b/src/leap/gui/ui/wizard.ui
@@ -47,7 +47,7 @@
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;New we will guide you through some configuration that is needed before you can connect for the first time.&lt;/p&gt;&lt;p&gt;If you ever need to modify these options again, you can find the wizard in the &lt;span style=&quot; font-style:italic;&quot;&gt;'Settings'&lt;/span&gt; menu from the main window.&lt;/p&gt;&lt;p&gt;Do you want to &lt;span style=&quot; font-weight:600;&quot;&gt;sign up&lt;/span&gt; for a new account, or &lt;span style=&quot; font-weight:600;&quot;&gt;log in&lt;/span&gt; with an already existing username?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Now we will guide you through some configuration that is needed before you can connect for the first time.&lt;/p&gt;&lt;p&gt;If you ever need to modify these options again, you can find the wizard in the &lt;span style=&quot; font-style:italic;&quot;&gt;'Settings'&lt;/span&gt; menu from the main window.&lt;/p&gt;&lt;p&gt;Do you want to &lt;span style=&quot; font-weight:600;&quot;&gt;sign up&lt;/span&gt; for a new account, or &lt;span style=&quot; font-weight:600;&quot;&gt;log in&lt;/span&gt; with an already existing username?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
@@ -497,6 +497,9 @@
<property name="text">
<string/>
</property>
+ <property name="textFormat">
+ <enum>Qt::AutoText</enum>
+ </property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
diff --git a/src/leap/gui/wizard.py b/src/leap/gui/wizard.py
index 7dcc8dd6..bac74d1d 100644
--- a/src/leap/gui/wizard.py
+++ b/src/leap/gui/wizard.py
@@ -21,7 +21,8 @@ First run wizard
import os
import logging
-from PySide import QtCore, QtGui
+from PySide import QtGui
+from functools import partial
from ui_wizard import Ui_Wizard
from leap.config.providerconfig import ProviderConfig
@@ -45,15 +46,18 @@ class Wizard(QtGui.QWizard):
SETUP_EIP_PAGE = 5
FINISH_PATH = 6
- WEAK_PASSWORDS = ("1234", "12345", "123456",
+ WEAK_PASSWORDS = ("123456", "qweasd", "qwerty",
"password")
- def __init__(self):
+ def __init__(self, checker):
QtGui.QWizard.__init__(self)
self.ui = Ui_Wizard()
self.ui.setupUi(self)
+ self.setPixmap(QtGui.QWizard.LogoPixmap,
+ QtGui.QPixmap(":/images/leap-color-small.png"))
+
self.QUESTION_ICON = QtGui.QPixmap(":/images/Emblem-question.png")
self.ERROR_ICON = QtGui.QPixmap(":/images/Dialog-error.png")
self.OK_ICON = QtGui.QPixmap(":/images/Dialog-accept.png")
@@ -94,6 +98,9 @@ class Wizard(QtGui.QWizard):
self.ui.lblPassword.setEchoMode(QtGui.QLineEdit.Password)
self.ui.lblPassword2.setEchoMode(QtGui.QLineEdit.Password)
+ self.ui.lnProvider.textChanged.connect(
+ self._enable_check)
+
self.ui.lblUser.returnPressed.connect(
self._focus_password)
self.ui.lblPassword.returnPressed.connect(
@@ -105,15 +112,14 @@ class Wizard(QtGui.QWizard):
self._username = None
- def __del__(self):
- self._provider_bootstrapper.set_should_quit()
- self._eip_bootstrapper.set_should_quit()
- self._provider_bootstrapper.wait()
- self._eip_bootstrapper.wait()
+ self._checker_thread = checker
def get_username(self):
return self._username
+ def _enable_check(self, text):
+ self.ui.btnCheck.setEnabled(len(self.ui.lnProvider.text()) != 0)
+
def _focus_password(self):
"""
Focuses at the password lineedit for the registration page
@@ -151,13 +157,13 @@ class Wizard(QtGui.QWizard):
if message is not None and password != password2:
message = "Passwords don't match"
- if message is not None and len(password) < 4:
+ if message is None and len(password) < 6:
message = "Password too short"
- if message is not None and password in self.WEAK_PASSWORDS:
+ if message is None and password in self.WEAK_PASSWORDS:
message = "Password too easy"
- if message is not None and username == password:
+ if message is None and username == password:
message = "Password equal to username"
if message is not None:
@@ -172,10 +178,6 @@ class Wizard(QtGui.QWizard):
Performs the registration based on the values provided in the form
"""
self.ui.btnRegister.setEnabled(False)
- # See the disabled button
- while QtGui.QApplication.instance().hasPendingEvents():
- QtGui.QApplication.instance().processEvents()
- self.button(QtGui.QWizard.NextButton).setFocus()
username = self.ui.lblUser.text()
password = self.ui.lblPassword.text()
@@ -183,27 +185,32 @@ class Wizard(QtGui.QWizard):
if self._basic_password_checks(username, password, password2):
register = SRPRegister(provider_config=self._provider_config)
- ok, req = register.register_user(username, password)
- if ok:
- self._set_register_status("<b>User registration OK</b>")
- self._username = username
- self.ui.lblPassword2.clearFocus()
- # Detach this call to allow UI updates briefly
- QtCore.QTimer.singleShot(1,
- self.page(self.REGISTER_USER_PAGE)
- .set_completed)
- else:
- print req.content
- error_msg = "Unknown error"
- try:
- error_msg = req.json().get("errors").get("login")[0]
- except:
- logger.error("Unknown error: %r" % (req.content,))
- self._set_register_status(error_msg)
- self.ui.btnRegister.setEnabled(True)
+ register.registration_finished.connect(
+ self._registration_finished)
+ self._checker_thread.add_checks(
+ [partial(register.register_user, username, password)])
+ self._username = username
+ self._set_register_status("Starting registration...")
else:
self.ui.btnRegister.setEnabled(True)
+ def _registration_finished(self, ok, req):
+ if ok:
+ self._set_register_status("<font color='green'>"
+ "<b>User registration OK</b></font>")
+ self.ui.lblPassword2.clearFocus()
+ self.page(self.REGISTER_USER_PAGE).set_completed()
+ self.button(QtGui.QWizard.BackButton).setEnabled(False)
+ else:
+ self._username = None
+ error_msg = "Unknown error"
+ try:
+ error_msg = req.json().get("errors").get("login")[0]
+ except:
+ logger.error("Unknown error: %r" % (req.content,))
+ self._set_register_status(error_msg)
+ self.ui.btnRegister.setEnabled(True)
+
def _set_register_status(self, status):
"""
Sets the status label in the registration page to status
@@ -222,12 +229,16 @@ class Wizard(QtGui.QWizard):
Starts the checks for a given provider
"""
+ if len(self.ui.lnProvider.text()) == 0:
+ return
+
self.ui.grpCheckProvider.setVisible(True)
self.ui.btnCheck.setEnabled(False)
self._domain = self.ui.lnProvider.text()
- self._provider_bootstrapper.start()
- self._provider_bootstrapper.run_provider_select_checks(self._domain)
+ self._provider_bootstrapper.run_provider_select_checks(
+ self._checker_thread,
+ self._domain)
def _complete_task(self, data, label, complete=False, complete_page=-1):
"""
@@ -328,7 +339,6 @@ class Wizard(QtGui.QWizard):
"""
self._complete_task(data, self.ui.lblCheckApiCert,
True, self.SETUP_PROVIDER_PAGE)
- self._provider_bootstrapper.set_should_quit()
def _download_eip_config(self, data):
"""
@@ -351,7 +361,6 @@ class Wizard(QtGui.QWizard):
"""
self._complete_task(data, self.ui.lblDownloadClientCert,
True, self.SETUP_EIP_PAGE)
- self._eip_bootstrapper.set_should_quit()
def _current_id_changed(self, pageId):
"""
@@ -365,14 +374,16 @@ class Wizard(QtGui.QWizard):
self.ui.lblNameResolution.setPixmap(self.QUESTION_ICON)
self.ui.lblHTTPS.setPixmap(self.QUESTION_ICON)
self.ui.lblProviderInfo.setPixmap(self.QUESTION_ICON)
+ self._enable_check("")
if pageId == self.SETUP_PROVIDER_PAGE:
self._provider_bootstrapper.\
- run_provider_setup_checks(self._provider_config)
+ run_provider_setup_checks(self._checker_thread,
+ self._provider_config)
if pageId == self.SETUP_EIP_PAGE:
- self._eip_bootstrapper.start()
- self._eip_bootstrapper.run_eip_setup_checks(self._provider_config)
+ self._eip_bootstrapper.run_eip_setup_checks(self._checker_thread,
+ self._provider_config)
if pageId == self.PRESENT_PROVIDER_PAGE:
# TODO: get the right lang for these