From ad16a72f60ecc84524c22e8912df4eb8a48a2a42 Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 6 Nov 2012 16:26:10 +0900 Subject: split wizard into separate files so we don't go nuts yet. --- src/leap/gui/firstrun/providerinfo.py | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/leap/gui/firstrun/providerinfo.py (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py new file mode 100644 index 00000000..f5f5518a --- /dev/null +++ b/src/leap/gui/firstrun/providerinfo.py @@ -0,0 +1,67 @@ +""" +Provider Info Page, used in First run Wizard +""" + +from PyQt4 import QtGui + +from leap.gui.constants import APP_LOGO + + +class ProviderInfoPage(QtGui.QWizardPage): + def __init__(self, parent=None): + super(ProviderInfoPage, self).__init__(parent) + + self.setTitle("Provider Info") + self.setSubTitle("Available information about chosen provider.") + + self.setPixmap( + QtGui.QWizard.LogoPixmap, + QtGui.QPixmap(APP_LOGO)) + + displayName = QtGui.QLabel("") + description = QtGui.QLabel("") + enrollment_policy = QtGui.QLabel("") + # XXX set stylesheet... + # prettify a little bit. + # bigger fonts and so on... + self.displayName = displayName + self.description = description + self.enrollment_policy = enrollment_policy + + layout = QtGui.QGridLayout() + layout.addWidget(displayName, 0, 1) + layout.addWidget(description, 1, 1) + layout.addWidget(enrollment_policy, 2, 1) + + self.setLayout(layout) + + def initializePage(self): + # XXX move to show info... + + # XXX get multilingual objects + # directly from the config object + + lang = "en" + pconfig = self.wizard().providerconfig + + dn = pconfig.get('display_name') + display_name = dn[lang] if dn else '' + self.displayName.setText( + "%s" % display_name) + + desc = pconfig.get('description') + description_text = desc[lang] if desc else '' + self.description.setText( + "%s" % description_text) + + enroll = pconfig.get('enrollment_policy') + if enroll: + self.enrollment_policy.setText( + 'enrollment policy: %s' % enroll) + + def nextId(self): + wizard = self.wizard() + next_ = "providersetupvalidation" + return wizard.get_page_index(next_) + + -- cgit v1.2.3 From 6032f776cabcd04aa7f4e1f55a34ecfec2775e85 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 7 Nov 2012 04:48:12 +0900 Subject: changes to update_signal + Fix update + Rename + Changed signature (we update progress bar from slot now) --- src/leap/gui/firstrun/providerinfo.py | 42 ++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index f5f5518a..52b4873f 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -2,22 +2,26 @@ Provider Info Page, used in First run Wizard """ +from PyQt4 import QtCore from PyQt4 import QtGui +from leap.gui.progress import ValidationPage + from leap.gui.constants import APP_LOGO -class ProviderInfoPage(QtGui.QWizardPage): +class ProviderInfoPage(ValidationPage): def __init__(self, parent=None): super(ProviderInfoPage, self).__init__(parent) self.setTitle("Provider Info") - self.setSubTitle("Available information about chosen provider.") + #self.setSubTitle("Available information about chosen provider.") self.setPixmap( QtGui.QWizard.LogoPixmap, QtGui.QPixmap(APP_LOGO)) + def create_info_panel(self): displayName = QtGui.QLabel("") description = QtGui.QLabel("") enrollment_policy = QtGui.QLabel("") @@ -28,15 +32,18 @@ class ProviderInfoPage(QtGui.QWizardPage): self.description = description self.enrollment_policy = enrollment_policy + # this trick allows us to reparent + QtCore.QObjectCleanupHandler().add(self.layout) layout = QtGui.QGridLayout() + layout.addWidget(displayName, 0, 1) layout.addWidget(description, 1, 1) layout.addWidget(enrollment_policy, 2, 1) self.setLayout(layout) + self.update() - def initializePage(self): - # XXX move to show info... + def show_provider_info(self): # XXX get multilingual objects # directly from the config object @@ -59,9 +66,32 @@ class ProviderInfoPage(QtGui.QWizardPage): self.enrollment_policy.setText( 'enrollment policy: %s' % enroll) + def _do_checks(self, update_signal=None): + """ + executes actual checks in a separate thread + """ + import time + update_signal.emit("head_sentinel", 0) + time.sleep(0.5) + update_signal.emit("something", 10) + time.sleep(0.5) + update_signal.emit("done", 90) + time.sleep(1) + update_signal.emit("end_sentinel", 100) + time.sleep(1) + + def _do_validation(self): + """ + called after _do_checks has finished + (connected to checker thread finished signal) + """ + print 'validation...' + self.progress.hide() + self.stepsTableWidget.hide() + self.create_info_panel() + self.show_provider_info() + def nextId(self): wizard = self.wizard() next_ = "providersetupvalidation" return wizard.get_page_index(next_) - - -- cgit v1.2.3 From 63fc5b19e39072f4bda26f2649e83832d68b5000 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 7 Nov 2012 06:06:40 +0900 Subject: fix issue with refresh timing using end_sentinel as a workaround for the lack of refresh. doing a pause so user gets some feedback about what's going on. error messages on select provider page should be all covered now. --- src/leap/gui/firstrun/providerinfo.py | 126 ++++++++++++++++++++++++++++++---- 1 file changed, 114 insertions(+), 12 deletions(-) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index 52b4873f..5cc34927 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -1,14 +1,27 @@ """ Provider Info Page, used in First run Wizard """ +import logging +import time from PyQt4 import QtCore from PyQt4 import QtGui +import requests + +from leap.base import exceptions as baseexceptions +from leap.crypto import certs +from leap.eip import exceptions as eipexceptions + from leap.gui.progress import ValidationPage from leap.gui.constants import APP_LOGO +logger = logging.getLogger(__name__) + +GUI_PAUSE_FOR_USER_SECONDS = 1 +pause_for_user = lambda: time.sleep(GUI_PAUSE_FOR_USER_SECONDS) + class ProviderInfoPage(ValidationPage): def __init__(self, parent=None): @@ -70,15 +83,95 @@ class ProviderInfoPage(ValidationPage): """ executes actual checks in a separate thread """ - import time + def pause_and_finish(): + update_signal.emit("end_sentinel", 100) + pause_for_user() + + wizard = self.wizard() + prevpage = "providerselection" + netchecker = wizard.netchecker() + providercertchecker = wizard.providercertchecker() + eipconfigchecker = wizard.eipconfigchecker() + + domain = self.field('provider_domain') + update_signal.emit("head_sentinel", 0) - time.sleep(0.5) - update_signal.emit("something", 10) - time.sleep(0.5) - update_signal.emit("done", 90) - time.sleep(1) - update_signal.emit("end_sentinel", 100) - time.sleep(1) + pause_for_user() + + # 1) try name resolution + update_signal.emit("Checking that server is reachable", 20) + logger.debug('checking name resolution') + try: + netchecker.check_name_resolution( + domain) + + except baseexceptions.LeapException as exc: + logger.debug('exception') + wizard.set_validation_error( + prevpage, exc.usermessage) + pause_and_finish() + return False + + # 2) try https connection + update_signal.emit("Checking secure connection to provider", 40) + logger.debug('checking https connection') + try: + providercertchecker.is_https_working( + "https://%s" % domain, + verify=True) + + except eipexceptions.HttpsBadCertError as exc: + logger.debug('exception') + # XXX skipping for now... + ############################################## + # We had this validation logic + # in the provider selection page before + ############################################## + #if self.trustProviderCertCheckBox.isChecked(): + #pass + #else: + wizard.set_validation_error( + prevpage, exc.usermessage) + #fingerprint = certs.get_cert_fingerprint( + #domain=domain, sep=" ") + + # it's ok if we've trusted this fgprt before + #trustedcrts = wizard.trusted_certs + #if trustedcrts and fingerprint.replace(' ', '') in trustedcrts: + #pass + #else: + # let your user face panick :P + #self.add_cert_info(fingerprint) + #self.did_cert_check = True + #self.completeChanged.emit() + #return False + pause_and_finish() + return False + + except baseexceptions.LeapException as exc: + wizard.set_validation_error( + prevpage, exc.usermessage) + pause_and_finish() + return False + + # try download provider info... + update_signal.emit("Downloading provider info", 70) + try: + eipconfigchecker.fetch_definition(domain=domain) + wizard.set_providerconfig( + eipconfigchecker.defaultprovider.config) + # XXX catch errors... + except requests.exceptions.SSLError: + # XXX we should have catched this before. + # but cert checking is broken. + wizard.set_validation_error( + prevpage, + "Could not get info from provider.") + pause_and_finish() + return False + + # We're done + pause_and_finish() def _do_validation(self): """ @@ -86,10 +179,19 @@ class ProviderInfoPage(ValidationPage): (connected to checker thread finished signal) """ print 'validation...' - self.progress.hide() - self.stepsTableWidget.hide() - self.create_info_panel() - self.show_provider_info() + prevpage = "providerselection" + errors = self.wizard().get_validation_error(prevpage) + + if not errors: + self.progress.hide() + self.stepsTableWidget.hide() + self.create_info_panel() + self.show_provider_info() + + else: + logger.debug('going back with errors') + logger.debug('ERRORS: %s' % errors) + self.go_back() def nextId(self): wizard = self.wizard() -- cgit v1.2.3 From ee5928e4e066ac9f72a7dec15972817746dbc058 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 8 Nov 2012 05:10:22 +0900 Subject: allow user to specify host:port for provider selection --- src/leap/gui/firstrun/providerinfo.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index 5cc34927..06e00682 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -23,6 +23,21 @@ GUI_PAUSE_FOR_USER_SECONDS = 1 pause_for_user = lambda: time.sleep(GUI_PAUSE_FOR_USER_SECONDS) +def get_https_domain_and_port(full_domain): + """ + returns a tuple with domain and port + from a full_domain string that can + contain a colon + """ + domain_split = full_domain.split(':') + _len = len(domain_split) + if _len == 1: + domain, port = full_domain, 443 + if _len == 2: + domain, port = domain_split + return domain, port + + class ProviderInfoPage(ValidationPage): def __init__(self, parent=None): super(ProviderInfoPage, self).__init__(parent) @@ -93,12 +108,18 @@ class ProviderInfoPage(ValidationPage): providercertchecker = wizard.providercertchecker() eipconfigchecker = wizard.eipconfigchecker() - domain = self.field('provider_domain') + full_domain = self.field('provider_domain') + + # we check if we have a port in the domain string. + domain, port = get_https_domain_and_port(full_domain) + _domain = u"%s:%s" % (domain, port) if port != 443 else unicode(domain) update_signal.emit("head_sentinel", 0) pause_for_user() + ######################## # 1) try name resolution + ######################## update_signal.emit("Checking that server is reachable", 20) logger.debug('checking name resolution') try: @@ -112,12 +133,14 @@ class ProviderInfoPage(ValidationPage): pause_and_finish() return False + ######################### # 2) try https connection + ######################### update_signal.emit("Checking secure connection to provider", 40) logger.debug('checking https connection') try: providercertchecker.is_https_working( - "https://%s" % domain, + "https://%s" % _domain, verify=True) except eipexceptions.HttpsBadCertError as exc: -- cgit v1.2.3 From 6a4d0b8298e24968106007fabef16238300742cd Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 8 Nov 2012 05:15:27 +0900 Subject: catch conn error while fetching provider info --- src/leap/gui/firstrun/providerinfo.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index 06e00682..9b959602 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -177,13 +177,15 @@ class ProviderInfoPage(ValidationPage): pause_and_finish() return False - # try download provider info... + ################################## + # 3) try download provider info... + ################################## + update_signal.emit("Downloading provider info", 70) try: - eipconfigchecker.fetch_definition(domain=domain) + eipconfigchecker.fetch_definition(domain=_domain) wizard.set_providerconfig( eipconfigchecker.defaultprovider.config) - # XXX catch errors... except requests.exceptions.SSLError: # XXX we should have catched this before. # but cert checking is broken. @@ -192,8 +194,16 @@ class ProviderInfoPage(ValidationPage): "Could not get info from provider.") pause_and_finish() return False + except requests.exceptions.ConnectionError: + wizard.set_validation_error( + prevpage, + "Could not download provider info " + "(refused conn.).") + pause_and_finish() + return False + # XXX catch more errors... - # We're done + # We're done! pause_and_finish() def _do_validation(self): -- cgit v1.2.3 From 8118056a244ca74d16380ad26a70e3da40e7e401 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 9 Nov 2012 11:21:40 +0900 Subject: connect page merged into regvalidation. Flow nearly working with fake provider, except for authentication. --- src/leap/gui/firstrun/providerinfo.py | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index 9b959602..4df477a7 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -2,7 +2,6 @@ Provider Info Page, used in First run Wizard """ import logging -import time from PyQt4 import QtCore from PyQt4 import QtGui @@ -14,29 +13,12 @@ from leap.crypto import certs from leap.eip import exceptions as eipexceptions from leap.gui.progress import ValidationPage +from leap.util.web import get_https_domain_and_port -from leap.gui.constants import APP_LOGO +from leap.gui.constants import APP_LOGO, pause_for_user logger = logging.getLogger(__name__) -GUI_PAUSE_FOR_USER_SECONDS = 1 -pause_for_user = lambda: time.sleep(GUI_PAUSE_FOR_USER_SECONDS) - - -def get_https_domain_and_port(full_domain): - """ - returns a tuple with domain and port - from a full_domain string that can - contain a colon - """ - domain_split = full_domain.split(':') - _len = len(domain_split) - if _len == 1: - domain, port = full_domain, 443 - if _len == 2: - domain, port = domain_split - return domain, port - class ProviderInfoPage(ValidationPage): def __init__(self, parent=None): @@ -127,7 +109,7 @@ class ProviderInfoPage(ValidationPage): domain) except baseexceptions.LeapException as exc: - logger.debug('exception') + logger.error(exc.message) wizard.set_validation_error( prevpage, exc.usermessage) pause_and_finish() -- cgit v1.2.3 From 23c3aa67e3f109eb7d75a89caa34b90144f99efa Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 12 Nov 2012 11:48:39 +0900 Subject: fix layout on providerinfo page --- src/leap/gui/firstrun/providerinfo.py | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index 4df477a7..0c557d66 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -9,7 +9,7 @@ from PyQt4 import QtGui import requests from leap.base import exceptions as baseexceptions -from leap.crypto import certs +#from leap.crypto import certs from leap.eip import exceptions as eipexceptions from leap.gui.progress import ValidationPage @@ -32,26 +32,36 @@ class ProviderInfoPage(ValidationPage): QtGui.QPixmap(APP_LOGO)) def create_info_panel(self): + # Use stacked widget instead + # of reparenting the layout. + + self.infoWidget = QtGui.QStackedWidget() + + info = QtGui.QWidget() + layout = QtGui.QVBoxLayout() + displayName = QtGui.QLabel("") description = QtGui.QLabel("") enrollment_policy = QtGui.QLabel("") # XXX set stylesheet... # prettify a little bit. # bigger fonts and so on... - self.displayName = displayName - self.description = description - self.enrollment_policy = enrollment_policy - # this trick allows us to reparent - QtCore.QObjectCleanupHandler().add(self.layout) - layout = QtGui.QGridLayout() + layout.addWidget(displayName) + layout.addWidget(description) + layout.addWidget(enrollment_policy) + layout.addStretch(1) + + info.setLayout(layout) + self.infoWidget.addWidget(info) - layout.addWidget(displayName, 0, 1) - layout.addWidget(description, 1, 1) - layout.addWidget(enrollment_policy, 2, 1) + self.layout.addWidget(self.infoWidget) - self.setLayout(layout) - self.update() + # add refs to self to allow for + # updates. + self.displayName = displayName + self.description = description + self.enrollment_policy = enrollment_policy def show_provider_info(self): -- cgit v1.2.3 From fe16e62fa83c24d2ef379a3f9e102d336e527656 Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 12 Nov 2012 12:25:11 +0900 Subject: cleanup errors on page init and on field change --- src/leap/gui/firstrun/providerinfo.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index 0c557d66..ef3b32c1 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -31,6 +31,9 @@ class ProviderInfoPage(ValidationPage): QtGui.QWizard.LogoPixmap, QtGui.QPixmap(APP_LOGO)) + self.prev_page = "providerselection" + #self.current_page = "providerinfo" + def create_info_panel(self): # Use stacked widget instead # of reparenting the layout. -- cgit v1.2.3 From d2dcf5a1060d60c451570349a6a06ad102d6924c Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 13 Nov 2012 21:54:04 +0900 Subject: fix missing provider parameter in leapconfig objects chain --- src/leap/gui/firstrun/providerinfo.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/leap/gui/firstrun/providerinfo.py') diff --git a/src/leap/gui/firstrun/providerinfo.py b/src/leap/gui/firstrun/providerinfo.py index ef3b32c1..e642fcd0 100644 --- a/src/leap/gui/firstrun/providerinfo.py +++ b/src/leap/gui/firstrun/providerinfo.py @@ -99,9 +99,6 @@ class ProviderInfoPage(ValidationPage): wizard = self.wizard() prevpage = "providerselection" - netchecker = wizard.netchecker() - providercertchecker = wizard.providercertchecker() - eipconfigchecker = wizard.eipconfigchecker() full_domain = self.field('provider_domain') @@ -109,6 +106,10 @@ class ProviderInfoPage(ValidationPage): domain, port = get_https_domain_and_port(full_domain) _domain = u"%s:%s" % (domain, port) if port != 443 else unicode(domain) + netchecker = wizard.netchecker() + providercertchecker = wizard.providercertchecker() + eipconfigchecker = wizard.eipconfigchecker(domain=_domain) + update_signal.emit("head_sentinel", 0) pause_for_user() @@ -178,6 +179,8 @@ class ProviderInfoPage(ValidationPage): update_signal.emit("Downloading provider info", 70) try: + # XXX we already set _domain in the initialization + # so it should not be needed here. eipconfigchecker.fetch_definition(domain=_domain) wizard.set_providerconfig( eipconfigchecker.defaultprovider.config) -- cgit v1.2.3