summaryrefslogtreecommitdiff
path: root/src/leap/gui/firstrun
diff options
context:
space:
mode:
authordrebs <drebs@leap.se>2012-12-24 10:14:58 -0200
committerdrebs <drebs@leap.se>2012-12-24 10:14:58 -0200
commit319e279b59ac080779d0a3375ae4d6582f5ee6a3 (patch)
tree118dd0f495c0d54f2b2c66ea235e4e4e6b8cefd5 /src/leap/gui/firstrun
parentca5fb41a55e1292005ed186baf3710831d9ad678 (diff)
parenta7b091a0553e6120f3e0eb6d4e73a89732c589b2 (diff)
Merge branch 'develop' of ssh://code.leap.se/leap_client into develop
Diffstat (limited to 'src/leap/gui/firstrun')
-rw-r--r--src/leap/gui/firstrun/__init__.py4
-rw-r--r--src/leap/gui/firstrun/connect.py231
-rw-r--r--src/leap/gui/firstrun/intro.py10
-rw-r--r--src/leap/gui/firstrun/last.py2
-rw-r--r--src/leap/gui/firstrun/login.py247
-rw-r--r--src/leap/gui/firstrun/providerselect.py22
-rw-r--r--src/leap/gui/firstrun/register.py83
-rw-r--r--src/leap/gui/firstrun/regvalidation.py16
-rwxr-xr-xsrc/leap/gui/firstrun/tests/integration/fake_provider.py31
-rwxr-xr-xsrc/leap/gui/firstrun/wizard.py88
10 files changed, 279 insertions, 455 deletions
diff --git a/src/leap/gui/firstrun/__init__.py b/src/leap/gui/firstrun/__init__.py
index 8a70d90e..d380b75a 100644
--- a/src/leap/gui/firstrun/__init__.py
+++ b/src/leap/gui/firstrun/__init__.py
@@ -5,7 +5,6 @@ try:
except ValueError:
pass
-import connect
import intro
import last
import login
@@ -17,7 +16,6 @@ import register
import regvalidation
__all__ = [
- 'connect',
'intro',
'last',
'login',
@@ -26,4 +24,4 @@ __all__ = [
'providerselect',
'providersetup',
'register',
- 'regvalidation']
+ 'regvalidation'] # ,'wizard']
diff --git a/src/leap/gui/firstrun/connect.py b/src/leap/gui/firstrun/connect.py
deleted file mode 100644
index a0fe021c..00000000
--- a/src/leap/gui/firstrun/connect.py
+++ /dev/null
@@ -1,231 +0,0 @@
-"""
-Connecting Page, used in First Run Wizard
-"""
-# XXX FIXME
-# DEPRECATED. All functionality moved to regvalidation
-# This file should be removed after checking that one is ok.
-# XXX
-
-import logging
-
-from PyQt4 import QtGui
-
-logger = logging.getLogger(__name__)
-
-from leap.base import auth
-
-from leap.gui.constants import APP_LOGO
-from leap.gui.styles import ErrorLabelStyleSheet
-
-
-class ConnectingPage(QtGui.QWizardPage):
-
- # XXX change to a ValidationPage
-
- def __init__(self, parent=None):
- super(ConnectingPage, self).__init__(parent)
-
- self.setTitle("Connecting")
- self.setSubTitle('Connecting to provider.')
-
- self.setPixmap(
- QtGui.QWizard.LogoPixmap,
- QtGui.QPixmap(APP_LOGO))
-
- self.status = QtGui.QLabel("")
- self.status.setWordWrap(True)
- self.progress = QtGui.QProgressBar()
- self.progress.setMaximum(100)
- self.progress.hide()
-
- # for pre-checks
- self.status_line_1 = QtGui.QLabel()
- self.status_line_2 = QtGui.QLabel()
- self.status_line_3 = QtGui.QLabel()
- self.status_line_4 = QtGui.QLabel()
-
- # for connecting signals...
- self.status_line_5 = QtGui.QLabel()
-
- layout = QtGui.QGridLayout()
- layout.addWidget(self.status, 0, 1)
- layout.addWidget(self.progress, 5, 1)
- layout.addWidget(self.status_line_1, 8, 1)
- layout.addWidget(self.status_line_2, 9, 1)
- layout.addWidget(self.status_line_3, 10, 1)
- layout.addWidget(self.status_line_4, 11, 1)
-
- # XXX to be used?
- #self.validation_status = QtGui.QLabel("")
- #self.validation_status.setStyleSheet(
- #ErrorLabelStyleSheet)
- #self.validation_msg = QtGui.QLabel("")
-
- self.setLayout(layout)
-
- self.goto_login_again = False
-
- def set_status(self, status):
- self.status.setText(status)
- self.status.setWordWrap(True)
-
- def set_status_line(self, line, status):
- line = getattr(self, 'status_line_%s' % line)
- if line:
- line.setText(status)
-
- def set_validation_status(self, status):
- # Do not remember if we're using
- # status lines > 3 now...
- # if we are, move below
- self.status_line_3.setStyleSheet(
- ErrorLabelStyleSheet)
- self.status_line_3.setText(status)
-
- def set_validation_message(self, message):
- self.status_line_4.setText(message)
- self.status_line_4.setWordWrap(True)
-
- def get_donemsg(self, msg):
- return "%s ... done" % msg
-
- def run_eip_checks_for_provider_and_connect(self, domain):
- wizard = self.wizard()
- conductor = wizard.conductor
- start_eip_signal = getattr(
- wizard,
- 'start_eipconnection_signal', None)
-
- if conductor:
- conductor.set_provider_domain(domain)
- conductor.run_checks()
- self.conductor = conductor
- errors = self.eip_error_check()
- if not errors and start_eip_signal:
- start_eip_signal.emit()
-
- else:
- logger.warning(
- "No conductor found. This means that "
- "probably the wizard has been launched "
- "in an stand-alone way")
-
- def eip_error_check(self):
- """
- a version of the main app error checker,
- but integrated within the connecting page of the wizard.
- consumes the conductor error queue.
- pops errors, and add those to the wizard page
- """
- logger.debug('eip error check from connecting page')
- errq = self.conductor.error_queue
- # XXX missing!
-
- def fetch_and_validate(self):
- # XXX MOVE TO validate function in register-validation
- import time
- domain = self.field('provider_domain')
- wizard = self.wizard()
- #pconfig = wizard.providerconfig
- eipconfigchecker = wizard.eipconfigchecker()
- pCertChecker = wizard.providercertchecker(
- domain=domain)
-
- # username and password are in different fields
- # if they were stored in log_in or sign_up pages.
- from_login = self.wizard().from_login
- unamek_base = 'userName'
- passwk_base = 'userPassword'
- unamek = 'login_%s' % unamek_base if from_login else unamek_base
- passwk = 'login_%s' % passwk_base if from_login else passwk_base
-
- username = self.field(unamek)
- password = self.field(passwk)
- credentials = username, password
-
- self.progress.show()
-
- fetching_eip_conf_msg = 'Fetching eip service configuration'
- self.set_status(fetching_eip_conf_msg)
- self.progress.setValue(30)
-
- # Fetching eip service
- eipconfigchecker.fetch_eip_service_config(
- domain=domain)
-
- self.status_line_1.setText(
- self.get_donemsg(fetching_eip_conf_msg))
-
- getting_client_cert_msg = 'Getting client certificate'
- self.set_status(getting_client_cert_msg)
- self.progress.setValue(66)
-
- # Download cert
- try:
- pCertChecker.download_new_client_cert(
- credentials=credentials,
- # FIXME FIXME FIXME
- # XXX FIX THIS!!!!!
- # BUG #638. remove verify
- # FIXME FIXME FIXME
- verify=False)
- except auth.SRPAuthenticationError as exc:
- self.set_validation_status(
- "Authentication error: %s" % exc.message)
- return False
-
- time.sleep(2)
- self.status_line_2.setText(
- self.get_donemsg(getting_client_cert_msg))
-
- validating_clientcert_msg = 'Validating client certificate'
- self.set_status(validating_clientcert_msg)
- self.progress.setValue(90)
- time.sleep(2)
- self.status_line_3.setText(
- self.get_donemsg(validating_clientcert_msg))
-
- self.progress.setValue(100)
- time.sleep(3)
-
- # here we go! :)
- self.run_eip_checks_for_provider_and_connect(domain)
-
- #self.validation_block = self.wait_for_validation_block()
-
- # XXX signal timeout!
- return True
-
- #
- # wizardpage methods
- #
-
- def nextId(self):
- wizard = self.wizard()
- # XXX this does not work because
- # page login has already been met
- #if self.goto_login_again:
- #next_ = "login"
- #else:
- #next_ = "lastpage"
- next_ = "lastpage"
- return wizard.get_page_index(next_)
-
- def initializePage(self):
- # XXX if we're coming from signup page
- # we could say something like
- # 'registration successful!'
- self.status.setText(
- "We have "
- "all we need to connect with the provider.<br><br> "
- "Click <i>next</i> to continue. ")
- self.progress.setValue(0)
- self.progress.hide()
- self.status_line_1.setText('')
- self.status_line_2.setText('')
- self.status_line_3.setText('')
-
- def validatePage(self):
- # XXX remove
- validated = self.fetch_and_validate()
- return validated
diff --git a/src/leap/gui/firstrun/intro.py b/src/leap/gui/firstrun/intro.py
index 4bb008c7..0a7484e2 100644
--- a/src/leap/gui/firstrun/intro.py
+++ b/src/leap/gui/firstrun/intro.py
@@ -11,7 +11,7 @@ class IntroPage(QtGui.QWizardPage):
def __init__(self, parent=None):
super(IntroPage, self).__init__(parent)
- self.setTitle("First run wizard.")
+ self.setTitle(self.tr("First run wizard."))
#self.setPixmap(
#QtGui.QWizard.WatermarkPixmap,
@@ -21,7 +21,7 @@ class IntroPage(QtGui.QWizardPage):
QtGui.QWizard.LogoPixmap,
QtGui.QPixmap(APP_LOGO))
- label = QtGui.QLabel(
+ label = QtGui.QLabel(self.tr(
"Now we will guide you through "
"some configuration that is needed before you "
"can connect for the first time.<br><br>"
@@ -29,16 +29,16 @@ class IntroPage(QtGui.QWizardPage):
"you can find the wizard in the '<i>Settings</i>' menu from the "
"main window.<br><br>"
"Do you want to <b>sign up</b> for a new account, or <b>log "
- "in</b> with an already existing username?<br>")
+ "in</b> with an already existing username?<br>"))
label.setWordWrap(True)
radiobuttonGroup = QtGui.QGroupBox()
self.sign_up = QtGui.QRadioButton(
- "Sign up for a new account.")
+ self.tr("Sign up for a new account."))
self.sign_up.setChecked(True)
self.log_in = QtGui.QRadioButton(
- "Log In with my credentials.")
+ self.tr("Log In with my credentials."))
radiobLayout = QtGui.QVBoxLayout()
radiobLayout.addWidget(self.sign_up)
diff --git a/src/leap/gui/firstrun/last.py b/src/leap/gui/firstrun/last.py
index d33d2e77..1d8caca4 100644
--- a/src/leap/gui/firstrun/last.py
+++ b/src/leap/gui/firstrun/last.py
@@ -58,6 +58,8 @@ class LastPage(QtGui.QWizardPage):
self.label.setText(
"Click '<i>%s</i>' to end the wizard and "
"save your settings." % finishText)
+ # XXX init network checker
+ # trigger signal
@coroutine
def eip_status_handler(self):
diff --git a/src/leap/gui/firstrun/login.py b/src/leap/gui/firstrun/login.py
index 02bace86..e7afee9f 100644
--- a/src/leap/gui/firstrun/login.py
+++ b/src/leap/gui/firstrun/login.py
@@ -82,6 +82,120 @@ class LogInPage(InlineValidationPage, UserFormMixIn): # InlineValidationPage
#self.registerField('is_login_wizard')
+ # actual checks
+
+ def _do_checks(self):
+
+ full_username = self.userNameLineEdit.text()
+ ###########################
+ # 0) check user@domain form
+ ###########################
+
+ def checkusername():
+ if full_username.count('@') != 1:
+ return self.fail(
+ self.tr(
+ "Username must be in the username@provider form."))
+ else:
+ return True
+
+ yield(("head_sentinel", 0), checkusername)
+
+ username, domain = full_username.split('@')
+ password = self.userPasswordLineEdit.text()
+
+ # We try a call to an authenticated
+ # page here as a mean to catch
+ # srp authentication errors while
+ wizard = self.wizard()
+ eipconfigchecker = wizard.eipconfigchecker()
+
+ ########################
+ # 1) try name resolution
+ ########################
+ # show the frame before going on...
+ QtCore.QMetaObject.invokeMethod(
+ self, "showStepsFrame")
+
+ # Able to contact domain?
+ # can get definition?
+ # two-by-one
+ def resolvedomain():
+ try:
+ eipconfigchecker.fetch_definition(domain=domain)
+
+ # we're using requests here for all
+ # the possible error cases that it catches.
+ except requests.exceptions.ConnectionError as exc:
+ return self.fail(exc.message[1])
+ except requests.exceptions.HTTPError as exc:
+ return self.fail(exc.message)
+ except Exception as exc:
+ # XXX get catchall error msg
+ return self.fail(
+ exc.message)
+ else:
+ return True
+
+ yield((self.tr("Resolving domain name"), 20), resolvedomain)
+
+ wizard.set_providerconfig(
+ eipconfigchecker.defaultprovider.config)
+
+ ########################
+ # 2) do authentication
+ ########################
+ credentials = username, password
+ pCertChecker = wizard.providercertchecker(
+ domain=domain)
+
+ def validate_credentials():
+ #################
+ # FIXME #BUG #638
+ verify = False
+
+ try:
+ pCertChecker.download_new_client_cert(
+ credentials=credentials,
+ verify=verify)
+
+ except auth.SRPAuthenticationError as exc:
+ return self.fail(
+ self.tr("Authentication error: %s" % exc.message))
+
+ except Exception as exc:
+ return self.fail(exc.message)
+
+ else:
+ return True
+
+ yield(('Validating credentials', 60), validate_credentials)
+
+ self.set_done()
+ yield(("end_sentinel", 100), lambda: None)
+
+ def green_validation_status(self):
+ val = self.validationMsg
+ val.setText(self.tr('Credentials validated.'))
+ val.setStyleSheet(styles.GreenLineEdit)
+
+ def on_checks_validation_ready(self):
+ """
+ after checks
+ """
+ if self.is_done():
+ self.disableFields()
+ self.cleanup_errormsg()
+ self.clean_wizard_errors(self.current_page)
+ # make the user confirm the transition
+ # to next page.
+ self.nextText('&Next')
+ self.nextFocus()
+ self.green_validation_status()
+ self.do_confirm_next = True
+
+ # ui update
+
def nextText(self, text):
self.setButtonText(
QtGui.QWizard.NextButton, text)
@@ -94,12 +208,18 @@ class LogInPage(InlineValidationPage, UserFormMixIn): # InlineValidationPage
self.wizard().button(
QtGui.QWizard.NextButton).setDisabled(True)
- def onUserNameEdit(self, *args):
+ def onUserNamePositionChanged(self, *args):
if self.initial_username_sample:
self.userNameLineEdit.setText('')
# XXX set regular color
self.initial_username_sample = None
+ def onUserNameTextChanged(self, *args):
+ if self.initial_username_sample:
+ k = args[0][-1]
+ self.initial_username_sample = None
+ self.userNameLineEdit.setText(k)
+
def disableFields(self):
for field in (self.userNameLineEdit,
self.userPasswordLineEdit):
@@ -111,13 +231,8 @@ class LogInPage(InlineValidationPage, UserFormMixIn): # InlineValidationPage
errors = self.wizard().get_validation_error(
self.current_page)
- #prev_er = getattr(self, 'prevalidation_error', None)
showerr = self.validationMsg.setText
- #if not errors and prev_er:
- #showerr(prev_er)
- #return
-#
if errors:
bad_str = getattr(self, 'bad_string', None)
cur_str = self.userNameLineEdit.text()
@@ -128,9 +243,6 @@ class LogInPage(InlineValidationPage, UserFormMixIn): # InlineValidationPage
self.bad_string = cur_str
showerr(errors)
else:
- #if prev_er:
- #showerr(prev_er)
- #return
# not the first time
if cur_str == bad_str:
showerr(errors)
@@ -177,7 +289,9 @@ class LogInPage(InlineValidationPage, UserFormMixIn): # InlineValidationPage
username = self.userNameLineEdit
username.setText('username@provider.example.org')
username.cursorPositionChanged.connect(
- self.onUserNameEdit)
+ self.onUserNamePositionChanged)
+ username.textChanged.connect(
+ self.onUserNameTextChanged)
self.initial_username_sample = True
self.validationMsg.setText('')
self.valFrame.hide()
@@ -215,116 +329,3 @@ class LogInPage(InlineValidationPage, UserFormMixIn): # InlineValidationPage
self.do_checks()
return self.is_done()
-
- def _do_checks(self):
- # XXX convert this to inline
-
- full_username = self.userNameLineEdit.text()
- ###########################
- # 0) check user@domain form
- ###########################
-
- def checkusername():
- if full_username.count('@') != 1:
- return self.fail(
- self.tr(
- "Username must be in the username@provider form."))
- else:
- return True
-
- yield(("head_sentinel", 0), checkusername)
-
- # XXX I think this is not needed
- # since we're also checking for the is_signup field.
- #self.wizard().from_login = True
-
- username, domain = full_username.split('@')
- password = self.userPasswordLineEdit.text()
-
- # We try a call to an authenticated
- # page here as a mean to catch
- # srp authentication errors while
- wizard = self.wizard()
- eipconfigchecker = wizard.eipconfigchecker()
-
- ########################
- # 1) try name resolution
- ########################
- # show the frame before going on...
- QtCore.QMetaObject.invokeMethod(
- self, "showStepsFrame")
-
- # Able to contact domain?
- # can get definition?
- # two-by-one
- def resolvedomain():
- try:
- eipconfigchecker.fetch_definition(domain=domain)
-
- # we're using requests here for all
- # the possible error cases that it catches.
- except requests.exceptions.ConnectionError as exc:
- return self.fail(exc.message[1])
- except requests.exceptions.HTTPError as exc:
- return self.fail(exc.message)
- except Exception as exc:
- # XXX get catchall error msg
- return self.fail(
- exc.message)
-
- yield((self.tr("resolving domain name"), 20), resolvedomain)
-
- wizard.set_providerconfig(
- eipconfigchecker.defaultprovider.config)
-
- ########################
- # 2) do authentication
- ########################
- credentials = username, password
- pCertChecker = wizard.providercertchecker(
- domain=domain)
-
- def validate_credentials():
- #################
- # FIXME #BUG #638
- verify = False
-
- try:
- pCertChecker.download_new_client_cert(
- credentials=credentials,
- verify=verify)
-
- except auth.SRPAuthenticationError as exc:
- return self.fail(
- self.tr("Authentication error: %s" % exc.message))
-
- except Exception as exc:
- return self.fail(exc.message)
-
- else:
- return True
-
- yield(('Validating credentials', 20), validate_credentials)
-
- self.set_done()
- yield(("end_sentinel", 0), lambda: None)
-
- def green_validation_status(self):
- val = self.validationMsg
- val.setText(self.tr('Credentials validated.'))
- val.setStyleSheet(styles.GreenLineEdit)
-
- def on_checks_validation_ready(self):
- """
- after checks
- """
- if self.is_done():
- self.disableFields()
- self.cleanup_errormsg()
- self.clean_wizard_errors(self.current_page)
- # make the user confirm the transition
- # to next page.
- self.nextText('&Next')
- self.nextFocus()
- self.green_validation_status()
- self.do_confirm_next = True
diff --git a/src/leap/gui/firstrun/providerselect.py b/src/leap/gui/firstrun/providerselect.py
index a4be51a9..fd48f7f9 100644
--- a/src/leap/gui/firstrun/providerselect.py
+++ b/src/leap/gui/firstrun/providerselect.py
@@ -40,7 +40,7 @@ class SelectProviderPage(InlineValidationPage):
self.did_cert_check = False
- self.is_done = False
+ self.done = False
self.setupSteps()
self.setupUI()
@@ -131,7 +131,7 @@ class SelectProviderPage(InlineValidationPage):
# certinfo
- def setupCertInfoGroup(self):
+ def setupCertInfoGroup(self): # pragma: no cover
# XXX not used now.
certinfoGroup = QtGui.QGroupBox(
self.tr("Certificate validation"))
@@ -188,7 +188,6 @@ class SelectProviderPage(InlineValidationPage):
_domain = u"%s:%s" % (domain, port) if port != 443 else unicode(domain)
netchecker = wizard.netchecker()
-
providercertchecker = wizard.providercertchecker()
eipconfigchecker = wizard.eipconfigchecker(domain=_domain)
@@ -205,6 +204,7 @@ class SelectProviderPage(InlineValidationPage):
this domain
"""
try:
+ #import ipdb;ipdb.set_trace()
netchecker.check_name_resolution(
domain)
@@ -306,7 +306,7 @@ class SelectProviderPage(InlineValidationPage):
# done!
- self.is_done = True
+ self.done = True
yield(("end_sentinel", 100), lambda: None)
def on_checks_validation_ready(self):
@@ -316,7 +316,7 @@ class SelectProviderPage(InlineValidationPage):
self.domain_checked = True
self.completeChanged.emit()
# let's set focus...
- if self.is_done:
+ if self.is_done():
self.wizard().clean_validation_error(self.current_page)
nextbutton = self.wizard().button(QtGui.QWizard.NextButton)
nextbutton.setFocus()
@@ -329,7 +329,7 @@ class SelectProviderPage(InlineValidationPage):
def is_insecure_cert_trusted(self):
return self.trustProviderCertCheckBox.isChecked()
- def onTrustCheckChanged(self, state):
+ def onTrustCheckChanged(self, state): # pragma: no cover XXX
checked = False
if state == 2:
checked = True
@@ -342,7 +342,7 @@ class SelectProviderPage(InlineValidationPage):
# trigger signal to redraw next button
self.completeChanged.emit()
- def add_cert_info(self, certinfo):
+ def add_cert_info(self, certinfo): # pragma: no cover XXX
self.certWarning.setText(
"Do you want to <b>trust this provider certificate?</b>")
self.certInfo.setText(
@@ -351,7 +351,7 @@ class SelectProviderPage(InlineValidationPage):
self.certinfoGroup.show()
def onProviderChanged(self, text):
- self.is_done = False
+ self.done = False
provider = self.providerNameEdit.text()
if provider:
self.providerCheckButton.setDisabled(False)
@@ -374,7 +374,7 @@ class SelectProviderPage(InlineValidationPage):
def isComplete(self):
provider = self.providerNameEdit.text()
- if not self.is_done:
+ if not self.is_done():
return False
if not provider:
@@ -383,7 +383,7 @@ class SelectProviderPage(InlineValidationPage):
if self.is_insecure_cert_trusted():
return True
if not self.did_cert_check:
- if self.is_done:
+ if self.is_done():
# XXX sure?
return True
return False
@@ -452,7 +452,7 @@ class SelectProviderPage(InlineValidationPage):
if hasattr(self, 'certinfoGroup'):
# XXX remove ?
self.certinfoGroup.hide()
- self.is_done = False
+ self.done = False
self.providerCheckButton.setDisabled(True)
self.valFrame.hide()
self.steps.removeAllSteps()
diff --git a/src/leap/gui/firstrun/register.py b/src/leap/gui/firstrun/register.py
index e85723cb..4c811093 100644
--- a/src/leap/gui/firstrun/register.py
+++ b/src/leap/gui/firstrun/register.py
@@ -131,6 +131,16 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
field.setDisabled(True)
# error painting
+ def paintEvent(self, event):
+ """
+ we hook our populate errors
+ on paintEvent because we need it to catch
+ when user enters the page coming from next,
+ and initializePage does not cover that case.
+ Maybe there's a better event to hook upon.
+ """
+ super(RegisterUserPage, self).paintEvent(event)
+ self.populateErrors()
def markRedAndGetFocus(self, field):
field.setStyleSheet(styles.ErrorLineEdit)
@@ -193,16 +203,21 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
"""
self.bad_string = None
- def paintEvent(self, event):
+ def green_validation_status(self):
+ val = self.validationMsg
+ val.setText(self.tr('Registration succeeded!'))
+ val.setStyleSheet(styles.GreenLineEdit)
+
+ def reset_validation_status(self):
"""
- we hook our populate errors
- on paintEvent because we need it to catch
- when user enters the page coming from next,
- and initializePage does not cover that case.
- Maybe there's a better event to hook upon.
+ empty the validation msg
+ and clean the inline validation widget.
"""
- super(RegisterUserPage, self).paintEvent(event)
- self.populateErrors()
+ self.validationMsg.setText('')
+ self.steps.removeAllSteps()
+ self.clearTable()
+
+ # actual checks
def _do_checks(self):
"""
@@ -255,6 +270,7 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
schema="https",
provider=provider,
verify=verify)
+ #import ipdb;ipdb.set_trace()
try:
ok, req = signup.register_user(
username, password)
@@ -277,9 +293,15 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
self.tr(
"Error during registration (%s)") % req.status_code)
- validation_msgs = json.loads(req.content)
- errors = validation_msgs.get('errors', None)
- logger.debug('validation errors: %s' % validation_msgs)
+ try:
+ validation_msgs = json.loads(req.content)
+ errors = validation_msgs.get('errors', None)
+ logger.debug('validation errors: %s' % validation_msgs)
+ except ValueError:
+ # probably bad json returned
+ return self.fail(
+ self.tr(
+ "Could not register (bad response)"))
if errors and errors.get('login', None):
# XXX this sometimes catch the blank username
@@ -287,11 +309,13 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
return self.fail(
self.tr('Username not available.'))
+ return True
+
logger.debug('registering user')
yield(("registering with provider", 40), register)
self.set_done()
- yield(("end_sentinel", 0), lambda: None)
+ yield(("end_sentinel", 100), lambda: None)
def on_checks_validation_ready(self):
"""
@@ -308,20 +332,6 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
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):
@@ -352,17 +362,26 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):
"""
inits wizard page
"""
- provider = self.field('provider_domain')
- self.setSubTitle(
- self.tr("Register a new user with provider %s.") %
- provider)
+ provider = unicode(self.field('provider_domain'))
+ if provider:
+ # here we should have provider
+ # but in tests we might not.
+
+ # XXX this error causes a segfault on free()
+ # that we might want to get fixed ...
+ #self.setSubTitle(
+ #self.tr("Register a new user with provider %s.") %
+ #provider)
+ self.setSubTitle(
+ self.tr("Register a new user with provider %s." %
+ provider))
self.validationMsg.setText('')
self.userPassword2LineEdit.setText('')
self.valFrame.hide()
def nextId(self):
wizard = self.wizard()
- if not wizard:
- return
+ #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 0e67834b..b86583e0 100644
--- a/src/leap/gui/firstrun/regvalidation.py
+++ b/src/leap/gui/firstrun/regvalidation.py
@@ -29,6 +29,7 @@ class RegisterUserValidationPage(ValidationPage):
def __init__(self, parent=None):
super(RegisterUserValidationPage, self).__init__(parent)
+ self.current_page = "signupvalidation"
title = "Connecting..."
# XXX uh... really?
@@ -100,9 +101,12 @@ class RegisterUserValidationPage(ValidationPage):
def fetcheipcert():
try:
- pCertChecker.download_new_client_cert(
+ downloaded = pCertChecker.download_new_client_cert(
credentials=credentials,
verify=verify)
+ if not downloaded:
+ logger.error('Could not download client cert.')
+ return False
except auth.SRPAuthenticationError as exc:
return self.fail(self.tr(
@@ -126,10 +130,12 @@ class RegisterUserValidationPage(ValidationPage):
"""
# 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)
+ if self.is_done():
+ 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/tests/integration/fake_provider.py b/src/leap/gui/firstrun/tests/integration/fake_provider.py
index 33ee0ee6..445b4487 100755
--- a/src/leap/gui/firstrun/tests/integration/fake_provider.py
+++ b/src/leap/gui/firstrun/tests/integration/fake_provider.py
@@ -40,6 +40,8 @@ from twisted.web.static import File
from twisted.web.resource import Resource
from twisted.internet import reactor
+from leap.testing.https_server import where
+
# See
# http://twistedmatrix.com/documents/current/web/howto/web-in-60/index.htmln
# for more examples
@@ -229,14 +231,13 @@ def get_certs_path():
def get_TLS_credentials():
# XXX this is giving errors
# XXX REview! We want to use gnutls!
- certs_path = get_certs_path()
cert = crypto.X509Certificate(
- open(certs_path + '/leaptestscert.pem').read())
+ open(where('leaptestscert.pem')).read())
key = crypto.X509PrivateKey(
- open(certs_path + '/leaptestskey.pem').read())
+ open(where('leaptestskey.pem')).read())
ca = crypto.X509Certificate(
- open(certs_path + '/cacert.pem').read())
+ open(where('cacert.pem')).read())
#crl = crypto.X509CRL(open(certs_path + '/crl.pem').read())
#cred = crypto.X509Credentials(cert, key, [ca], [crl])
cred = X509Credentials(cert, key, [ca])
@@ -253,19 +254,17 @@ class OpenSSLServerContextFactory:
"""Create an SSL context.
This is a sample implementation that loads a certificate from a file
called 'server.pem'."""
- certs_path = get_certs_path()
ctx = SSL.Context(SSL.SSLv23_METHOD)
- ctx.use_certificate_file(certs_path + '/leaptestscert.pem')
- ctx.use_privatekey_file(certs_path + '/leaptestskey.pem')
+ #certs_path = get_certs_path()
+ #ctx.use_certificate_file(certs_path + '/leaptestscert.pem')
+ #ctx.use_privatekey_file(certs_path + '/leaptestskey.pem')
+ ctx.use_certificate_file(where('leaptestscert.pem'))
+ ctx.use_privatekey_file(where('leaptestskey.pem'))
return ctx
-if __name__ == "__main__":
-
- from twisted.python import log
- log.startLogging(sys.stdout)
-
+def serve_fake_provider():
root = Resource()
root.putChild("provider.json", File("./provider.json"))
config = Resource()
@@ -293,3 +292,11 @@ if __name__ == "__main__":
reactor.listenSSL(8443, factory, OpenSSLServerContextFactory())
reactor.run()
+
+
+if __name__ == "__main__":
+
+ from twisted.python import log
+ log.startLogging(sys.stdout)
+
+ serve_fake_provider()
diff --git a/src/leap/gui/firstrun/wizard.py b/src/leap/gui/firstrun/wizard.py
index 9b77b877..89209401 100755
--- a/src/leap/gui/firstrun/wizard.py
+++ b/src/leap/gui/firstrun/wizard.py
@@ -2,8 +2,11 @@
import logging
import sip
-sip.setapi('QString', 2)
-sip.setapi('QVariant', 2)
+try:
+ sip.setapi('QString', 2)
+ sip.setapi('QVariant', 2)
+except ValueError:
+ pass
from PyQt4 import QtCore
from PyQt4 import QtGui
@@ -46,12 +49,29 @@ TODO-ish:
"""
+def get_pages_dict():
+ return OrderedDict((
+ ('intro', firstrun.intro.IntroPage),
+ ('providerselection',
+ firstrun.providerselect.SelectProviderPage),
+ ('login', firstrun.login.LogInPage),
+ ('providerinfo', firstrun.providerinfo.ProviderInfoPage),
+ ('providersetupvalidation',
+ firstrun.providersetup.ProviderSetupValidationPage),
+ ('signup', firstrun.register.RegisterUserPage),
+ ('signupvalidation',
+ firstrun.regvalidation.RegisterUserValidationPage),
+ ('lastpage', firstrun.last.LastPage)
+ ))
+
+
class FirstRunWizard(QtGui.QWizard):
def __init__(
self,
conductor_instance,
parent=None,
+ pages_dict=None,
eip_username=None,
providers=None,
success_cb=None, is_provider_setup=False,
@@ -112,20 +132,7 @@ class FirstRunWizard(QtGui.QWizard):
self.is_previously_registered = bool(self.eip_username)
self.from_login = False
- pages_dict = OrderedDict((
- ('intro', firstrun.intro.IntroPage),
- ('providerselection',
- firstrun.providerselect.SelectProviderPage),
- ('login', firstrun.login.LogInPage),
- ('providerinfo', firstrun.providerinfo.ProviderInfoPage),
- ('providersetupvalidation',
- firstrun.providersetup.ProviderSetupValidationPage),
- ('signup', firstrun.register.RegisterUserPage),
- ('signupvalidation',
- firstrun.regvalidation.RegisterUserValidationPage),
- ('connecting', firstrun.connect.ConnectingPage),
- ('lastpage', firstrun.last.LastPage)
- ))
+ pages_dict = pages_dict or get_pages_dict()
self.add_pages_from_dict(pages_dict)
self.validation_errors = {}
@@ -146,6 +153,10 @@ class FirstRunWizard(QtGui.QWizard):
# TODO: set style for MAC / windows ...
#self.setWizardStyle()
+ #
+ # setup pages in wizard
+ #
+
def add_pages_from_dict(self, pages_dict):
"""
@param pages_dict: the dictionary with pages, where
@@ -168,6 +179,10 @@ class FirstRunWizard(QtGui.QWizard):
"""
return self.pages_dict.keys().index(page_name)
+ #
+ # validation errors
+ #
+
def set_validation_error(self, pagename, error):
self.validation_errors[pagename] = error
@@ -179,20 +194,6 @@ class FirstRunWizard(QtGui.QWizard):
def get_validation_error(self, pagename):
return self.validation_errors.get(pagename, None)
- def set_providerconfig(self, providerconfig):
- self.providerconfig = providerconfig
-
- def setWindowFlags(self, flags):
- logger.debug('setting window flags')
- QtGui.QWizard.setWindowFlags(self, flags)
-
- def focusOutEvent(self, event):
- # needed ?
- self.setFocus(True)
- self.activateWindow()
- self.raise_()
- self.show()
-
def accept(self):
"""
final step in the wizard.
@@ -246,11 +247,14 @@ class FirstRunWizard(QtGui.QWizard):
if cb and callable(cb):
self.success_cb()
- def get_provider_by_index(self):
- provider = self.field('provider_index')
- return self.providers[provider]
+ # misc helpers
def get_random_str(self, n):
+ """
+ returns a random string
+ :param n: the length of the desired string
+ :rvalue: str
+ """
from string import (ascii_uppercase, ascii_lowercase, digits)
from random import choice
return ''.join(choice(
@@ -258,6 +262,24 @@ class FirstRunWizard(QtGui.QWizard):
ascii_lowercase +
digits) for x in range(n))
+ def set_providerconfig(self, providerconfig):
+ """
+ sets a providerconfig attribute
+ used when we fetch and parse a json configuration
+ """
+ self.providerconfig = providerconfig
+
+ def get_provider_by_index(self): # pragma: no cover
+ """
+ returns the value of a provider given its index.
+ this was used in the select provider page,
+ in the case where we were preseeding providers in a combobox
+ """
+ # Leaving it here for the moment when we go back at the
+ # option of preseeding with known provider values.
+ provider = self.field('provider_index')
+ return self.providers[provider]
+
if __name__ == '__main__':
# standalone test