summaryrefslogtreecommitdiff
path: root/src/leap/gui/firstrun/providerselect.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/gui/firstrun/providerselect.py')
-rw-r--r--src/leap/gui/firstrun/providerselect.py475
1 files changed, 0 insertions, 475 deletions
diff --git a/src/leap/gui/firstrun/providerselect.py b/src/leap/gui/firstrun/providerselect.py
deleted file mode 100644
index 36bb4510..00000000
--- a/src/leap/gui/firstrun/providerselect.py
+++ /dev/null
@@ -1,475 +0,0 @@
-"""
-Select Provider Page, used in First Run Wizard
-"""
-import logging
-
-import requests
-
-from PyQt4 import QtCore
-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.progress import InlineValidationPage
-from leap.gui import styles
-from leap.gui.utils import delay
-from leap.util.web import get_https_domain_and_port
-
-from leap.gui.constants import APP_LOGO, APP_WATERMARK
-
-logger = logging.getLogger(__name__)
-
-
-class SelectProviderPage(InlineValidationPage):
-
- launchChecks = QtCore.pyqtSignal()
-
- 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(
- "Please enter the domain of the provider you want "
- "to use for your connection")
- )
- self.setPixmap(
- QtGui.QWizard.WatermarkPixmap,
- QtGui.QPixmap(APP_WATERMARK))
-
- self.setPixmap(
- QtGui.QWizard.LogoPixmap,
- QtGui.QPixmap(APP_LOGO))
-
- self.did_cert_check = False
-
- self.done = False
-
- self.setupSteps()
- self.setupUI()
-
- self.launchChecks.connect(
- self.launch_checks)
-
- self.providerNameEdit.editingFinished.connect(
- lambda: self.providerCheckButton.setFocus(True))
-
- def setupUI(self):
- """
- initializes the UI
- """
- providerNameLabel = QtGui.QLabel("h&ttps://")
- # note that we expect the bare domain name
- # we will add the scheme later
- providerNameEdit = QtGui.QLineEdit()
- providerNameEdit.cursorPositionChanged.connect(
- self.reset_validation_status)
- providerNameLabel.setBuddy(providerNameEdit)
-
- # add regex validator
- providerDomainRe = QtCore.QRegExp(r"^[a-z1-9_\-\.]+$")
- providerNameEdit.setValidator(
- QtGui.QRegExpValidator(providerDomainRe, self))
- self.providerNameEdit = providerNameEdit
-
- # Eventually we will seed a list of
- # well known providers here.
-
- #providercombo = QtGui.QComboBox()
- #if providers:
- #for provider in providers:
- #providercombo.addItem(provider)
- #providerNameSelect = providercombo
-
- self.registerField("provider_domain*", self.providerNameEdit)
- #self.registerField('provider_name_index', providerNameSelect)
-
- validationMsg = QtGui.QLabel("")
- validationMsg.setStyleSheet(styles.ErrorLabelStyleSheet)
- self.validationMsg = validationMsg
- providerCheckButton = QtGui.QPushButton(self.tr("chec&k!"))
- self.providerCheckButton = providerCheckButton
-
- # cert info
-
- # this is used in the callback
- # for the checkbox changes.
- # tricky, since the first time came
- # from the exception message.
- # should get string from exception too!
- self.bad_cert_status = self.tr(
- "Server certificate could not be verified.")
-
- self.certInfo = QtGui.QLabel("")
- self.certInfo.setWordWrap(True)
- self.certWarning = QtGui.QLabel("")
- self.trustProviderCertCheckBox = QtGui.QCheckBox(
- self.tr("&Trust this provider certificate."))
-
- self.trustProviderCertCheckBox.stateChanged.connect(
- self.onTrustCheckChanged)
- self.providerNameEdit.textChanged.connect(
- self.onProviderChanged)
- self.providerCheckButton.clicked.connect(
- self.onCheckButtonClicked)
-
- layout = QtGui.QGridLayout()
- layout.addWidget(validationMsg, 0, 2)
- layout.addWidget(providerNameLabel, 1, 1)
- layout.addWidget(providerNameEdit, 1, 2)
- layout.addWidget(providerCheckButton, 1, 3)
-
- # add certinfo group
- # XXX not shown now. should move to validation box.
- #layout.addWidget(certinfoGroup, 4, 1, 4, 2)
- #self.certinfoGroup = certinfoGroup
- #self.certinfoGroup.hide()
-
- # add validation frame
- self.setupValidationFrame()
- layout.addWidget(self.valFrame, 4, 2, 4, 2)
- self.valFrame.hide()
-
- self.setLayout(layout)
-
- # certinfo
-
- def setupCertInfoGroup(self): # pragma: no cover
- # XXX not used now.
- certinfoGroup = QtGui.QGroupBox(
- self.tr("Certificate validation"))
- certinfoLayout = QtGui.QVBoxLayout()
- certinfoLayout.addWidget(self.certInfo)
- certinfoLayout.addWidget(self.certWarning)
- certinfoLayout.addWidget(self.trustProviderCertCheckBox)
- certinfoGroup.setLayout(certinfoLayout)
- self.certinfoGroup = self.certinfoGroup
-
- # progress frame
-
- def setupValidationFrame(self):
- qframe = QtGui.QFrame
- valFrame = qframe()
- valFrame.setFrameStyle(qframe.NoFrame)
- valframeLayout = QtGui.QVBoxLayout()
- zeros = (0, 0, 0, 0)
- valframeLayout.setContentsMargins(*zeros)
-
- valframeLayout.addWidget(self.stepsTableWidget)
- valFrame.setLayout(valframeLayout)
- self.valFrame = valFrame
-
- @QtCore.pyqtSlot()
- def onDisableCheckButton(self):
- #print 'CHECK BUTTON DISABLED!!!'
- self.providerCheckButton.setDisabled(True)
-
- @QtCore.pyqtSlot()
- def launch_checks(self):
- self.do_checks()
-
- def onCheckButtonClicked(self):
- QtCore.QMetaObject.invokeMethod(
- self, "onDisableCheckButton")
-
- QtCore.QMetaObject.invokeMethod(
- self, "showStepsFrame")
-
- delay(self, "launch_checks")
-
- def _do_checks(self):
- """
- generator that yields actual checks
- that are executed in a separate thread
- """
-
- wizard = self.wizard()
- full_domain = self.providerNameEdit.text()
-
- # 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)
-
- netchecker = wizard.netchecker()
- providercertchecker = wizard.providercertchecker()
- eipconfigchecker = wizard.eipconfigchecker(domain=_domain)
-
- yield(("head_sentinel", 0), lambda: None)
-
- ########################
- # 1) try name resolution
- ########################
-
- def namecheck():
- """
- in which we check if
- we are able to name resolve
- this domain
- """
- try:
- #import ipdb;ipdb.set_trace()
- netchecker.check_name_resolution(
- domain)
-
- except baseexceptions.LeapException as exc:
- logger.error(exc.message)
- return self.fail(exc.usermessage)
-
- except Exception as exc:
- return self.fail(exc.message)
-
- else:
- return True
-
- logger.debug('checking name resolution')
- yield((self.tr("Checking if it is a valid provider"), 20), namecheck)
-
- #########################
- # 2) try https connection
- #########################
-
- def httpscheck():
- """
- in which we check
- if the provider
- is offering service over
- https
- """
- try:
- providercertchecker.is_https_working(
- "https://%s" % _domain,
- verify=True)
-
- except eipexceptions.HttpsBadCertError as exc:
- logger.debug('exception')
- return self.fail(exc.usermessage)
- # XXX skipping for now...
- ##############################################
- # We had this validation logic
- # in the provider selection page before
- ##############################################
- #if self.trustProviderCertCheckBox.isChecked():
- #pass
- #else:
- #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
-
- except baseexceptions.LeapException as exc:
- return self.fail(exc.usermessage)
-
- except Exception as exc:
- return self.fail(exc.message)
-
- else:
- return True
-
- logger.debug('checking https connection')
- yield((self.tr("Checking for a secure connection"), 40), httpscheck)
-
- ##################################
- # 3) try download provider info...
- ##################################
-
- def fetchinfo():
- 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)
- except requests.exceptions.SSLError:
- return self.fail(self.tr(
- "Could not get info from provider."))
- except requests.exceptions.ConnectionError:
- return self.fail(self.tr(
- "Could not download provider info "
- "(refused conn.)."))
-
- except Exception as exc:
- return self.fail(
- self.tr(exc.message))
- else:
- return True
-
- yield((self.tr("Getting info from the provider"), 80), fetchinfo)
-
- # done!
-
- self.done = True
- yield(("end_sentinel", 100), lambda: None)
-
- def on_checks_validation_ready(self):
- """
- called after _do_checks has finished.
- """
- self.domain_checked = True
- self.completeChanged.emit()
- # let's set focus...
- if self.is_done():
- self.wizard().clean_validation_error(self.current_page)
- nextbutton = self.wizard().button(QtGui.QWizard.NextButton)
- nextbutton.setFocus()
- else:
- self.providerNameEdit.setFocus()
-
- # cert trust verification
- # (disabled for now)
-
- def is_insecure_cert_trusted(self):
- return self.trustProviderCertCheckBox.isChecked()
-
- def onTrustCheckChanged(self, state): # pragma: no cover XXX
- checked = False
- if state == 2:
- checked = True
-
- if checked:
- self.reset_validation_status()
- else:
- self.set_validation_status(self.bad_cert_status)
-
- # trigger signal to redraw next button
- self.completeChanged.emit()
-
- def add_cert_info(self, certinfo): # pragma: no cover XXX
- self.certWarning.setText(
- self.tr("Do you want to <b>trust this provider certificate?</b>"))
- # XXX Check if this needs to abstracted to remove certinfo
- self.certInfo.setText(
- self.tr('SHA-256 fingerprint: <i>%s</i><br>' % certinfo))
- self.certInfo.setWordWrap(True)
- self.certinfoGroup.show()
-
- def onProviderChanged(self, text):
- self.done = False
- provider = self.providerNameEdit.text()
- if provider:
- self.providerCheckButton.setDisabled(False)
- else:
- self.providerCheckButton.setDisabled(True)
- self.completeChanged.emit()
-
- def reset_validation_status(self):
- """
- empty the validation msg
- and clean the inline validation widget.
- """
- self.validationMsg.setText('')
- self.steps.removeAllSteps()
- self.clearTable()
- self.domain_checked = False
-
- # pagewizard methods
-
- def isComplete(self):
- provider = self.providerNameEdit.text()
-
- if not self.is_done():
- return False
-
- if not provider:
- return False
- else:
- if self.is_insecure_cert_trusted():
- return True
- if not self.did_cert_check:
- if self.is_done():
- # XXX sure?
- return True
- return False
-
- def populateErrors(self):
- # XXX could move this to ValidationMixin
- # with some defaults for the validating fields
- # (now it only allows one field, manually specified)
-
- #logger.debug('getting errors')
- errors = self.wizard().get_validation_error(
- self.current_page)
- if errors:
- bad_str = getattr(self, 'bad_string', None)
- cur_str = self.providerNameEdit.text()
- showerr = self.validationMsg.setText
- markred = lambda: self.providerNameEdit.setStyleSheet(
- styles.ErrorLineEdit)
- umarkrd = lambda: self.providerNameEdit.setStyleSheet(
- styles.RegularLineEdit)
- if bad_str is None:
- # first time we fall here.
- # save the current bad_string value
- self.bad_string = cur_str
- showerr(errors)
- markred()
- else:
- # not the first time
- # XXX hey, this is getting convoluted.
- # roll out this.
- # but be careful about all the possibilities
- # with going back and forth once you
- # enter a domain.
- if cur_str == bad_str:
- showerr(errors)
- markred()
- else:
- if not getattr(self, 'domain_checked', None):
- showerr('')
- umarkrd()
- else:
- self.bad_string = cur_str
- showerr(errors)
-
- def cleanup_errormsg(self):
- """
- we reset bad_string to None
- should be called before leaving the page
- """
- self.bad_string = None
- self.domain_checked = False
-
- 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(SelectProviderPage, self).paintEvent(event)
- self.populateErrors()
-
- def initializePage(self):
- self.validationMsg.setText('')
- if hasattr(self, 'certinfoGroup'):
- # XXX remove ?
- self.certinfoGroup.hide()
- self.done = False
- self.providerCheckButton.setDisabled(True)
- self.valFrame.hide()
- self.steps.removeAllSteps()
- self.clearTable()
-
- def validatePage(self):
- # some cleanup before we leave the page
- self.cleanup_errormsg()
-
- # go
- return True
-
- def nextId(self):
- wizard = self.wizard()
- if not wizard:
- return
- return wizard.get_page_index('providerinfo')