diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/gui/firstrun/login.py | 118 | ||||
| -rw-r--r-- | src/leap/gui/firstrun/providersetup.py | 75 | ||||
| -rw-r--r-- | src/leap/gui/firstrun/regvalidation.py | 150 | 
3 files changed, 230 insertions, 113 deletions
| diff --git a/src/leap/gui/firstrun/login.py b/src/leap/gui/firstrun/login.py index ae4b23c6..4271c774 100644 --- a/src/leap/gui/firstrun/login.py +++ b/src/leap/gui/firstrun/login.py @@ -4,7 +4,7 @@ LogIn Page, used inf First Run Wizard  from PyQt4 import QtCore  from PyQt4 import QtGui -import requests +#import requests  from leap.gui.firstrun.mixins import UserFormMixIn @@ -18,6 +18,7 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):          self.setTitle("Log In")          self.setSubTitle("Log in with your credentials.") +        self.current_page = "login"          self.setPixmap(              QtGui.QWizard.LogoPixmap, @@ -68,30 +69,89 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):      # pagewizard methods +    #### begin possible refactor + +    def populateErrors(self): +        # XXX could move this to ValidationMixin +        # used in providerselect and register too + +        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() + +            if bad_str is None: +                # first time we fall here. +                # save the current bad_string value +                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) +                else: +                    showerr('') + +    def cleanup_errormsg(self): +        """ +        we reset bad_string to None +        should be called before leaving the page +        """ +        self.bad_string = None + +    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(LogInPage, self).paintEvent(event) +        self.populateErrors() + +    def set_prevalidation_error(self, error): +        self.prevalidation_error = error + +    #### end possible refactor +      def nextId(self):          wizard = self.wizard()          if not wizard:              return -        if wizard.is_provider_setup is True: -            next_ = 'connecting'          if wizard.is_provider_setup is False: -            next_ = 'providersetup' +            next_ = 'providersetupvalidation' +        if wizard.is_provider_setup is True: +            # XXX bad name, ok, gonna change that +            next_ = 'signupvalidation'          return wizard.get_page_index(next_)      def initializePage(self): +        super(LogInPage, self).initializePage()          self.userNameLineEdit.setText('username@provider.example.org')          self.userNameLineEdit.cursorPositionChanged.connect(              self.onUserNameEdit)          self.initial_username_sample = True      def validatePage(self): -        wizard = self.wizard() -        eipconfigchecker = wizard.eipconfigchecker() +        #wizard = self.wizard() +        #eipconfigchecker = wizard.eipconfigchecker()          full_username = self.userNameLineEdit.text()          password = self.userPasswordLineEdit.text()          if full_username.count('@') != 1: -            self.set_validation_status( +            self.set_prevalidation_error(                  "Username must be in the username@provider form.")              return False @@ -100,33 +160,33 @@ class LogInPage(QtGui.QWizardPage, UserFormMixIn):          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) - +        #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) - -        # XXX validate user? or we leave that for later? -        # I think the best thing to do for that is -        # continue to provider setup page, and if -        # we catch authentication error there, redirect -        # again to this page (by clicking "next" to -        # come here). -        # Rationale is that we need to verify server certs -        # and so on. - -        # mark that we came from login page. +        #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) +        #################################################### + +        # XXX I think this is not needed +        # since we're also checking for the is_signup field.          self.wizard().from_login = True +        # some cleanup before we leave the page +        self.cleanup_errormsg() +          return True diff --git a/src/leap/gui/firstrun/providersetup.py b/src/leap/gui/firstrun/providersetup.py index a1710a3a..3fb9a19b 100644 --- a/src/leap/gui/firstrun/providersetup.py +++ b/src/leap/gui/firstrun/providersetup.py @@ -2,17 +2,24 @@  Provider Setup Validation Page,  used if First Run Wizard  """ +import logging  from PyQt4 import QtGui +from leap.base import auth  from leap.gui.progress import ValidationPage  from leap.gui.constants import APP_LOGO, pause_for_user +logger = logging.getLogger(__name__) +  class ProviderSetupValidationPage(ValidationPage):      def __init__(self, parent=None):          super(ProviderSetupValidationPage, self).__init__(parent) +        is_signup = self.field("is_signup") +        self.is_signup = is_signup +          self.setTitle("Setting up provider")          #self.setSubTitle(              #"auto configuring provider...") @@ -25,14 +32,56 @@ class ProviderSetupValidationPage(ValidationPage):          """          executes actual checks in a separate thread          """ -        domain = self.field('provider_domain') +        full_domain = self.field('provider_domain')          wizard = self.wizard()          pconfig = wizard.providerconfig -        pCertChecker = wizard.providercertchecker -        certchecker = pCertChecker(domain=domain) +        #pCertChecker = wizard.providercertchecker +        #certchecker = pCertChecker(domain=full_domain) +        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) + +            step = "fetch_eipcert" +            update_signal.emit('validating credentials', 20) + +            unamek = 'login_userName' +            passwk = 'login_userPassword' + +            username = self.field(unamek) +            password = self.field(passwk) +            credentials = username, password + +            ################# +            # FIXME #BUG #638 +            verify = False + +            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 + +            pause_for_user() + +        ####################################### +          update_signal.emit('Fetching CA certificate', 30)          pause_for_user() @@ -48,7 +97,7 @@ class ProviderSetupValidationPage(ValidationPage):          # (Check with the trusted fingerprints dict          # or something smart) -        certchecker.download_ca_cert( +        pCertChecker.download_ca_cert(              uri=ca_cert_uri,              verify=False)          pause_for_user() @@ -59,7 +108,7 @@ class ProviderSetupValidationPage(ValidationPage):          # XXX get fingerprint dict (types)          #sha256_fpr = ca_cert_fingerprint.split('=')[1] -        #validate_fpr = certchecker.check_ca_cert_fingerprint( +        #validate_fpr = pCertChecker.check_ca_cert_fingerprint(              #fingerprint=sha256_fpr)          #if not validate_fpr:              # XXX update validationMsg @@ -70,7 +119,7 @@ class ProviderSetupValidationPage(ValidationPage):          #api_uri = pconfig.get('api_uri', None)          #try: -            #api_cert_verified = certchecker.verify_api_https(api_uri) +            #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 @@ -95,15 +144,18 @@ class ProviderSetupValidationPage(ValidationPage):          called after _do_checks has finished          (connected to checker thread finished signal)          """ +        prevpage = "providerselection" if self.is_signup else "login"          wizard = self.wizard() +          if self.errors: -            print 'going back with errors' +            logger.debug('going back with errors') +            name, first_error = self.pop_first_error()              wizard.set_validation_error( -                'providerselection', -                'error on provider setup') +                prevpage, +                first_error)              self.go_back()          else: -            print 'going next' +            logger.debug('going next')              self.go_next()      def nextId(self): @@ -114,5 +166,6 @@ class ProviderSetupValidationPage(ValidationPage):          if is_signup is True:              next_ = 'signup'          if is_signup is False: -            next_ = 'connecting' +            # XXX bad name. change to connect again. +            next_ = 'signupvalidation'          return wizard.get_page_index(next_) diff --git a/src/leap/gui/firstrun/regvalidation.py b/src/leap/gui/firstrun/regvalidation.py index b1308051..e85c2ac6 100644 --- a/src/leap/gui/firstrun/regvalidation.py +++ b/src/leap/gui/firstrun/regvalidation.py @@ -28,15 +28,20 @@ logger = logging.getLogger(__name__)  class RegisterUserValidationPage(ValidationPage):      def __init__(self, parent=None): -        # XXX TODO: -        # We should check if we come from signup -        # or login, and change title / first step -        # accordingly. -          super(RegisterUserValidationPage, self).__init__(parent) -        self.setTitle("User Creation") -        self.setSubTitle( -            "Registering account with provider.") +        is_signup = self.field("is_signup") +        self.is_signup = is_signup + +        if is_signup: +            title = "User Creation" +            subtitle = "Registering account with provider." +        else: +            title = "Connecting..." +            # XXX uh... really? +            subtitle = "Checking connection with provider." + +        self.setTitle(title) +        self.setSubTitle(subtitle)          self.setPixmap(              QtGui.QWizard.LogoPixmap, @@ -61,12 +66,12 @@ class RegisterUserValidationPage(ValidationPage):          # Set Credentials.          # username and password are in different fields          # if they were stored in log_in or sign_up pages. +        is_signup = self.is_signup -        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 +        unamek = 'login_%s' % unamek_base if not is_signup else unamek_base +        passwk = 'login_%s' % passwk_base if not is_signup else passwk_base          username = self.field(unamek)          password = self.field(passwk) @@ -77,73 +82,73 @@ class RegisterUserValidationPage(ValidationPage):              domain=full_domain)          ########################################### -        # XXX this only should be setup -        # if not from_login. - -        signup = auth.LeapSRPRegister( -            schema="https", -            provider=full_domain, -            verify=verify) +        # only if from signup +        if is_signup: +            signup = auth.LeapSRPRegister( +                schema="https", +                provider=full_domain, +                verify=verify)          update_signal.emit("head_sentinel", 0)          ##################################################          # 1) register user          ################################################## -        # XXX this only should be DONE -        # if NOT from_login. - -        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) +        # only if from signup. + +        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 -        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 @@ -168,7 +173,7 @@ class RegisterUserValidationPage(ValidationPage):          ##################################################          # 3) 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) @@ -233,8 +238,7 @@ class RegisterUserValidationPage(ValidationPage):          called after _do_checks has finished          (connected to checker thread finished signal)          """ -        is_signup = self.field("is_signup") -        prevpage = "signup" if is_signup else "login" +        prevpage = "signup" if self.is_signup else "login"          wizard = self.wizard()          if self.errors: | 
