58
62
STRONG_COLOR = QColor(50, 205, 50)
61
class ChooseSignInPage(QWizardPage):
65
class SSOWizardPage(QWizardPage):
66
"""Root class for all wizard pages."""
68
def __init__(self, ui, controller, parent=None):
69
"""Create a new instance."""
70
QWizardPage.__init__(self, parent)
73
self.controller = controller
74
self.controller.setupUi(self)
77
# pylint: disable=C0103
79
"""Provide the next id."""
81
# pylint: enable=C0103
84
class EnhancedLineEdit(object):
85
"""Represents and enhanced lineedit.
87
This class works on an already added lineedit to the widget so
88
that we are just adding extra items to it.
91
def __init__(self, line_edit, valid_cb=lambda x: False):
92
"""Create an instance."""
93
self._line_edit = line_edit
94
layout = QHBoxLayout(self._line_edit)
96
self._line_edit.setLayout(layout)
97
self.valid_cb = valid_cb
99
self.clear_button = QPushButton(self._line_edit)
100
layout.addWidget(self.clear_button)
101
self.clear_button.setMinimumSize(16, 16)
102
self.clear_button.setVisible(False)
103
self.clear_button.setFlat(True)
104
self.clear_button.setCursor(QCursor(0))
105
self.clear_button.setIcon(QApplication.style().standardIcon(
106
QStyle.SP_MessageBoxWarning))
107
# connect the change of text to the cation that will check if the
108
# text is valid and if the icon should be shown.
109
self._line_edit.textChanged.connect(self.show_button)
111
def show_button(self, string):
112
"""Decide if we show the button or not."""
113
if not self.valid_cb(string):
114
self.clear_button.setVisible(True)
116
self.clear_button.setVisible(False)
119
class SSOWizardEnhancedEditPage(SSOWizardPage):
120
"""Page that contains enhanced line edits."""
122
def __init__(self, ui, controller, parent=None):
123
"""Create a new instance."""
124
SSOWizardPage.__init__(self, ui, controller, parent)
125
self._enhanced_edits = {}
127
def set_line_edit_validation_rule(self, edit, cb):
128
"""Set a new enhanced edit so that we can show an icon."""
129
if edit in self._enhanced_edits:
130
self._enhanced_edits[edit].valid_cb = cb
132
# create a new enhanced edit
133
enhanced_edit = EnhancedLineEdit(edit, cb)
134
self._enhanced_edits[edit] = enhanced_edit
137
class ChooseSignInPage(SSOWizardPage):
62
138
"""Widget that allows the user to choose how to sign in."""
64
140
def __init__(self, ui, controller, parent=None):
65
141
"""Create a new widget to be used."""
66
QWizardPage.__init__(self, parent)
68
self.controller = controller
70
controller.setupUi(self)
73
# pylint: disable=C0103
75
"""Provide the next id."""
77
# pylint: enable=C0103
142
SSOWizardPage.__init__(self, ui, controller, parent)
79
144
# allow to access to the different useful children
88
153
return self.ui.setup_account_button
91
class CurrentUserSignInPage(QWizardPage):
156
class CurrentUserSignInPage(SSOWizardPage):
92
157
"""Widget that allows to get the data of user to sign in."""
94
159
def __init__(self, ui, controller, parent=None):
95
160
"""Create a new widget to be used."""
96
QWizardPage.__init__(self, parent)
98
self.controller = controller
100
self.controller.setupUi(self)
161
SSOWizardPage.__init__(self, ui, controller, parent)
102
163
# allow to access to the different useful data
131
192
return self.ui.sign_in_button
134
class EmailVerificationPage(QWizardPage):
195
class EmailVerificationPage(SSOWizardPage):
135
196
"""Widget used to input the email verification code."""
137
198
def __init__(self, ui, controller, parent=None):
138
199
"""Create a new widget to be used."""
139
QWizardPage.__init__(self, parent)
141
self.ui.setupUi(self)
142
self.controller = controller
143
self.controller.setupUi(self)
200
SSOWizardPage.__init__(self, ui, controller, parent)
146
203
def verification_code(self):
158
215
return self.ui.next_button
161
class ErrorPage(QWizardPage):
218
class ErrorPage(SSOWizardPage):
162
219
"""Widget used to show the diff errors."""
164
221
def __init__(self, ui, controller, parent=None):
165
222
"""Create a new widget to be used."""
166
QWizardPage.__init__(self, parent)
223
SSOWizardPage.__init__(self, ui, controller, parent)
168
225
self.ui.setupUi(self)
169
226
self.controller = controller
182
239
return self.ui.error_message_label
185
class TosPage(QWizardPage):
242
class ForgottenPasswordPage(SSOWizardEnhancedEditPage):
243
"""Widget used to deal with users that forgot the password."""
245
def __init__(self, ui, controller, parent=None):
246
"""Create a new instance."""
247
SSOWizardEnhancedEditPage.__init__(self, ui, controller, parent)
250
def email_widget(self):
251
"""Return the widget used to show the email information."""
252
return self.ui.email_widget
255
def forgotted_password_intro_label(self):
256
"""Return the intro label that lets the user know the issue."""
257
return self.ui.forgotted_password_intro_label
260
def error_label(self):
261
"""Return the label used to show error."""
262
return self.ui.error_label
265
def email_address_label(self):
266
"""Return the lable used to state the use of the line edit."""
267
return self.ui.email_address_label
270
def email_address(self):
271
"""Return the email address provided by the user."""
272
return str(self.ui.email_line_edit.text())
275
def email_address_line_edit(self):
276
"""Return the line edit with the content."""
277
return self.ui.email_line_edit
280
def send_button(self):
281
"""Return the button used to request the new password."""
282
return self.ui.send_button
285
def try_again_widget(self):
286
"""Return the widget used to display the try again button."""
287
return self.ui.try_again_widget
290
def try_again_button(self):
291
"""Return the button used to try again the reset password."""
292
return self.ui.try_again_button
295
class ResetPasswordPage(SSOWizardEnhancedEditPage):
296
"""Widget used to allow the user change his password."""
298
def __init__(self, ui, controller, parent=None):
299
"""Create a new instance."""
300
SSOWizardEnhancedEditPage.__init__(self, ui, controller, parent)
303
def reset_code_line_edit(self):
304
"""Return the line edit where the reset code is given."""
305
return self.ui.reset_code_line_edit
308
def reset_code(self):
309
"""Return the reset code typed by the user."""
310
return str(self.ui.reset_code_line_edit.text())
313
def password_line_edit(self):
314
"""Return the line edit where the password is typed."""
315
return self.ui.password_line_edit
319
"""Return the passsword typed by the user."""
320
return str(self.ui.password_line_edit.text())
323
def confirm_password_line_edit(self):
324
"""Return the line edit used to confirm the password."""
325
return self.ui.confirm_password_line_edit
328
def retyped_password(self):
329
"""Return the password confirmation given by the user."""
330
return str(self.ui.confirm_password_line_edit.text())
333
def reset_password_button(self):
334
"""Return the button used to reset the password."""
335
return self.ui.reset_password_button
338
class TosPage(SSOWizardPage):
186
339
"""Widget used to show the tos."""
188
341
def __init__(self, ui, controller, parent=None):
189
342
"""Create a new instance."""
190
QWizardPage.__init__(self, parent)
192
self.ui.setupUi(self)
193
self.controller = controller
194
self.controller.setupUi(self)
196
# pylint: disable=C0103
198
"""Return the next page id."""
200
# pylint: enable=C0103
343
SSOWizardPage.__init__(self, ui, controller, parent)
203
346
def webkit(self):
205
348
return self.ui.terms_webkit
208
class EnhancedLineEdit(object):
209
"""Represents an enhanced lineedit.
211
This class works on an already added lineedit to the widget so
212
that we are just adding extra items to it.
215
def __init__(self, line_edit, valid_cb=lambda x: False):
216
"""Create an instance."""
217
self._line_edit = line_edit
218
layout = QHBoxLayout(self._line_edit)
220
self._line_edit.setLayout(layout)
221
self.valid_cb = valid_cb
223
self.clear_button = QPushButton(self._line_edit)
224
layout.addWidget(self.clear_button)
225
self.clear_button.setMinimumSize(16, 16)
226
self.clear_button.setVisible(False)
227
self.clear_button.setFlat(True)
228
self.clear_button.setCursor(QCursor(0))
229
self.clear_button.setIcon(QApplication.style().standardIcon(
230
QStyle.SP_MessageBoxWarning))
231
# connect the change of text to the callback that will check if the
232
# text is valid and if the icon should be shown.
233
self._line_edit.textChanged.connect(self.show_button)
235
def show_button(self, string):
236
"""Decide if we show the button or not."""
237
if not self.valid_cb(string):
238
self.clear_button.setVisible(True)
240
self.clear_button.setVisible(False)
243
class SetupAccountPage(QWizardPage):
351
class SetupAccountPage(SSOWizardEnhancedEditPage):
244
352
"""Widget used to create a new account."""
246
354
def __init__(self, ui, controller, parent=None):
247
355
"""Create a new widget to be used."""
248
QWizardPage.__init__(self, parent)
356
SSOWizardEnhancedEditPage.__init__(self, ui, controller, parent)
249
357
self._enhanced_edits = {}
251
359
self.ui.setupUi(self)
252
360
# palettes that will be used to set the colors of the password strength
253
361
original_palette = self.ui.strength_frame.palette()
254
362
self._original_color = original_palette.background().color()
256
363
self.captcha_id = None
257
364
self.captcha_file = None
258
365
self.ui.captcha_view.setPixmap(QPixmap())
294
401
frame.setPalette(palette)
295
402
frame.setAutoFillBackground(True)
297
# pylint: disable=C0103
299
"""Return the next page id."""
301
# pylint: enable=C0103
303
def set_line_edit_validation_rule(self, edit, cb):
304
"""Set a new enhanced edit so that we can show an icon."""
305
if edit in self._enhanced_edits:
306
self._enhanced_edits[edit].valid_cb = cb
308
# create a new enhanced edit
309
enhanced_edit = EnhancedLineEdit(edit, cb)
310
self._enhanced_edits[edit] = enhanced_edit
314
406
"""Return the name input."""
421
513
return self.ui.set_up_button
424
class SuccessPage(QWizardPage):
516
class SuccessPage(SSOWizardPage):
425
517
"""Page used to display success message."""
427
519
def __init__(self, ui, controller, parent=None):
428
520
"""Create a new instance."""
429
QWizardPage.__init__(self, parent)
521
SSOWizardPage.__init__(self, ui, controller, parent)
431
523
self.ui.setupUi(self)
432
524
self.controller = controller
458
550
"""Create a new wizard."""
459
551
QWizard.__init__(self, parent)
552
# store common useful data provided by the app
553
self.app_name = app_name
554
self.tos_url = tos_url
555
self.help_text = help_text
460
557
# set the diff pages of the QWizard
461
self.sign_in_controller = ChooseSignInController(title='Sign In',
462
existing_account_id=4,
558
self.sign_in_controller = ChooseSignInController(title='Sign In')
464
559
self.sign_in_page = ChooseSignInPage(Ui_ChooseSignInPage(),
465
560
self.sign_in_controller,
467
self.setup_controller = SetUpAccountController(tos_id=2,
562
self.setup_controller = SetUpAccountController()
471
563
self.setup_account = SetupAccountPage(Ui_SetUpAccountPage(),
472
564
self.setup_controller,
474
self.tos = TosPage(Ui_TosPage(), TosController())
566
self.tos = TosPage(Ui_TosPage(), TosController(tos_url=tos_url),
475
568
self.email_verification = EmailVerificationPage(
476
569
Ui_EmailVerificationPage(),
477
570
EmailVerificationController())
478
self.current_user_controller = CurrentUserController(title='Sign in',
571
self.current_user_controller = CurrentUserController(title='Sign in')
480
572
self.current_user = CurrentUserSignInPage(Ui_CurrentUserSignInPage(),
481
573
self.current_user_controller,
486
578
self.error_controller = ErrorController()
487
579
self.error = ErrorPage(Ui_ErrorPage(), self.error_controller)
580
self.forgotte_pwd_controller = ForgottenPasswordController()
581
self.forgotten = ForgottenPasswordPage(Ui_ForgottenPasswordPage(),
582
self.forgotte_pwd_controller,
584
self.reset_password_controller = ResetPasswordController()
585
self.reset_password = ResetPasswordPage(Ui_ResetPasswordPage(),
586
self.reset_password_controller,
488
588
# store the ids of the pages so that it is easier to access them later
490
590
for page in [self.sign_in_page, self.setup_account, self.tos,
491
591
self.email_verification, self.current_user, self.success,
592
self.error, self.forgotten, self.reset_password]:
493
593
self._pages[page] = self.addPage(page)
495
595
# set the buttons layout to only have cancel and back since the next
504
604
self.controller.setupUi(self)
607
def sign_in_page_id(self):
608
"""Return the id of the page used for choosing sign in type."""
609
return self._pages[self.sign_in_page]
612
def setup_account_page_id(self):
613
"""Return the id of the page used for sign in."""
614
return self._pages[self.setup_account]
617
def tos_page_id(self):
618
"""Return the id of the tos page."""
619
return self._pages[self.tos]
622
def email_verification_page_id(self):
623
"""Return the id of the verification page."""
624
return self._pages[self.email_verification]
627
def current_user_page_id(self):
628
"""Return the id used to signin by a current user."""
629
return self._pages[self.current_user]
507
632
def success_page_id(self):
508
633
"""Return the id of the success page."""
509
634
return self._pages[self.success]
637
def forgotten_password_page_id(self):
638
"""Return the id of the forgotten password page."""
639
return self._pages[self.forgotten]
642
def reset_password_page_id(self):
643
"""Return the id of the reset password page."""
644
return self._pages[self.reset_password]
512
647
def error_page_id(self):
513
648
"""Return the id of the error page."""
514
649
return self._pages[self.error]
517
652
class UbuntuSSOClientGUI(object):
518
653
"""Ubuntu single sign-on GUI."""
520
def __init__(self, app_name, tc_url='', help_text='',
655
def __init__(self, app_name, tc_url='http://one.ubuntu.com', help_text='',
521
656
window_id=0, login_only=False):
522
657
"""Create a new instance."""
523
658
# create the controller and the ui, then set the cb and call the show