summaryrefslogtreecommitdiff
path: root/src/leap/gui/firstrun
diff options
context:
space:
mode:
authorkali <kali@leap.se>2012-11-27 00:12:22 +0900
committerkali <kali@leap.se>2012-11-27 00:43:01 +0900
commitd5136a5f3b2aa8b16e8341f2eb99d05993028acf (patch)
tree7ef847e02cb9d60fb38761d0001f41968ea5a23f /src/leap/gui/firstrun
parent7a263b8ee74cc92ba39796cd9ad48395adfa7450 (diff)
inline validation at register page.
inline widget and focus and red marks and whistles.
Diffstat (limited to 'src/leap/gui/firstrun')
-rw-r--r--src/leap/gui/firstrun/providerselect.py58
-rw-r--r--src/leap/gui/firstrun/providersetup.py23
-rw-r--r--src/leap/gui/firstrun/register.py179
-rw-r--r--src/leap/gui/firstrun/regvalidation.py80
-rwxr-xr-xsrc/leap/gui/firstrun/wizard.py2
5 files changed, 194 insertions, 148 deletions
diff --git a/src/leap/gui/firstrun/providerselect.py b/src/leap/gui/firstrun/providerselect.py
index dffde040..e59a23a9 100644
--- a/src/leap/gui/firstrun/providerselect.py
+++ b/src/leap/gui/firstrun/providerselect.py
@@ -169,7 +169,7 @@ class SelectProviderPage(InlineValidationPage):
@QtCore.pyqtSlot()
def onDisableCheckButton(self):
- print 'CHECK BUTTON DISABLED!!!'
+ #print 'CHECK BUTTON DISABLED!!!'
self.providerCheckButton.setDisabled(True)
@QtCore.pyqtSlot()
@@ -183,6 +183,8 @@ class SelectProviderPage(InlineValidationPage):
QtCore.QMetaObject.invokeMethod(
self, "showStepsFrame")
+ # is this still needed?
+ # XXX can I doo delay(self, "do_checks") ?
delay(self, "launch_checks")
def _do_checks(self):
@@ -192,8 +194,6 @@ class SelectProviderPage(InlineValidationPage):
"""
wizard = self.wizard()
- curpage = "providerselection"
-
full_domain = self.providerNameEdit.text()
# we check if we have a port in the domain string.
@@ -205,10 +205,6 @@ class SelectProviderPage(InlineValidationPage):
providercertchecker = wizard.providercertchecker()
eipconfigchecker = wizard.eipconfigchecker(domain=_domain)
- def fail():
- self.is_done = False
- return False
-
yield(("head_sentinel", 0), lambda: None)
########################
@@ -227,20 +223,16 @@ class SelectProviderPage(InlineValidationPage):
except baseexceptions.LeapException as exc:
logger.error(exc.message)
- wizard.set_validation_error(
- curpage, exc.usermessage)
- return fail()
+ return self.fail(exc.usermessage)
except Exception as exc:
- wizard.set_validation_error(
- curpage, exc.message)
- return fail()
+ return self.fail(exc.message)
else:
return True
logger.debug('checking name resolution')
- yield(("check name", 20), namecheck)
+ yield((self.tr("checking domain name"), 20), namecheck)
#########################
# 2) try https connection
@@ -260,6 +252,7 @@ class SelectProviderPage(InlineValidationPage):
except eipexceptions.HttpsBadCertError as exc:
logger.debug('exception')
+ return self.fail(exc.usermessage)
# XXX skipping for now...
##############################################
# We had this validation logic
@@ -268,8 +261,6 @@ class SelectProviderPage(InlineValidationPage):
#if self.trustProviderCertCheckBox.isChecked():
#pass
#else:
- wizard.set_validation_error(
- curpage, exc.usermessage)
#fingerprint = certs.get_cert_fingerprint(
#domain=domain, sep=" ")
@@ -284,23 +275,18 @@ class SelectProviderPage(InlineValidationPage):
#self.did_cert_check = True
#self.completeChanged.emit()
#return False
- return fail()
except baseexceptions.LeapException as exc:
- wizard.set_validation_error(
- curpage, exc.usermessage)
- return fail()
+ return self.fail(exc.usermessage)
except Exception as exc:
- wizard.set_validation_error(
- curpage, exc.message)
- return fail()
+ return self.fail(exc.message)
else:
return True
logger.debug('checking https connection')
- yield(("https check", 40), httpscheck)
+ yield((self.tr("checking https connection"), 40), httpscheck)
##################################
# 3) try download provider info...
@@ -316,28 +302,20 @@ class SelectProviderPage(InlineValidationPage):
except requests.exceptions.SSLError:
# XXX we should have catched this before.
# but cert checking is broken.
- wizard.set_validation_error(
- curpage,
- self.tr(
- "Could not get info from provider."))
- return fail()
+ return self.fail(self.tr(
+ "Could not get info from provider."))
except requests.exceptions.ConnectionError:
- wizard.set_validation_error(
- curpage,
- self.tr(
- "Could not download provider info "
- "(refused conn.)."))
- return fail()
+ return self.fail(self.tr(
+ "Could not download provider info "
+ "(refused conn.)."))
except Exception as exc:
- wizard.set_validation_error(
- curpage, exc.message)
- return fail()
-
+ return self.fail(
+ self.tr(exc.message))
else:
return True
- yield(("fetch info", 80), fetchinfo)
+ yield((self.tr("fetching provider info"), 80), fetchinfo)
# done!
diff --git a/src/leap/gui/firstrun/providersetup.py b/src/leap/gui/firstrun/providersetup.py
index 7904538d..1a362794 100644
--- a/src/leap/gui/firstrun/providersetup.py
+++ b/src/leap/gui/firstrun/providersetup.py
@@ -17,6 +17,9 @@ logger = logging.getLogger(__name__)
class ProviderSetupValidationPage(ValidationPage):
def __init__(self, parent=None):
super(ProviderSetupValidationPage, self).__init__(parent)
+ self.current_page = "providersetupvalidation"
+
+ # XXX needed anymore?
is_signup = self.field("is_signup")
self.is_signup = is_signup
@@ -33,7 +36,6 @@ class ProviderSetupValidationPage(ValidationPage):
generator that yields actual checks
that are executed in a separate thread
"""
- curpage = "providersetupvalidation"
full_domain = self.field('provider_domain')
wizard = self.wizard()
@@ -44,10 +46,6 @@ class ProviderSetupValidationPage(ValidationPage):
pCertChecker = wizard.providercertchecker(
domain=full_domain)
- def fail():
- self.is_done = False
- return False
-
yield(("head_sentinel", 0), lambda: None)
########################
@@ -73,19 +71,17 @@ class ProviderSetupValidationPage(ValidationPage):
except baseexceptions.LeapException as exc:
logger.error(exc.message)
- wizard.set_validation_error(
- curpage, exc.usermessage)
- return fail()
+ # XXX this should be _ method
+ return self.fail(self.tr(exc.usermessage))
except Exception as exc:
- wizard.set_validation_error(
- curpage, exc.message)
- return fail()
+ return self.fail(exc.message)
else:
return True
- yield(('Fetching CA certificate', 30), fetchcacert)
+ yield((self.tr('Fetching CA certificate'), 30),
+ fetchcacert)
#########################
# 2) check CA fingerprint
@@ -106,7 +102,8 @@ class ProviderSetupValidationPage(ValidationPage):
# should catch exception
#return False
- yield((self.tr("Checking CA fingerprint"), 60), checkcafingerprint)
+ yield((self.tr("Checking CA fingerprint"), 60),
+ checkcafingerprint)
#########################
# 2) check CA fingerprint
diff --git a/src/leap/gui/firstrun/register.py b/src/leap/gui/firstrun/register.py
index ddfcd1c5..7ce74892 100644
--- a/src/leap/gui/firstrun/register.py
+++ b/src/leap/gui/firstrun/register.py
@@ -1,6 +1,7 @@
"""
Register User Page, used in First Run Wizard
"""
+import json
import logging
import socket
@@ -14,6 +15,7 @@ from leap.gui.firstrun.mixins import UserFormMixIn
logger = logging.getLogger(__name__)
from leap.base import auth
+from leap.gui import styles
from leap.gui.constants import APP_LOGO, BARE_USERNAME_REGEX
from leap.gui.progress import InlineValidationPage
from leap.gui.styles import ErrorLabelStyleSheet
@@ -39,6 +41,8 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
self.setupSteps()
self.setupUI()
+ self.do_confirm_next = False
+ self.focused_field = False
def setupUI(self):
userNameLabel = QtGui.QLabel("User &name:")
@@ -101,23 +105,64 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
self.valFrame.hide()
self.setLayout(layout)
+ self.commitText("Sign up!")
+ # commit button
+
+ def commitText(self, text):
# change "commit" button text
self.setButtonText(
- QtGui.QWizard.CommitButton, "Sign up!")
+ QtGui.QWizard.CommitButton, text)
- # pagewizard methods
+ @property
+ def commitButton(self):
+ return self.wizard().button(QtGui.QWizard.CommitButton)
+
+ def commitFocus(self):
+ self.commitButton.setFocus()
+
+ def disableCommitButton(self):
+ self.commitButton.setDisabled(True)
+
+ def disableFields(self):
+ for field in (self.userNameLineEdit,
+ self.userPasswordLineEdit,
+ self.userPassword2LineEdit):
+ field.setDisabled(True)
+
+ # error painting
+
+ def markRedAndGetFocus(self, field):
+ field.setStyleSheet(styles.ErrorLineEdit)
+ if not self.focused_field:
+ self.focused_field = True
+ field.setFocus(QtCore.Qt.OtherFocusReason)
+
+ def markRegular(self, field):
+ field.setStyleSheet(styles.RegularLineEdit)
def populateErrors(self):
- # XXX could move this to ValidationMixin
- # used in providerselect too
+ def showerr(text):
+ self.validationMsg.setText(text)
+ err_lower = text.lower()
+ if "username" in err_lower:
+ self.markRedAndGetFocus(
+ self.userNameLineEdit)
+ if "password" in err_lower:
+ self.markRedAndGetFocus(
+ self.userPasswordLineEdit)
+
+ def unmarkred():
+ for field in (self.userNameLineEdit,
+ self.userPasswordLineEdit,
+ self.userPassword2LineEdit):
+ self.markRegular(field)
errors = self.wizard().get_validation_error(
self.current_page)
if errors:
bad_str = getattr(self, 'bad_string', None)
cur_str = self.userNameLineEdit.text()
- showerr = self.validationMsg.setText
prev_er = getattr(self, 'prevalidation_error', None)
if bad_str is None:
@@ -133,7 +178,13 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
if cur_str == bad_str:
showerr(errors)
else:
+ self.focused_field = False
showerr('')
+ unmarkred()
+ else:
+ # no errors
+ self.focused_field = False
+ unmarkred()
def cleanup_errormsg(self):
"""
@@ -153,60 +204,32 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
super(RegisterUserPage, self).paintEvent(event)
self.populateErrors()
- def validatePage(self):
- """
- we only pre-validate here password weakness
- stuff, or any other client side validation
- that we think of.
- real server validation is made on next page,
- and if any errors are thrown there we come back
- and re-display the validation label.
- """
- # calls checks, which after successful
- # execution will call on_checks_validation_ready
- self.do_checks()
- return self.is_done()
-
def _do_checks(self):
"""
generator that yields actual checks
that are executed in a separate thread
"""
- wizard = self.wizard()
- curpage = self.current_page
- senderr = lambda err: wizard.set_validation_error(curpage, err)
-
provider = self.field('provider_domain')
username = self.userNameLineEdit.text()
password = self.userPasswordLineEdit.text()
password2 = self.userPassword2LineEdit.text()
- def fail():
- self.set_undone()
- return False
-
def checkpass():
# we better have here
# some call to a password checker...
# to assess strenght and avoid silly stuff.
if password != password2:
- msg = self.tr('Password does not match..')
- senderr(msg)
- return fail()
+ return self.fail(self.tr('Password does not match..'))
if len(password) < 6:
#self.set_prevalidation_error('Password too short.')
- msg = self.tr('Password too short.')
- senderr(msg)
- return fail()
+ return self.fail(self.tr('Password too short.'))
if password == "123456":
# joking, but not too much.
#self.set_prevalidation_error('Password too obvious.')
- msg = self.tr('Password too obvious.')
- senderr(msg)
- return fail()
+ return self.fail(self.tr('Password too obvious.'))
# go
return True
@@ -220,6 +243,10 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
# 1) register user
##################################################
+ # show the frame before going on...
+ QtCore.QMetaObject.invokeMethod(
+ self, "showStepsFrame")
+
def register():
# XXX FIXME!
verify = False
@@ -233,22 +260,22 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
username, password)
except socket.timeout:
- msg = self.tr("Error connecting to provider (timeout)")
- senderr(msg)
- return fail()
+ return self.fail(
+ self.tr("Error connecting to provider (timeout)"))
except requests.exceptions.ConnectionError as exc:
logger.error(exc.message)
- msg = self.tr('Error Connecting to provider (connerr).')
- senderr(msg)
- return fail()
+ return self.fail(
+ self.tr('Error Connecting to provider (connerr).'))
+ except Exception as exc:
+ return self.fail(exc.message)
# XXX check for != OK instead???
if req.status_code in (404, 500):
- msg = self.tr(
- "Error during registration (%s)") % req.status_code
- return fail()
+ return self.fail(
+ self.tr(
+ "Error during registration (%s)") % req.status_code)
validation_msgs = json.loads(req.content)
errors = validation_msgs.get('errors', None)
@@ -257,9 +284,8 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
if errors and errors.get('login', None):
# XXX this sometimes catch the blank username
# but we're not allowing that (soon)
- msg = self.tr('Username not available.')
- senderr(msg)
- return fail()
+ return self.fail(
+ self.tr('Username not available.'))
logger.debug('registering user')
yield(("registering with provider", 40), register)
@@ -269,10 +295,61 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
yield(("end_sentinel", 0), lambda: None)
def on_checks_validation_ready(self):
-
+ """
+ after checks
+ """
if self.is_done():
+ # XXX should disable
+ # all entry forms
+ self.disableFields()
self.cleanup_errormsg()
- self.go_next()
+ self.clean_wizard_errors(self.current_page)
+ # make the user confirm the transition
+ # to next page.
+ self.commitText('Connect!')
+ self.commitFocus()
+ self.green_validation_status()
+ self.do_confirm_next = True
+
+ def green_validation_status(self):
+ val = self.validationMsg
+ val.setText(self.tr('Registration succeeded!'))
+ val.setStyleSheet(styles.GreenLineEdit)
+
+ def reset_validation_status(self):
+ """
+ empty the validation msg
+ and clean the inline validation widget.
+ """
+ self.validationMsg.setText('')
+ self.steps.removeAllSteps()
+ self.clearTable()
+
+ # pagewizard methods
+
+ def validatePage(self):
+ """
+ if not register done, do checks.
+ if done, wait for click.
+ """
+ self.disableCommitButton()
+ self.cleanup_errormsg()
+ self.clean_wizard_errors(self.current_page)
+
+ # After a successful validation
+ # (ie, success register with server)
+ # we change the commit button text
+ # and set this flag to True.
+ if self.do_confirm_next:
+ return True
+
+ if not self.is_done():
+ # calls checks, which after successful
+ # execution will call on_checks_validation_ready
+ self.reset_validation_status()
+ self.do_checks()
+
+ return self.is_done()
def initializePage(self):
"""
@@ -284,9 +361,11 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
provider)
self.validationMsg.setText('')
self.userPassword2LineEdit.setText('')
+ self.valFrame.hide()
def nextId(self):
wizard = self.wizard()
if not wizard:
return
+ # XXX this should be called connect
return wizard.get_page_index('signupvalidation')
diff --git a/src/leap/gui/firstrun/regvalidation.py b/src/leap/gui/firstrun/regvalidation.py
index 79971944..0e67834b 100644
--- a/src/leap/gui/firstrun/regvalidation.py
+++ b/src/leap/gui/firstrun/regvalidation.py
@@ -9,12 +9,12 @@ used in First Run Wizard
# the login branch of the wizard.
import logging
-import json
-import socket
+#import json
+#import socket
from PyQt4 import QtGui
-import requests
+#import requests
from leap.gui.progress import ValidationPage
from leap.util.web import get_https_domain_and_port
@@ -77,67 +77,59 @@ class RegisterUserValidationPage(ValidationPage):
pCertChecker = wizard.providercertchecker(
domain=full_domain)
- update_signal.emit("head_sentinel", 0)
+ yield(("head_sentinel", 0), lambda: None)
##################################################
- # 2) fetching eip service config
+ # 1) fetching eip service config
##################################################
+ def fetcheipconf():
+ try:
+ eipconfigchecker.fetch_eip_service_config(
+ domain=full_domain)
- step = "fetch_eipconf"
- fetching_eipconf_msg = "Fetching eip service configuration"
- update_signal.emit(fetching_eipconf_msg, 60)
- try:
- eipconfigchecker.fetch_eip_service_config(
- domain=full_domain)
-
- # XXX get specific exception
- except:
- self.set_error(
- step,
- 'Could not download eip config.')
- #pause_for_user()
- return False
- #pause_for_user()
+ # XXX get specific exception
+ except Exception as exc:
+ return self.fail(exc.message)
+
+ yield((self.tr("Fetching provider config..."), 40),
+ fetcheipconf)
##################################################
- # 3) getting client certificate
+ # 2) getting client certificate
##################################################
- # XXX maybe only do this if we come from signup
-
- step = "fetch_eipcert"
- fetching_clientcert_msg = "Fetching eip certificate"
- update_signal.emit(fetching_clientcert_msg, 80)
- try:
- pCertChecker.download_new_client_cert(
- credentials=credentials,
- verify=verify)
+ def fetcheipcert():
+ try:
+ pCertChecker.download_new_client_cert(
+ credentials=credentials,
+ verify=verify)
- except auth.SRPAuthenticationError as exc:
- self.set_error(
- step,
- "Authentication error: %s" % exc.message)
- return False
+ except auth.SRPAuthenticationError as exc:
+ return self.fail(self.tr(
+ "Authentication error: %s" % exc.message))
+ else:
+ return True
- #pause_for_user()
+ yield((self.tr("Fetching eip certificate"), 80),
+ fetcheipcert)
################
# end !
################
-
- update_signal.emit("end_sentinel", 100)
- #pause_for_user()
-
- # here we go! :)
- # this should be called CONNECT PAGE AGAIN.
- self.run_eip_checks_for_provider_and_connect(_domain)
+ self.set_done()
+ yield(("end_sentinel", 100), lambda: None)
def on_checks_validation_ready(self):
"""
called after _do_checks has finished
(connected to checker thread finished signal)
"""
- pass
+ # this should be called CONNECT PAGE AGAIN.
+ # here we go! :)
+ full_domain = self.field('provider_domain')
+ domain, port = get_https_domain_and_port(full_domain)
+ _domain = u"%s:%s" % (domain, port) if port != 443 else unicode(domain)
+ self.run_eip_checks_for_provider_and_connect(_domain)
def run_eip_checks_for_provider_and_connect(self, domain):
wizard = self.wizard()
diff --git a/src/leap/gui/firstrun/wizard.py b/src/leap/gui/firstrun/wizard.py
index 2ee1947a..9b77b877 100755
--- a/src/leap/gui/firstrun/wizard.py
+++ b/src/leap/gui/firstrun/wizard.py
@@ -39,7 +39,7 @@ TODO-ish:
[ ] Document signals used / expected.
[ ] Separate style from widgets.
[ ] Fix TOFU Widget for provider cert.
-[ ] Refactor widgets out.
+[X] Refactor widgets out.
[ ] Follow more MVC style.
[ ] Maybe separate "first run wizard" into different wizards
that share some of the pages?