"""
Select Provider Page, used in First Run Wizard
"""
import logging
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.constants import APP_LOGO
from leap.gui.styles import ErrorLabelStyleSheet
logger = logging.getLogger(__name__)
class SelectProviderPage(QtGui.QWizardPage):
def __init__(self, parent=None, providers=None):
super(SelectProviderPage, self).__init__(parent)
self.setTitle("Enter Provider")
self.setSubTitle(
"Please enter the domain of the provider you want "
"to use for your connection."
)
self.setPixmap(
QtGui.QWizard.LogoPixmap,
QtGui.QPixmap(APP_LOGO))
self.did_cert_check = False
self.current_page = 'providerselection'
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-z\d_-.]+$")
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(ErrorLabelStyleSheet)
self.validationMsg = validationMsg
# 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 = "Server certificate could not be verified."
self.certInfo = QtGui.QLabel("")
self.certInfo.setWordWrap(True)
self.certWarning = QtGui.QLabel("")
self.trustProviderCertCheckBox = QtGui.QCheckBox(
"&Trust this provider certificate.")
self.trustProviderCertCheckBox.stateChanged.connect(
self.onTrustCheckChanged)
self.providerNameEdit.textChanged.connect(
self.onProviderChanged)
layout = QtGui.QGridLayout()
layout.addWidget(validationMsg, 0, 2)
layout.addWidget(providerNameLabel, 1, 1)
layout.addWidget(providerNameEdit, 1, 2)
# XXX get a groupbox or something....
certinfoGroup = QtGui.QGroupBox("Certificate validation")
certinfoLayout = QtGui.QVBoxLayout()
certinfoLayout.addWidget(self.certInfo)
certinfoLayout.addWidget(self.certWarning)
certinfoLayout.addWidget(self.trustProviderCertCheckBox)
certinfoGroup.setLayout(certinfoLayout)
layout.addWidget(certinfoGroup, 4, 1, 4, 2)
self.certinfoGroup = certinfoGroup
self.certinfoGroup.hide()
self.setLayout(layout)
def is_insecure_cert_trusted(self):
return self.trustProviderCertCheckBox.isChecked()
def onTrustCheckChanged(self, state):
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 onProviderChanged(self, text):
self.completeChanged.emit()
def reset_validation_status(self):
"""
empty the validation msg
"""
self.validationMsg.setText('')
#def set_validation_status(selF, STATUS):
#self.validationMsg.setText(status)
def add_cert_info(self, certinfo):
self.certWarning.setText(
"Do you want to trust this provider certificate?")
self.certInfo.setText(
'SHA-256 fingerprint: %s
' % certinfo)
self.certInfo.setWordWrap(True)
self.certinfoGroup.show()
# pagewizard methods
def isComplete(self):
provider = self.providerNameEdit.text()
if not provider:
return False
else:
if self.is_insecure_cert_trusted():
return True
if not self.did_cert_check:
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
if bad_str is None:
# first time we fall here.
# save the current bad_string value
self.bad_string = cur_str
showerr(errors)
else:
# 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(SelectProviderPage, self).paintEvent(event)
self.populateErrors()
def initializePage(self):
self.validationMsg.setText('')
self.certinfoGroup.hide()
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')