summaryrefslogtreecommitdiff
path: root/src/leap/gui/firstrun
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/gui/firstrun')
-rw-r--r--src/leap/gui/firstrun/login.py67
-rw-r--r--src/leap/gui/firstrun/providerselect.py8
-rw-r--r--src/leap/gui/firstrun/providersetup.py158
-rw-r--r--src/leap/gui/firstrun/register.py158
-rw-r--r--src/leap/gui/firstrun/regvalidation.py79
-rwxr-xr-xsrc/leap/gui/firstrun/wizard.py1
6 files changed, 283 insertions, 188 deletions
diff --git a/src/leap/gui/firstrun/login.py b/src/leap/gui/firstrun/login.py
index 004fa7d4..3a6ec089 100644
--- a/src/leap/gui/firstrun/login.py
+++ b/src/leap/gui/firstrun/login.py
@@ -6,14 +6,17 @@ from PyQt4 import QtGui
#import requests
+from leap.base import auth
from leap.gui.firstrun.mixins import UserFormMixIn
from leap.gui.constants import APP_LOGO, FULL_USERNAME_REGEX
from leap.gui.styles import ErrorLabelStyleSheet
-class LogInPage(QtGui.QWizardPage, UserFormMixIn):
+class LogInPage(QtGui.QWizardPage, UserFormMixIn): # InlineValidationPage
+
def __init__(self, parent=None):
+
super(LogInPage, self).__init__(parent)
self.setTitle("Log In")
@@ -24,6 +27,9 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):
QtGui.QWizard.LogoPixmap,
QtGui.QPixmap(APP_LOGO))
+ self.setupUI()
+
+ def setupUI(self):
userNameLabel = QtGui.QLabel("User &name:")
userNameLineEdit = QtGui.QLineEdit()
userNameLineEdit.cursorPositionChanged.connect(
@@ -149,6 +155,7 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):
#wizard = self.wizard()
#eipconfigchecker = wizard.eipconfigchecker()
+ # XXX should move to _do_checks
full_username = self.userNameLineEdit.text()
password = self.userPasswordLineEdit.text()
if full_username.count('@') != 1:
@@ -191,3 +198,61 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):
self.cleanup_errormsg()
return True
+
+ def _do_checks(self):
+ # XXX convert this to inline
+
+ full_username = self.userNameLineEdit.text()
+ password = self.userPasswordLineEdit.text()
+ username, domain = full_username.split('@')
+ # We try a call to an authenticated
+ # page here as a mean to catch
+ # srp authentication errors while
+ wizard = self.wizard()
+ pCertChecker = wizard.providercertchecker(
+ domain=domain)
+
+ curpage = "login"
+
+ def fail():
+ self.is_done = False
+ return False
+
+ ########################
+ # 1) try name resolution
+ ########################
+ # XXX
+ # bring here from validation above...
+
+ ########################
+ # 2) do authentication
+ ########################
+
+ unamek = 'login_userName'
+ passwk = 'login_userPassword'
+
+ username = self.field(unamek)
+ password = self.field(passwk)
+ credentials = username, password
+
+ def validate_credentials():
+ #################
+ # FIXME #BUG #638
+ verify = False
+
+ try:
+ pCertChecker.download_new_client_cert(
+ credentials=credentials,
+ verify=verify)
+
+ except auth.SRPAuthenticationError as exc:
+ wizard.set_validation_error(
+ curpage, "Authentication error: %s" % exc.usermessage)
+ return fail()
+
+ except Exception as exc:
+ wizard.set_validation_error(
+ curpage, "%s" % exc.message)
+ return fail()
+
+ yield(('Validating credentials', 20), lambda: None)
diff --git a/src/leap/gui/firstrun/providerselect.py b/src/leap/gui/firstrun/providerselect.py
index d029b1db..dffde040 100644
--- a/src/leap/gui/firstrun/providerselect.py
+++ b/src/leap/gui/firstrun/providerselect.py
@@ -1,7 +1,6 @@
"""
Select Provider Page, used in First Run Wizard
"""
-from functools import partial
import logging
import requests
@@ -20,10 +19,9 @@ from leap.util.web import get_https_domain_and_port
logger = logging.getLogger(__name__)
-# XXX check newer version in progress...
-
def delay(obj, method_str):
+ # XXX check newer version in progress.py...
"""
this is a hack to get responsiveness in the ui
"""
@@ -40,6 +38,7 @@ class SelectProviderPage(InlineValidationPage):
def __init__(self, parent=None, providers=None):
super(SelectProviderPage, self).__init__(parent)
+ self.current_page = 'providerselection'
self.setTitle(self.tr("Enter Provider"))
self.setSubTitle(self.tr(
@@ -51,7 +50,6 @@ class SelectProviderPage(InlineValidationPage):
QtGui.QPixmap(APP_LOGO))
self.did_cert_check = False
- self.current_page = 'providerselection'
self.is_done = False
@@ -346,7 +344,7 @@ class SelectProviderPage(InlineValidationPage):
self.is_done = True
yield(("end_sentinel", 100), lambda: None)
- def _inline_validation_ready(self):
+ def on_checks_validation_ready(self):
"""
called after _do_checks has finished.
"""
diff --git a/src/leap/gui/firstrun/providersetup.py b/src/leap/gui/firstrun/providersetup.py
index 042d117c..7904538d 100644
--- a/src/leap/gui/firstrun/providersetup.py
+++ b/src/leap/gui/firstrun/providersetup.py
@@ -6,10 +6,10 @@ import logging
from PyQt4 import QtGui
-from leap.base import auth
+from leap.base import exceptions as baseexceptions
from leap.gui.progress import ValidationPage
-from leap.gui.constants import APP_LOGO, pause_for_user
+from leap.gui.constants import APP_LOGO
logger = logging.getLogger(__name__)
@@ -20,18 +20,21 @@ class ProviderSetupValidationPage(ValidationPage):
is_signup = self.field("is_signup")
self.is_signup = is_signup
- self.setTitle("Provider setup")
+ self.setTitle(self.tr("Provider setup"))
self.setSubTitle(
- "Doing autoconfig.")
+ self.tr("Doing autoconfig."))
self.setPixmap(
QtGui.QWizard.LogoPixmap,
QtGui.QPixmap(APP_LOGO))
- def _do_checks(self, update_signal=None):
+ def _do_checks(self):
"""
- executes actual checks in a separate thread
+ generator that yields actual checks
+ that are executed in a separate thread
"""
+ curpage = "providersetupvalidation"
+
full_domain = self.field('provider_domain')
wizard = self.wizard()
pconfig = wizard.providerconfig
@@ -41,68 +44,56 @@ class ProviderSetupValidationPage(ValidationPage):
pCertChecker = wizard.providercertchecker(
domain=full_domain)
- update_signal.emit('head_sentinel', 0)
-
- ######################################
- if not self.is_signup:
- # We come from login page.
- # We try a call to an authenticated
- # page here as a mean to catch
- # srp authentication errors while
- # we are still at one page's reach
- # of the login credentials input page.
- # (so we're able to go back an correct)
+ def fail():
+ self.is_done = False
+ return False
- step = "fetch_eipcert"
- update_signal.emit('Validating credentials', 20)
+ yield(("head_sentinel", 0), lambda: None)
- unamek = 'login_userName'
- passwk = 'login_userPassword'
+ ########################
+ # 1) fetch ca cert
+ ########################
- username = self.field(unamek)
- password = self.field(passwk)
- credentials = username, password
-
- #################
- # FIXME #BUG #638
- verify = False
+ def fetchcacert():
+ if pconfig:
+ ca_cert_uri = pconfig.get('ca_cert_uri').geturl()
+ else:
+ ca_cert_uri = None
+ # XXX check scheme == "https"
+ # XXX passing verify == False because
+ # we have trusted right before.
+ # We should check it's the same domain!!!
+ # (Check with the trusted fingerprints dict
+ # or something smart)
try:
- pCertChecker.download_new_client_cert(
- credentials=credentials,
- verify=verify)
+ pCertChecker.download_ca_cert(
+ uri=ca_cert_uri,
+ verify=False)
- except auth.SRPAuthenticationError as exc:
- self.set_error(
- step,
- "Authentication error: %s" % exc.message)
- return False
+ except baseexceptions.LeapException as exc:
+ logger.error(exc.message)
+ wizard.set_validation_error(
+ curpage, exc.usermessage)
+ return fail()
- #pause_for_user()
+ except Exception as exc:
+ wizard.set_validation_error(
+ curpage, exc.message)
+ return fail()
- #######################################
+ else:
+ return True
- update_signal.emit('Fetching CA certificate', 30)
- #pause_for_user()
+ yield(('Fetching CA certificate', 30), fetchcacert)
- if pconfig:
- ca_cert_uri = pconfig.get('ca_cert_uri').geturl()
- else:
- ca_cert_uri = None
+ #########################
+ # 2) check CA fingerprint
+ #########################
- # XXX check scheme == "https"
- # XXX passing verify == False because
- # we have trusted right before.
- # We should check it's the same domain!!!
- # (Check with the trusted fingerprints dict
- # or something smart)
-
- pCertChecker.download_ca_cert(
- uri=ca_cert_uri,
- verify=False)
- #pause_for_user()
-
- update_signal.emit('Checking CA fingerprint', 66)
+ def checkcafingerprint():
+ # XXX get the real thing!!!
+ pass
#ca_cert_fingerprint = pconfig.get('ca_cert_fingerprint', None)
# XXX get fingerprint dict (types)
@@ -115,33 +106,40 @@ class ProviderSetupValidationPage(ValidationPage):
# should catch exception
#return False
- update_signal.emit('Validating api certificate', 90)
-
- #api_uri = pconfig.get('api_uri', None)
- #try:
- #api_cert_verified = pCertChecker.verify_api_https(api_uri)
- #except requests.exceptions.SSLError as exc:
- #logger.error('BUG #638. %s' % exc.message)
- # XXX RAISE! See #638
- # bypassing until the hostname is fixed.
- # We probably should raise yet-another-warning
- # here saying user that the hostname "XX.XX.XX.XX' does not
- # match 'foo.bar.baz'
- #api_cert_verified = True
-
- #if not api_cert_verified:
- # XXX update validationMsg
- # should catch exception
- #return False
+ yield((self.tr("Checking CA fingerprint"), 60), checkcafingerprint)
+
+ #########################
+ # 2) check CA fingerprint
+ #########################
+
+ def validatecacert():
+ pass
+ #api_uri = pconfig.get('api_uri', None)
+ #try:
+ #api_cert_verified = pCertChecker.verify_api_https(api_uri)
+ #except requests.exceptions.SSLError as exc:
+ #logger.error('BUG #638. %s' % exc.message)
+ # XXX RAISE! See #638
+ # bypassing until the hostname is fixed.
+ # We probably should raise yet-another-warning
+ # here saying user that the hostname "XX.XX.XX.XX' does not
+ # match 'foo.bar.baz'
+ #api_cert_verified = True
+
+ #if not api_cert_verified:
+ # XXX update validationMsg
+ # should catch exception
+ #return False
+
+ #???
+ #ca_cert_path = checker.ca_cert_path
- #pause_for_user()
- #ca_cert_path = checker.ca_cert_path
+ yield((self.tr('Validating api certificate'), 90), validatecacert)
self.set_done()
- update_signal.emit('end_sentinel', 100)
- #pause_for_user()
+ yield(('end_sentinel', 100), lambda: None)
- def _do_validation(self):
+ def on_checks_validation_ready(self):
"""
called after _do_checks has finished
(connected to checker thread finished signal)
diff --git a/src/leap/gui/firstrun/register.py b/src/leap/gui/firstrun/register.py
index f872a127..ddfcd1c5 100644
--- a/src/leap/gui/firstrun/register.py
+++ b/src/leap/gui/firstrun/register.py
@@ -2,7 +2,9 @@
Register User Page, used in First Run Wizard
"""
import logging
+import socket
+import requests
from PyQt4 import QtCore
from PyQt4 import QtGui
@@ -11,31 +13,34 @@ from leap.gui.firstrun.mixins import UserFormMixIn
logger = logging.getLogger(__name__)
+from leap.base import auth
from leap.gui.constants import APP_LOGO, BARE_USERNAME_REGEX
+from leap.gui.progress import InlineValidationPage
from leap.gui.styles import ErrorLabelStyleSheet
-class RegisterUserPage(QtGui.QWizardPage, UserFormMixIn):
+class RegisterUserPage(InlineValidationPage, UserFormMixIn):
def __init__(self, parent=None):
super(RegisterUserPage, self).__init__(parent)
+ self.current_page = "signup"
- self.setTitle("Sign Up")
+ self.setTitle(self.tr("Sign Up"))
+ # subtitle is set in the initializePage
self.setPixmap(
QtGui.QWizard.LogoPixmap,
QtGui.QPixmap(APP_LOGO))
- self.current_page = "signup"
-
# commit page means there's no way back after this...
# XXX should change the text on the "commit" button...
self.setCommitPage(True)
- self.initUI()
+ self.setupSteps()
+ self.setupUI()
- def initUI(self):
+ def setupUI(self):
userNameLabel = QtGui.QLabel("User &name:")
userNameLineEdit = QtGui.QLineEdit()
userNameLineEdit.cursorPositionChanged.connect(
@@ -89,8 +94,18 @@ class RegisterUserPage(QtGui.QWizardPage, UserFormMixIn):
layout.addWidget(self.userPasswordLineEdit, 2, 3)
layout.addWidget(self.userPassword2LineEdit, 3, 3)
layout.addWidget(rememberPasswordCheckBox, 4, 3, 4, 4)
+
+ # add validation frame
+ self.setupValidationFrame()
+ layout.addWidget(self.valFrame, 5, 2, 5, 2)
+ self.valFrame.hide()
+
self.setLayout(layout)
+ # change "commit" button text
+ self.setButtonText(
+ QtGui.QWizard.CommitButton, "Sign up!")
+
# pagewizard methods
def populateErrors(self):
@@ -138,9 +153,6 @@ class RegisterUserPage(QtGui.QWizardPage, UserFormMixIn):
super(RegisterUserPage, self).paintEvent(event)
self.populateErrors()
- def set_prevalidation_error(self, error):
- self.prevalidation_error = error
-
def validatePage(self):
"""
we only pre-validate here password weakness
@@ -150,33 +162,117 @@ class RegisterUserPage(QtGui.QWizardPage, UserFormMixIn):
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)
- #username = self.userNameLineEdit.text()
+ provider = self.field('provider_domain')
+ username = self.userNameLineEdit.text()
password = self.userPasswordLineEdit.text()
password2 = self.userPassword2LineEdit.text()
- # we better have here
- # some call to a password checker...
- # to assess strenght and avoid silly stuff.
-
- if password != password2:
- self.set_prevalidation_error('Password does not match.')
+ def fail():
+ self.set_undone()
return False
- if len(password) < 6:
- self.set_prevalidation_error('Password too short.')
- return False
-
- if password == "123456":
- # joking, but not too much.
- self.set_prevalidation_error('Password too obvious.')
- return False
-
- # some cleanup before we leave the page
- self.cleanup_errormsg()
-
- # go
- return True
+ 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()
+
+ if len(password) < 6:
+ #self.set_prevalidation_error('Password too short.')
+ msg = self.tr('Password too short.')
+ senderr(msg)
+ return fail()
+
+ 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()
+
+ # go
+ return True
+
+ yield(("head_sentinel", 0), checkpass)
+
+ # XXX should emit signal for .show the frame!
+ # XXX HERE!
+
+ ##################################################
+ # 1) register user
+ ##################################################
+
+ def register():
+ # XXX FIXME!
+ verify = False
+
+ signup = auth.LeapSRPRegister(
+ schema="https",
+ provider=provider,
+ verify=verify)
+ try:
+ ok, req = signup.register_user(
+ username, password)
+
+ except socket.timeout:
+ msg = self.tr("Error connecting to provider (timeout)")
+ senderr(msg)
+ return fail()
+
+ except requests.exceptions.ConnectionError as exc:
+ logger.error(exc.message)
+ msg = self.tr('Error Connecting to provider (connerr).')
+ senderr(msg)
+ return fail()
+
+ # XXX check for != OK instead???
+
+ if req.status_code in (404, 500):
+ msg = self.tr(
+ "Error during registration (%s)") % req.status_code
+ return fail()
+
+ validation_msgs = json.loads(req.content)
+ errors = validation_msgs.get('errors', None)
+ logger.debug('validation errors: %s' % validation_msgs)
+
+ 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()
+
+ logger.debug('registering user')
+ yield(("registering with provider", 40), register)
+
+ # set_done??
+ self.set_done()
+ yield(("end_sentinel", 0), lambda: None)
+
+ def on_checks_validation_ready(self):
+
+ if self.is_done():
+ self.cleanup_errormsg()
+ self.go_next()
def initializePage(self):
"""
@@ -184,7 +280,7 @@ class RegisterUserPage(QtGui.QWizardPage, UserFormMixIn):
"""
provider = self.field('provider_domain')
self.setSubTitle(
- "Register a new user with provider %s." %
+ self.tr("Register a new user with provider %s.") %
provider)
self.validationMsg.setText('')
self.userPassword2LineEdit.setText('')
diff --git a/src/leap/gui/firstrun/regvalidation.py b/src/leap/gui/firstrun/regvalidation.py
index 6db2bf6e..79971944 100644
--- a/src/leap/gui/firstrun/regvalidation.py
+++ b/src/leap/gui/firstrun/regvalidation.py
@@ -20,7 +20,7 @@ from leap.gui.progress import ValidationPage
from leap.util.web import get_https_domain_and_port
from leap.base import auth
-from leap.gui.constants import APP_LOGO, pause_for_user
+from leap.gui.constants import APP_LOGO
logger = logging.getLogger(__name__)
@@ -77,79 +77,9 @@ class RegisterUserValidationPage(ValidationPage):
pCertChecker = wizard.providercertchecker(
domain=full_domain)
- ###########################################
- # only if from signup
- # MOVE TO SIGNUP PAGE...
- if is_signup:
- signup = auth.LeapSRPRegister(
- schema="https",
- provider=full_domain,
- verify=verify)
-
update_signal.emit("head_sentinel", 0)
##################################################
- # 1) register user
- ##################################################
- # only if from signup.
- # XXX MOVE THIS STEP TO SIGNUP-IN-PLACE VALIDATION
- # WIDGET..........................................
-
- if is_signup:
-
- step = "register"
- update_signal.emit("checking availability", 20)
- update_signal.emit("registering with provider", 40)
- logger.debug('registering user')
-
- try:
- ok, req = signup.register_user(
- username, password)
-
- except socket.timeout:
- self.set_error(
- step,
- "Error connecting to provider (timeout)")
- #pause_for_user()
- return False
-
- except requests.exceptions.ConnectionError as exc:
- logger.error(exc.message)
- self.set_error(
- step,
- "Error connecting to provider "
- "(connection error)")
- # XXX we should signal a BAD step
- #pause_for_user()
- update_signal.emit("connection error!", 50)
- #pause_for_user()
- return False
-
- # XXX check for != OK instead???
-
- if req.status_code in (404, 500):
- self.set_error(
- step,
- "Error during registration (%s)" % req.status_code)
- pause_for_user()
- return False
-
- validation_msgs = json.loads(req.content)
- errors = validation_msgs.get('errors', None)
- logger.debug('validation errors: %s' % validation_msgs)
-
- if errors and errors.get('login', None):
- # XXX this sometimes catch the blank username
- # but we're not allowing that (soon)
- self.set_error(
- step,
- 'Username not available.')
- #pause_for_user()
- return False
-
- #pause_for_user()
-
- ##################################################
# 2) fetching eip service config
##################################################
@@ -202,6 +132,13 @@ class RegisterUserValidationPage(ValidationPage):
# this should be called CONNECT PAGE AGAIN.
self.run_eip_checks_for_provider_and_connect(_domain)
+ def on_checks_validation_ready(self):
+ """
+ called after _do_checks has finished
+ (connected to checker thread finished signal)
+ """
+ pass
+
def run_eip_checks_for_provider_and_connect(self, domain):
wizard = self.wizard()
conductor = wizard.conductor
diff --git a/src/leap/gui/firstrun/wizard.py b/src/leap/gui/firstrun/wizard.py
index 4a72177e..2ee1947a 100755
--- a/src/leap/gui/firstrun/wizard.py
+++ b/src/leap/gui/firstrun/wizard.py
@@ -139,6 +139,7 @@ class FirstRunWizard(QtGui.QWizard):
# set options
self.setOption(QtGui.QWizard.IndependentPages, on=False)
+ self.setOption(QtGui.QWizard.NoBackButtonOnStartPage, on=True)
self.setWindowTitle("First Run Wizard")