From dfd4ed8e7f20376756f83a1b42211c40d13cd873 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 4 Oct 2012 01:02:08 +0900 Subject: initial skeleton for wizard --- src/leap/gui/firstrunwizard.py | 191 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100755 src/leap/gui/firstrunwizard.py (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py new file mode 100755 index 00000000..25f0a769 --- /dev/null +++ b/src/leap/gui/firstrunwizard.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# This is only needed for Python v2 but is harmless for Python v3. +import sip +sip.setapi('QString', 2) +sip.setapi('QVariant', 2) + +from PyQt4 import QtGui + +# XXX change and use some other stuff. +import firstrunwizard_rc + + +class FirstRunWizard(QtGui.QWizard): + def __init__(self, parent=None, providers=None): + super(FirstRunWizard, self).__init__(parent) + + if not providers: + providers = ('springbok',) + self.providers = providers + + self.addPage(IntroPage()) + self.addPage(SelectProviderPage(providers=providers)) + + self.addPage(RegisterUserPage(wizard=self)) + #self.addPage(GlobalEIPSettings()) + self.addPage(LastPage()) + + self.setPixmap( + QtGui.QWizard.BannerPixmap, + QtGui.QPixmap(':/images/banner.png')) + self.setPixmap( + QtGui.QWizard.BackgroundPixmap, + QtGui.QPixmap(':/images/background.png')) + + self.setWindowTitle("First Run Wizard") + + def accept(self): + print 'chosen provider: ', self.get_provider() + print 'username: ', self.field('userName') + print 'password: ', self.field('userPassword') + print 'remember password: ', self.field('rememberPassword') + super(FirstRunWizard, self).accept() + # XXX we should emit a completed signal here... + # and pass a dict with options + # XXX unless one exists by default... + + def get_provider(self): + provider = self.field('provider_index') + return self.providers[provider] + + +class IntroPage(QtGui.QWizardPage): + def __init__(self, parent=None): + super(IntroPage, self).__init__(parent) + + self.setTitle("First run wizard.") + self.setPixmap( + QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(':/images/watermark1.png')) + + label = QtGui.QLabel( + "Now we will guide you through " + "some configuration that is needed before you " + "connect for the first time.

" + "If you ever need to modify this options again, " + "you can access from the 'Settings' menu in the " + "main window of the app.") + label.setWordWrap(True) + + layout = QtGui.QVBoxLayout() + layout.addWidget(label) + self.setLayout(layout) + + +class SelectProviderPage(QtGui.QWizardPage): + def __init__(self, parent=None, providers=None): + super(SelectProviderPage, self).__init__(parent) + + self.setTitle("Select Provider") + self.setSubTitle( + "Please select which provider do you want " + "to use for your connection." + ) + self.setPixmap( + QtGui.QWizard.LogoPixmap, + QtGui.QPixmap(':/images/logo1.png')) + + providerNameLabel = QtGui.QLabel("&Provider:") + + providercombo = QtGui.QComboBox() + if providers: + for provider in providers: + providercombo.addItem(provider) + providerNameSelect = providercombo + + providerNameLabel.setBuddy(providerNameSelect) + + self.registerField('provider_index', providerNameSelect) + + layout = QtGui.QGridLayout() + layout.addWidget(providerNameLabel, 0, 0) + layout.addWidget(providerNameSelect, 0, 1) + self.setLayout(layout) + + +class RegisterUserPage(QtGui.QWizardPage): + def __init__(self, parent=None, wizard=None): + super(RegisterUserPage, self).__init__(parent) + + # XXX check for no wizard pased + # getting provider from previous step + provider = wizard.get_provider() + + self.setTitle("User registration") + self.setSubTitle( + "Register a new user with provider %s." % + provider) + self.setPixmap( + QtGui.QWizard.LogoPixmap, + QtGui.QPixmap(':/images/logo2.png')) + + rememberPasswordCheckBox = QtGui.QCheckBox( + "&Remember password.") + rememberPasswordCheckBox.setChecked(True) + + userNameLabel = QtGui.QLabel("User &name:") + self.userNameLineEdit = QtGui.QLineEdit() + userNameLabel.setBuddy(self.userNameLineEdit) + + userPasswordLabel = QtGui.QLabel("&Password:") + self.userPasswordLineEdit = QtGui.QLineEdit() + self.userPasswordLineEdit.setEchoMode( + QtGui.QLineEdit.Password) + + userPasswordLabel.setBuddy(self.userPasswordLineEdit) + + self.registerField('userName', self.userNameLineEdit) + self.registerField('userPassword', self.userPasswordLineEdit) + self.registerField('rememberPassword', rememberPasswordCheckBox) + + layout = QtGui.QGridLayout() + layout.setColumnMinimumWidth(0, 20) + + layout.addWidget(userNameLabel, 0, 0) + layout.addWidget(self.userNameLineEdit, 0, 3) + + layout.addWidget(userPasswordLabel, 1, 0) + layout.addWidget(self.userPasswordLineEdit, 1, 3) + + layout.addWidget(rememberPasswordCheckBox, 2, 3, 2, 4) + self.setLayout(layout) + + # XXX how to validatioN ---- + + def initializePage(self): + pass + + +class LastPage(QtGui.QWizardPage): + def __init__(self, parent=None): + super(LastPage, self).__init__(parent) + + self.setTitle("Ready to go!") + self.setPixmap( + QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(':/images/watermark2.png')) + + self.label = QtGui.QLabel() + self.label.setWordWrap(True) + + layout = QtGui.QVBoxLayout() + layout.addWidget(self.label) + self.setLayout(layout) + + def initializePage(self): + finishText = self.wizard().buttonText( + QtGui.QWizard.FinishButton) + finishText = finishText.replace('&', '') + self.label.setText( + "Click '%s' to end the wizard and start " + "encrypting your connection." % finishText) + + +if __name__ == '__main__': + + import sys + + app = QtGui.QApplication(sys.argv) + wizard = FirstRunWizard() + wizard.show() + sys.exit(app.exec_()) -- cgit v1.2.3 From c06d7e25649cc76dfe7418a520dc823270a3191f Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 5 Oct 2012 01:59:06 +0900 Subject: add user registration to wizard validation still a bit fragile but there it is. --- src/leap/gui/firstrunwizard.py | 170 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 161 insertions(+), 9 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index 25f0a769..bf1f351c 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -9,6 +9,78 @@ from PyQt4 import QtGui # XXX change and use some other stuff. import firstrunwizard_rc +# registration ###################### +# move to base/ + +import requests +import srp + + +class LeapSRPRegister(object): + + def __init__(self, + schema="https", + provider=None, + port=None, + register_path="users.json", + method="POST", + fetcher=requests, + srp=srp, + hashfun=srp.SHA256, + ng_constant=srp.NG_1024): + + self.schema = schema + self.provider = provider + self.port = port + self.register_path = register_path + self.method = method + self.fetcher = fetcher + self.srp = srp + self.HASHFUN = hashfun + self.NG = ng_constant + + self.init_session() + + def init_session(self): + self.session = self.fetcher.session() + + def get_registration_uri(self): + # XXX assert is https! + # use urlparse + uri = "%s://%s:%s/%s" % ( + self.schema, + self.provider, + self.port, + self.register_path) + return uri + + def register_user(self, username, password, keep=False): + salt, vkey = self.srp.create_salted_verification_key( + username, + password, + self.HASHFUN, + self.NG) + + user_data = { + 'login': username, + 'password_verifier': vkey, + 'password_salt': salt} + + uri = self.get_registration_uri() + print 'post to uri: %s' % uri + # XXX get self.method + req = self.session.post(uri, data=user_data) + print req + req.raise_for_status() + return True + +###################################### + +ErrorLabelStyleSheet = """ +QLabel { color: red; + font-weight: bold} +""" + class FirstRunWizard(QtGui.QWizard): def __init__(self, parent=None, providers=None): @@ -34,10 +106,13 @@ class FirstRunWizard(QtGui.QWizard): self.setWindowTitle("First Run Wizard") + # TODO: set style for MAC / windows ... + #self.setWizardStyle() + def accept(self): print 'chosen provider: ', self.get_provider() print 'username: ', self.field('userName') - print 'password: ', self.field('userPassword') + #print 'password: ', self.field('userPassword') print 'remember password: ', self.field('rememberPassword') super(FirstRunWizard, self).accept() # XXX we should emit a completed signal here... @@ -109,6 +184,8 @@ class RegisterUserPage(QtGui.QWizardPage): # XXX check for no wizard pased # getting provider from previous step + # XXX save as self.provider, + # we will need it for validating page provider = wizard.get_provider() self.setTitle("User registration") @@ -124,7 +201,10 @@ class RegisterUserPage(QtGui.QWizardPage): rememberPasswordCheckBox.setChecked(True) userNameLabel = QtGui.QLabel("User &name:") - self.userNameLineEdit = QtGui.QLineEdit() + userNameLineEdit = QtGui.QLineEdit() + userNameLineEdit.cursorPositionChanged.connect( + self.reset_validation_status) + self.userNameLineEdit = userNameLineEdit userNameLabel.setBuddy(self.userNameLineEdit) userPasswordLabel = QtGui.QLabel("&Password:") @@ -141,19 +221,91 @@ class RegisterUserPage(QtGui.QWizardPage): layout = QtGui.QGridLayout() layout.setColumnMinimumWidth(0, 20) - layout.addWidget(userNameLabel, 0, 0) - layout.addWidget(self.userNameLineEdit, 0, 3) + validationMsg = QtGui.QLabel("") + validationMsg.setStyleSheet(ErrorLabelStyleSheet) + + self.validationMsg = validationMsg + + layout.addWidget(validationMsg, 0, 3) + + layout.addWidget(userNameLabel, 1, 0) + layout.addWidget(self.userNameLineEdit, 1, 3) - layout.addWidget(userPasswordLabel, 1, 0) - layout.addWidget(self.userPasswordLineEdit, 1, 3) + layout.addWidget(userPasswordLabel, 2, 0) + layout.addWidget(self.userPasswordLineEdit, 2, 3) - layout.addWidget(rememberPasswordCheckBox, 2, 3, 2, 4) + layout.addWidget(rememberPasswordCheckBox, 3, 3, 3, 4) self.setLayout(layout) - # XXX how to validatioN ---- + def reset_validation_status(self): + """ + empty the validation msg + """ + self.validationMsg.setText('') + + def set_status_validating(self): + """ + set validation msg to 'registering...' + """ + # XXX this is not shown, + # I guess it is because there is no delay... + self.validationMsg.setText('registering...') + + def set_status_invalid_username(self): + """ + set validation msg to + not available user + """ + self.validationMsg.setText('Username not available.') + + # overwritten methods def initializePage(self): - pass + """ + inits wizard page + """ + self.validationMsg.setText('') + + def validatePage(self): + """ + validation + we initialize the srp protocol register + and try to register user. if error + returned we write validation error msg + above the form. + """ + print 'validating page...' + self.set_status_validating() + # could move to status box maybe... + + username = self.userNameLineEdit.text() + password = self.userPasswordLineEdit.text() + + # XXX TODO -- remove debug info + # XXX get from provider info + + signup = LeapSRPRegister( + schema="http", + #provider="springbok" + provider="localhost", + port=8000 + ) + try: + valid = signup.register_user(username, password) + except requests.exceptions.HTTPError: + valid = False + # XXX use QString + # XXX line wrap + # XXX Raise Validation Labels... + # TODO catch 404, or other errors... + self.set_status_invalid_username() + + return True if valid is True else False + + +class GlobalEIPSettings(QtGui.QWizardPage): + def __init__(self, parent=None): + super(GlobalEIPSettings, self).__init__(parent) class LastPage(QtGui.QWizardPage): -- cgit v1.2.3 From a92ea6fcc5e2e10c6df6d41b52a5d98044317eba Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 5 Oct 2012 05:32:15 +0900 Subject: wizard called from main app if not run before. --- src/leap/gui/firstrunwizard.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index bf1f351c..b93dc8e9 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -1,14 +1,18 @@ #!/usr/bin/env python -# This is only needed for Python v2 but is harmless for Python v3. +import logging + import sip sip.setapi('QString', 2) sip.setapi('QVariant', 2) +from PyQt4 import QtCore from PyQt4 import QtGui # XXX change and use some other stuff. import firstrunwizard_rc +logger = logging.getLogger(__name__) + # registration ###################### # move to base/ @@ -83,13 +87,16 @@ QLabel { color: red; class FirstRunWizard(QtGui.QWizard): - def __init__(self, parent=None, providers=None): + def __init__(self, parent=None, providers=None, success_cb=None): super(FirstRunWizard, self).__init__(parent) if not providers: providers = ('springbok',) self.providers = providers + # success callback + self.success_cb = success_cb + self.addPage(IntroPage()) self.addPage(SelectProviderPage(providers=providers)) @@ -119,6 +126,14 @@ class FirstRunWizard(QtGui.QWizard): # and pass a dict with options # XXX unless one exists by default... + settings = QtCore.QSettings() + settings.setValue("FirstRunWizardDone", True) + + logger.debug('First Run Wizard Done.') + cb = self.success_cb + if cb and callable(cb): + self.success_cb() + def get_provider(self): provider = self.field('provider_index') return self.providers[provider] -- cgit v1.2.3 From b9d1b57976984d1032b3abc810f462a80fdc55aa Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 5 Oct 2012 07:00:42 +0900 Subject: focus fix for wizard --- src/leap/gui/firstrunwizard.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index b93dc8e9..cc70daab 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -88,8 +88,11 @@ QLabel { color: red; class FirstRunWizard(QtGui.QWizard): def __init__(self, parent=None, providers=None, success_cb=None): - super(FirstRunWizard, self).__init__(parent) + super(FirstRunWizard, self).__init__( + parent, + QtCore.Qt.WindowStaysOnTopHint) + # XXX hardcoded for tests if not providers: providers = ('springbok',) self.providers = providers @@ -116,6 +119,16 @@ class FirstRunWizard(QtGui.QWizard): # TODO: set style for MAC / windows ... #self.setWizardStyle() + def setWindowFlags(self, flags): + logger.debug('setting window flags') + QtGui.QWizard.setWindowFlags(self, flags) + + def focusOutEvent(self, event): + self.setFocus(True) + self.activateWindow() + self.raise_() + self.show() + def accept(self): print 'chosen provider: ', self.get_provider() print 'username: ', self.field('userName') @@ -219,8 +232,13 @@ class RegisterUserPage(QtGui.QWizardPage): userNameLineEdit = QtGui.QLineEdit() userNameLineEdit.cursorPositionChanged.connect( self.reset_validation_status) + userNameLabel.setBuddy(userNameLineEdit) + # TODO + # add validator + # usernameRe = QRegexp(r"[]") + # userNameLineEdit.setValidator( + # QRegExpValidator(usernameRe, self)) self.userNameLineEdit = userNameLineEdit - userNameLabel.setBuddy(self.userNameLineEdit) userPasswordLabel = QtGui.QLabel("&Password:") self.userPasswordLineEdit = QtGui.QLineEdit() -- cgit v1.2.3 From 54c1457af1288f7a849f888f2af4f484e5e824e4 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 5 Oct 2012 07:07:03 +0900 Subject: use leap logo --- src/leap/gui/firstrunwizard.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index cc70daab..e5a0f074 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -9,10 +9,13 @@ from PyQt4 import QtCore from PyQt4 import QtGui # XXX change and use some other stuff. -import firstrunwizard_rc +from leap.gui import mainwindow_rc +#import firstrunwizard_rc logger = logging.getLogger(__name__) +APP_LOGO = ':/images/leap-color-small.png' + # registration ###################### # move to base/ @@ -157,9 +160,9 @@ class IntroPage(QtGui.QWizardPage): super(IntroPage, self).__init__(parent) self.setTitle("First run wizard.") - self.setPixmap( - QtGui.QWizard.WatermarkPixmap, - QtGui.QPixmap(':/images/watermark1.png')) + #self.setPixmap( + #QtGui.QWizard.WatermarkPixmap, + #QtGui.QPixmap(':/images/watermark1.png')) label = QtGui.QLabel( "Now we will guide you through " @@ -186,7 +189,7 @@ class SelectProviderPage(QtGui.QWizardPage): ) self.setPixmap( QtGui.QWizard.LogoPixmap, - QtGui.QPixmap(':/images/logo1.png')) + QtGui.QPixmap(APP_LOGO)) providerNameLabel = QtGui.QLabel("&Provider:") @@ -222,7 +225,7 @@ class RegisterUserPage(QtGui.QWizardPage): provider) self.setPixmap( QtGui.QWizard.LogoPixmap, - QtGui.QPixmap(':/images/logo2.png')) + QtGui.QPixmap(APP_LOGO)) rememberPasswordCheckBox = QtGui.QCheckBox( "&Remember password.") @@ -346,9 +349,9 @@ class LastPage(QtGui.QWizardPage): super(LastPage, self).__init__(parent) self.setTitle("Ready to go!") - self.setPixmap( - QtGui.QWizard.WatermarkPixmap, - QtGui.QPixmap(':/images/watermark2.png')) + #self.setPixmap( + #QtGui.QWizard.WatermarkPixmap, + #QtGui.QPixmap(':/images/watermark2.png')) self.label = QtGui.QLabel() self.label.setWordWrap(True) -- cgit v1.2.3 From baefda49d741a6e8149233f292f92221aaf3b675 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 5 Oct 2012 07:13:48 +0900 Subject: remove prints --- src/leap/gui/firstrunwizard.py | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index e5a0f074..3b27985f 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -8,9 +8,7 @@ sip.setapi('QVariant', 2) from PyQt4 import QtCore from PyQt4 import QtGui -# XXX change and use some other stuff. from leap.gui import mainwindow_rc -#import firstrunwizard_rc logger = logging.getLogger(__name__) @@ -74,10 +72,11 @@ class LeapSRPRegister(object): 'password_salt': salt} uri = self.get_registration_uri() - print 'post to uri: %s' % uri + logger.debug('post to uri: %s' % uri) + # XXX get self.method req = self.session.post(uri, data=user_data) - print req + logger.debug(req) req.raise_for_status() return True @@ -133,14 +132,15 @@ class FirstRunWizard(QtGui.QWizard): self.show() def accept(self): - print 'chosen provider: ', self.get_provider() - print 'username: ', self.field('userName') - #print 'password: ', self.field('userPassword') - print 'remember password: ', self.field('rememberPassword') + """ + final step in the wizard. + gather the info, update settings + and call the success callback. + """ + logger.debug('chosen provider: %s', self.get_provider()) + logger.debug('username: %s', self.field('userName')) + logger.debug('remember password: %s', self.field('rememberPassword')) super(FirstRunWizard, self).accept() - # XXX we should emit a completed signal here... - # and pass a dict with options - # XXX unless one exists by default... settings = QtCore.QSettings() settings.setValue("FirstRunWizardDone", True) @@ -160,6 +160,7 @@ class IntroPage(QtGui.QWizardPage): super(IntroPage, self).__init__(parent) self.setTitle("First run wizard.") + #self.setPixmap( #QtGui.QWizard.WatermarkPixmap, #QtGui.QPixmap(':/images/watermark1.png')) @@ -171,6 +172,7 @@ class IntroPage(QtGui.QWizardPage): "If you ever need to modify this options again, " "you can access from the 'Settings' menu in the " "main window of the app.") + label.setWordWrap(True) layout = QtGui.QVBoxLayout() @@ -215,8 +217,6 @@ class RegisterUserPage(QtGui.QWizardPage): # XXX check for no wizard pased # getting provider from previous step - # XXX save as self.provider, - # we will need it for validating page provider = wizard.get_provider() self.setTitle("User registration") @@ -310,7 +310,6 @@ class RegisterUserPage(QtGui.QWizardPage): returned we write validation error msg above the form. """ - print 'validating page...' self.set_status_validating() # could move to status box maybe... @@ -330,9 +329,6 @@ class RegisterUserPage(QtGui.QWizardPage): valid = signup.register_user(username, password) except requests.exceptions.HTTPError: valid = False - # XXX use QString - # XXX line wrap - # XXX Raise Validation Labels... # TODO catch 404, or other errors... self.set_status_invalid_username() @@ -349,6 +345,7 @@ class LastPage(QtGui.QWizardPage): super(LastPage, self).__init__(parent) self.setTitle("Ready to go!") + #self.setPixmap( #QtGui.QWizard.WatermarkPixmap, #QtGui.QPixmap(':/images/watermark2.png')) -- cgit v1.2.3 From 7c659fed65f08f2b52f0320c99a456679749e3f3 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 5 Oct 2012 09:30:50 +0900 Subject: use keyring to store user password using a quite lame cryptedfile by the moment until dbus bug makes gnome-keyring usable again or we come up with the encrypted database solution. we might want to explore the option of using this python-keyring with the different native backends for win and macosx. for now: we generate a random secret that we store in the qsettings file. so, the whole thing is just to avoid plaintext stuff. for this, we could have done rot13, haha. --- src/leap/gui/firstrunwizard.py | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index 3b27985f..1012f64c 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -8,6 +8,7 @@ sip.setapi('QVariant', 2) from PyQt4 import QtCore from PyQt4 import QtGui +from leap.crypto import leapkeyring from leap.gui import mainwindow_rc logger = logging.getLogger(__name__) @@ -89,7 +90,9 @@ QLabel { color: red; class FirstRunWizard(QtGui.QWizard): - def __init__(self, parent=None, providers=None, success_cb=None): + def __init__( + self, parent=None, providers=None, + success_cb=None): super(FirstRunWizard, self).__init__( parent, QtCore.Qt.WindowStaysOnTopHint) @@ -126,6 +129,7 @@ class FirstRunWizard(QtGui.QWizard): QtGui.QWizard.setWindowFlags(self, flags) def focusOutEvent(self, event): + # needed ? self.setFocus(True) self.activateWindow() self.raise_() @@ -137,13 +141,27 @@ class FirstRunWizard(QtGui.QWizard): gather the info, update settings and call the success callback. """ - logger.debug('chosen provider: %s', self.get_provider()) - logger.debug('username: %s', self.field('userName')) - logger.debug('remember password: %s', self.field('rememberPassword')) + provider = self.get_provider() + username = self.field('userName') + password = self.field('userPassword') + remember_pass = self.field('rememberPassword') + + logger.debug('chosen provider: %s', provider) + logger.debug('username: %s', username) + logger.debug('remember password: %s', remember_pass) super(FirstRunWizard, self).accept() settings = QtCore.QSettings() settings.setValue("FirstRunWizardDone", True) + settings.setValue( + "eip_%s_username" % provider, + username) + settings.setValue("%s_remember_pass" % provider, remember_pass) + + seed = self.get_random_str(10) + settings.setValue("%s_seed" % provider, seed) + + leapkeyring.leap_set_password(username, password, seed=seed) logger.debug('First Run Wizard Done.') cb = self.success_cb @@ -154,6 +172,14 @@ class FirstRunWizard(QtGui.QWizard): provider = self.field('provider_index') return self.providers[provider] + def get_random_str(self, n): + from string import (ascii_uppercase, ascii_lowercase, digits) + from random import choice + return ''.join(choice( + ascii_uppercase + + ascii_lowercase + + digits) for x in range(n)) + class IntroPage(QtGui.QWizardPage): def __init__(self, parent=None): -- cgit v1.2.3 From 3e2eb0cb1878a9494650ea1278ef2f9211ebdaac Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 5 Oct 2012 10:10:04 +0900 Subject: add menu for running wizard at will it's still buggy in that it does not bother to stop the ongoing checks or connection. we should take care of that soon. --- src/leap/gui/firstrunwizard.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index 1012f64c..02ace77e 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -194,10 +194,10 @@ class IntroPage(QtGui.QWizardPage): label = QtGui.QLabel( "Now we will guide you through " "some configuration that is needed before you " - "connect for the first time.

" - "If you ever need to modify this options again, " - "you can access from the 'Settings' menu in the " - "main window of the app.") + "can connect for the first time.

" + "If you ever need to modify these options again, " + "you can find the wizard in the 'Settings' menu from the " + "main window of the Leap App.") label.setWordWrap(True) -- cgit v1.2.3 From f60e4bbbad22d6ae2d40abfc6f47eba1d0d7cbc8 Mon Sep 17 00:00:00 2001 From: kali Date: Sat, 6 Oct 2012 02:30:34 +0900 Subject: springbok hardcoded path for registration --- src/leap/gui/firstrunwizard.py | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index 02ace77e..d1fb77ec 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -28,7 +28,7 @@ class LeapSRPRegister(object): schema="https", provider=None, port=None, - register_path="users.json", + register_path="1/users.json", method="POST", fetcher=requests, srp=srp, @@ -53,11 +53,18 @@ class LeapSRPRegister(object): def get_registration_uri(self): # XXX assert is https! # use urlparse - uri = "%s://%s:%s/%s" % ( - self.schema, - self.provider, - self.port, - self.register_path) + if self.port: + uri = "%s://%s:%s/%s" % ( + self.schema, + self.provider, + self.port, + self.register_path) + else: + uri = "%s://%s/%s" % ( + self.schema, + self.provider, + self.register_path) + return uri def register_user(self, username, password, keep=False): @@ -68,9 +75,9 @@ class LeapSRPRegister(object): self.NG) user_data = { - 'login': username, - 'password_verifier': vkey, - 'password_salt': salt} + 'user[login]': username, + 'user[password_verifier]': vkey, + 'user[password_salt]': salt} uri = self.get_registration_uri() logger.debug('post to uri: %s' % uri) @@ -78,6 +85,8 @@ class LeapSRPRegister(object): # XXX get self.method req = self.session.post(uri, data=user_data) logger.debug(req) + logger.debug('user_data: %s', user_data) + #logger.debug('response: %s', req.text) req.raise_for_status() return True @@ -344,12 +353,14 @@ class RegisterUserPage(QtGui.QWizardPage): # XXX TODO -- remove debug info # XXX get from provider info + # XXX enforce https + # and pass a verify value signup = LeapSRPRegister( schema="http", - #provider="springbok" - provider="localhost", - port=8000 + #provider="localhost", + provider="springbok", + #port=8000 ) try: valid = signup.register_user(username, password) @@ -393,8 +404,12 @@ class LastPage(QtGui.QWizardPage): if __name__ == '__main__': - + # standalone test import sys + import logging + logging.basicConfig() + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) app = QtGui.QApplication(sys.argv) wizard = FirstRunWizard() -- cgit v1.2.3 From 9b025fe9972f686e40481d5eb03518e2fdac2d14 Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 8 Oct 2012 03:50:07 +0900 Subject: fix hexlify + add regex validator for usernames --- src/leap/gui/firstrunwizard.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index d1fb77ec..27cc01aa 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -17,6 +17,7 @@ APP_LOGO = ':/images/leap-color-small.png' # registration ###################### # move to base/ +import binascii import requests import srp @@ -76,8 +77,8 @@ class LeapSRPRegister(object): user_data = { 'user[login]': username, - 'user[password_verifier]': vkey, - 'user[password_salt]': salt} + 'user[password_verifier]': binascii.hexlify(vkey), + 'user[password_salt]': binascii.hexlify(salt)} uri = self.get_registration_uri() logger.debug('post to uri: %s' % uri) @@ -87,6 +88,7 @@ class LeapSRPRegister(object): logger.debug(req) logger.debug('user_data: %s', user_data) #logger.debug('response: %s', req.text) + # we catch it in the form req.raise_for_status() return True @@ -271,11 +273,11 @@ class RegisterUserPage(QtGui.QWizardPage): userNameLineEdit.cursorPositionChanged.connect( self.reset_validation_status) userNameLabel.setBuddy(userNameLineEdit) - # TODO - # add validator - # usernameRe = QRegexp(r"[]") - # userNameLineEdit.setValidator( - # QRegExpValidator(usernameRe, self)) + + # add regex validator + usernameRe = QtCore.QRegExp(r"^[A-Za-z\d_]+$") + userNameLineEdit.setValidator( + QtGui.QRegExpValidator(usernameRe, self)) self.userNameLineEdit = userNameLineEdit userPasswordLabel = QtGui.QLabel("&Password:") -- cgit v1.2.3 From 8a594577660d78a4f0f9d3c5f5902dff3911e010 Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 8 Oct 2012 05:53:16 +0900 Subject: catch timeout and specify kind of signup error --- src/leap/gui/firstrunwizard.py | 96 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 13 deletions(-) (limited to 'src/leap/gui/firstrunwizard.py') diff --git a/src/leap/gui/firstrunwizard.py b/src/leap/gui/firstrunwizard.py index 27cc01aa..abdff7cf 100755 --- a/src/leap/gui/firstrunwizard.py +++ b/src/leap/gui/firstrunwizard.py @@ -1,5 +1,7 @@ #!/usr/bin/env python import logging +import json +import socket import sip sip.setapi('QString', 2) @@ -22,6 +24,10 @@ import binascii import requests import srp +from leap.base import constants as baseconstants + +SIGNUP_TIMEOUT = getattr(baseconstants, 'SIGNUP_TIMEOUT', 5) + class LeapSRPRegister(object): @@ -69,6 +75,10 @@ class LeapSRPRegister(object): return uri def register_user(self, username, password, keep=False): + """ + @rtype: tuple + @rvalue: (ok, request) + """ salt, vkey = self.srp.create_salted_verification_key( username, password, @@ -84,13 +94,15 @@ class LeapSRPRegister(object): logger.debug('post to uri: %s' % uri) # XXX get self.method - req = self.session.post(uri, data=user_data) + req = self.session.post( + uri, data=user_data, + timeout=SIGNUP_TIMEOUT) logger.debug(req) logger.debug('user_data: %s', user_data) #logger.debug('response: %s', req.text) # we catch it in the form - req.raise_for_status() - return True + #req.raise_for_status() + return (req.ok, req) ###################################### @@ -101,6 +113,7 @@ QLabel { color: red; class FirstRunWizard(QtGui.QWizard): + def __init__( self, parent=None, providers=None, success_cb=None): @@ -249,9 +262,15 @@ class SelectProviderPage(QtGui.QWizardPage): class RegisterUserPage(QtGui.QWizardPage): + setSigningUpStatus = QtCore.pyqtSignal([]) + def __init__(self, parent=None, wizard=None): super(RegisterUserPage, self).__init__(parent) + # bind wizard page signals + self.setSigningUpStatus.connect( + self.set_status_validating) + # XXX check for no wizard pased # getting provider from previous step provider = wizard.get_provider() @@ -320,9 +339,15 @@ class RegisterUserPage(QtGui.QWizardPage): """ set validation msg to 'registering...' """ - # XXX this is not shown, + # XXX this is NOT WORKING. + # My guess is that, even if we are using + # signals to trigger this, it does + # not show until the validate function + # returns. # I guess it is because there is no delay... + logger.debug('registering........') self.validationMsg.setText('registering...') + # need to call update somehow??? def set_status_invalid_username(self): """ @@ -331,6 +356,27 @@ class RegisterUserPage(QtGui.QWizardPage): """ self.validationMsg.setText('Username not available.') + def set_status_server_500(self): + """ + set validation msg to + internal server error + """ + self.validationMsg.setText("Error during registration (500)") + + def set_status_timeout(self): + """ + set validation msg to + timeout + """ + self.validationMsg.setText("Error connecting to provider (timeout)") + + def set_status_unknown_error(self): + """ + set validation msg to + unknown error + """ + self.validationMsg.setText("Error during signup") + # overwritten methods def initializePage(self): @@ -347,8 +393,13 @@ class RegisterUserPage(QtGui.QWizardPage): returned we write validation error msg above the form. """ - self.set_status_validating() - # could move to status box maybe... + # the slot for this signal is not doing + # what's expected. Investigate why, + # right now we're not giving any feedback + # to the user re. what's going on. The only + # thing I can see as a workaround is setting + # a low timeout. + self.setSigningUpStatus.emit() username = self.userNameLineEdit.text() password = self.userPasswordLineEdit.text() @@ -360,18 +411,37 @@ class RegisterUserPage(QtGui.QWizardPage): signup = LeapSRPRegister( schema="http", - #provider="localhost", provider="springbok", + + #provider="localhost", + #register_path="timeout", #port=8000 ) try: - valid = signup.register_user(username, password) - except requests.exceptions.HTTPError: - valid = False - # TODO catch 404, or other errors... + ok, req = signup.register_user(username, password) + except socket.timeout: + self.set_status_timeout() + return False + + if ok: + return True + + # something went wrong. + # not registered, let's catch what. + # get timeout + # ... + if req.status_code == 500: + self.set_status_server_500() + return False + + validation_msgs = json.loads(req.content) + logger.debug('validation errors: %s' % validation_msgs) + errors = validation_msgs.get('errors', None) + if errors and errors.get('login', None): self.set_status_invalid_username() - - return True if valid is True else False + else: + self.set_status_unknown_error() + return False class GlobalEIPSettings(QtGui.QWizardPage): -- cgit v1.2.3