diff options
| author | kali <kali@leap.se> | 2012-11-27 03:34:08 +0900 | 
|---|---|---|
| committer | kali <kali@leap.se> | 2012-11-27 03:43:46 +0900 | 
| commit | 1bb7e85425f2f427401cd02726c55922874a59a0 (patch) | |
| tree | a391b1a75efaf96b3b5ee096d36af27f8da90d3e /src | |
| parent | d5136a5f3b2aa8b16e8341f2eb99d05993028acf (diff) | |
login validation inline
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/gui/firstrun/last.py | 2 | ||||
| -rw-r--r-- | src/leap/gui/firstrun/login.py | 242 | ||||
| -rw-r--r-- | src/leap/gui/firstrun/providerselect.py | 4 | ||||
| -rw-r--r-- | src/leap/gui/firstrun/register.py | 11 | 
4 files changed, 165 insertions, 94 deletions
| diff --git a/src/leap/gui/firstrun/last.py b/src/leap/gui/firstrun/last.py index 13b2f548..d33d2e77 100644 --- a/src/leap/gui/firstrun/last.py +++ b/src/leap/gui/firstrun/last.py @@ -78,6 +78,8 @@ class LastPage(QtGui.QWizardPage):                      break          except GeneratorExit:              pass +        except StopIteration: +            pass      def initializePage(self):          wizard = self.wizard() diff --git a/src/leap/gui/firstrun/login.py b/src/leap/gui/firstrun/login.py index 3a6ec089..02bace86 100644 --- a/src/leap/gui/firstrun/login.py +++ b/src/leap/gui/firstrun/login.py @@ -4,20 +4,22 @@ LogIn Page, used inf First Run Wizard  from PyQt4 import QtCore  from PyQt4 import QtGui -#import requests +import requests  from leap.base import auth  from leap.gui.firstrun.mixins import UserFormMixIn +from leap.gui.progress import InlineValidationPage +from leap.gui import styles  from leap.gui.constants import APP_LOGO, FULL_USERNAME_REGEX -from leap.gui.styles import ErrorLabelStyleSheet -class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage +class LogInPage(InlineValidationPage, UserFormMixIn):  # InlineValidationPage      def __init__(self, parent=None):          super(LogInPage, self).__init__(parent) +        self.current_page = "login"          self.setTitle("Log In")          self.setSubTitle("Log in with your credentials.") @@ -27,8 +29,11 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage              QtGui.QWizard.LogoPixmap,              QtGui.QPixmap(APP_LOGO)) +        self.setupSteps()          self.setupUI() +        self.do_confirm_next = False +      def setupUI(self):          userNameLabel = QtGui.QLabel("User &name:")          userNameLineEdit = QtGui.QLineEdit() @@ -40,6 +45,9 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage          usernameRe = QtCore.QRegExp(FULL_USERNAME_REGEX)          userNameLineEdit.setValidator(              QtGui.QRegExpValidator(usernameRe, self)) + +        #userNameLineEdit.setPlaceholderText( +            #'username@provider.example.org')          self.userNameLineEdit = userNameLineEdit          userPasswordLabel = QtGui.QLabel("&Password:") @@ -55,7 +63,7 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage          layout.setColumnMinimumWidth(0, 20)          validationMsg = QtGui.QLabel("") -        validationMsg.setStyleSheet(ErrorLabelStyleSheet) +        validationMsg.setStyleSheet(styles.ErrorLabelStyleSheet)          self.validationMsg = validationMsg          layout.addWidget(validationMsg, 0, 3) @@ -64,18 +72,38 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage          layout.addWidget(userPasswordLabel, 2, 0)          layout.addWidget(self.userPasswordLineEdit, 2, 3) +        # add validation frame +        self.setupValidationFrame() +        layout.addWidget(self.valFrame, 4, 2, 4, 2) +        self.valFrame.hide() + +        self.nextText("Log in")          self.setLayout(layout)          #self.registerField('is_login_wizard') +    def nextText(self, text): +        self.setButtonText( +            QtGui.QWizard.NextButton, text) + +    def nextFocus(self): +        self.wizard().button( +            QtGui.QWizard.NextButton).setFocus() + +    def disableNextButton(self): +        self.wizard().button( +            QtGui.QWizard.NextButton).setDisabled(True) +      def onUserNameEdit(self, *args):          if self.initial_username_sample:              self.userNameLineEdit.setText('') +            # XXX set regular color              self.initial_username_sample = None -    # pagewizard methods - -    #### begin possible refactor +    def disableFields(self): +        for field in (self.userNameLineEdit, +                      self.userPasswordLineEdit): +            field.setDisabled(True)      def populateErrors(self):          # XXX could move this to ValidationMixin @@ -83,13 +111,13 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage          errors = self.wizard().get_validation_error(              self.current_page) -        prev_er = getattr(self, 'prevalidation_error', None) +        #prev_er = getattr(self, 'prevalidation_error', None)          showerr = self.validationMsg.setText -        if not errors and prev_er: -            showerr(prev_er) -            return - +        #if not errors and prev_er: +            #showerr(prev_er) +            #return +#          if errors:              bad_str = getattr(self, 'bad_string', None)              cur_str = self.userNameLineEdit.text() @@ -100,13 +128,14 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage                  self.bad_string = cur_str                  showerr(errors)              else: -                if prev_er: -                    showerr(prev_er) -                    return +                #if prev_er: +                    #showerr(prev_er) +                    #return                  # not the first time                  if cur_str == bad_str:                      showerr(errors)                  else: +                    self.focused_field = False                      showerr('')      def cleanup_errormsg(self): @@ -130,7 +159,7 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage      def set_prevalidation_error(self, error):          self.prevalidation_error = error -    #### end possible refactor +    # pagewizard methods      def nextId(self):          wizard = self.wizard() @@ -145,95 +174,115 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage      def initializePage(self):          super(LogInPage, self).initializePage() -        # XXX setPlaceholderText instead?! -        self.userNameLineEdit.setText('username@provider.example.org') -        self.userNameLineEdit.cursorPositionChanged.connect( +        username = self.userNameLineEdit +        username.setText('username@provider.example.org') +        username.cursorPositionChanged.connect(              self.onUserNameEdit)          self.initial_username_sample = True +        self.validationMsg.setText('') +        self.valFrame.hide() -    def validatePage(self): -        #wizard = self.wizard() -        #eipconfigchecker = wizard.eipconfigchecker() +    def reset_validation_status(self): +        """ +        empty the validation msg +        and clean the inline validation widget. +        """ +        self.validationMsg.setText('') +        self.steps.removeAllSteps() +        self.clearTable() -        # XXX should move to _do_checks -        full_username = self.userNameLineEdit.text() -        password = self.userPasswordLineEdit.text() -        if full_username.count('@') != 1: -            self.set_prevalidation_error( -                "Username must be in the username@provider form.") -            return False +    def validatePage(self): +        """ +        if not register done, do checks. +        if done, wait for click. +        """ +        self.disableNextButton() +        self.cleanup_errormsg() +        self.clean_wizard_errors(self.current_page) -        username, domain = full_username.split('@') -        self.setField('provider_domain', domain) -        self.setField('login_userName', username) -        self.setField('login_userPassword', password) - -        #################################################### -        # Validation logic: -        # move to provider setup page -        #################################################### -        # Able to contact domain? -        # can get definition? -        # two-by-one -        #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: -            #self.set_validation_status(exc.message[1]) -            #return False -        #except requests.exceptions.HTTPError as exc: -            #self.set_validation_status(exc.message) -            #return False -        #wizard.set_providerconfig( -            #eipconfigchecker.defaultprovider.config) -        #################################################### +        if self.do_confirm_next: +            full_username = self.userNameLineEdit.text() +            password = self.userPasswordLineEdit.text() +            username, domain = full_username.split('@') +            self.setField('provider_domain', domain) +            self.setField('login_userName', username) +            self.setField('login_userPassword', password) -        # XXX I think this is not needed -        # since we're also checking for the is_signup field. -        self.wizard().from_login = True +            return True -        # some cleanup before we leave the page -        self.cleanup_errormsg() +        if not self.is_done(): +            self.reset_validation_status() +            self.do_checks() -        return True +        return self.is_done()      def _do_checks(self):          # XXX convert this to inline          full_username = self.userNameLineEdit.text() -        password = self.userPasswordLineEdit.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() -        pCertChecker = wizard.providercertchecker( -            domain=domain) - -        curpage = "login" - -        def fail(): -            self.is_done = False -            return False +        eipconfigchecker = wizard.eipconfigchecker()          ########################          # 1) try name resolution          ######################## -        # XXX -        # bring here from validation above... +        # 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          ######################## - -        unamek = 'login_userName' -        passwk = 'login_userPassword' - -        username = self.field(unamek) -        password = self.field(passwk)          credentials = username, password +        pCertChecker = wizard.providercertchecker( +            domain=domain)          def validate_credentials():              ################# @@ -246,13 +295,36 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):  # InlineValidationPage                      verify=verify)              except auth.SRPAuthenticationError as exc: -                wizard.set_validation_error( -                    curpage, "Authentication error: %s" % exc.usermessage) -                return fail() +                return self.fail( +                    self.tr("Authentication error: %s" % exc.message))              except Exception as exc: -                wizard.set_validation_error( -                    curpage, "%s" % exc.message) -                return fail() +                return self.fail(exc.message) -        yield(('Validating credentials', 20), lambda: None) +            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 e59a23a9..3ffc6ff6 100644 --- a/src/leap/gui/firstrun/providerselect.py +++ b/src/leap/gui/firstrun/providerselect.py @@ -11,12 +11,12 @@ from PyQt4 import QtGui  from leap.base import exceptions as baseexceptions  #from leap.crypto import certs  from leap.eip import exceptions as eipexceptions - -from leap.gui.constants import APP_LOGO  from leap.gui.progress import InlineValidationPage  from leap.gui import styles  from leap.util.web import get_https_domain_and_port +from leap.gui.constants import APP_LOGO +  logger = logging.getLogger(__name__) diff --git a/src/leap/gui/firstrun/register.py b/src/leap/gui/firstrun/register.py index 7ce74892..e85723cb 100644 --- a/src/leap/gui/firstrun/register.py +++ b/src/leap/gui/firstrun/register.py @@ -163,7 +163,7 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):          if errors:              bad_str = getattr(self, 'bad_string', None)              cur_str = self.userNameLineEdit.text() -            prev_er = getattr(self, 'prevalidation_error', None) +            #prev_er = getattr(self, 'prevalidation_error', None)              if bad_str is None:                  # first time we fall here. @@ -171,9 +171,9 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):                  self.bad_string = cur_str                  showerr(errors)              else: -                if prev_er: -                    showerr(prev_er) -                    return +                #if prev_er: +                    #showerr(prev_er) +                    #return                  # not the first time                  if cur_str == bad_str:                      showerr(errors) @@ -290,7 +290,6 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):          logger.debug('registering user')          yield(("registering with provider", 40), register) -        # set_done??          self.set_done()          yield(("end_sentinel", 0), lambda: None) @@ -299,8 +298,6 @@ class RegisterUserPage(InlineValidationPage, UserFormMixIn):          after checks          """          if self.is_done(): -            # XXX should disable -            # all entry forms              self.disableFields()              self.cleanup_errormsg()              self.clean_wizard_errors(self.current_page) | 
