29
29
# pylint: enable=F0401
31
31
from PyQt4 import QtGui, QtCore
32
from twisted.internet import defer
34
33
from ubuntu_sso import NO_OP
35
from ubuntu_sso.qt import build_general_error_message
36
from ubuntu_sso.qt import common
37
from ubuntu_sso.qt.gui import SSOWizardEnhancedEditPage
38
from ubuntu_sso.qt import enhanced_check_box
39
from ubuntu_sso.utils.ui import SET_UP_ACCOUNT_BUTTON
34
from ubuntu_sso.logger import setup_gui_logging
35
from ubuntu_sso.qt import (
37
build_general_error_message,
42
from ubuntu_sso.qt.sso_wizard_page import SSOWizardEnhancedEditPage
43
from ubuntu_sso.qt.ui.setup_account_ui import Ui_SetUpAccountPage
40
44
from ubuntu_sso.utils.ui import (
41
45
AGREE_TO_PRIVACY_POLICY,
43
47
AGREE_TO_TERMS_AND_PRIVACY_POLICY,
44
48
CAPTCHA_LOAD_ERROR,
49
CAPTCHA_RELOAD_MESSAGE,
45
51
CAPTCHA_REQUIRED_ERROR,
46
52
CAPTCHA_SOLUTION_ENTRY,
66
72
PRIVACY_POLICY_TEXT,
75
SET_UP_ACCOUNT_BUTTON,
72
from ubuntu_sso.logger import setup_logging
75
logger = setup_logging('ubuntu_sso.setup_account_page')
77
# pylint: disable=C0103
78
ERROR = u'<font color="#df2d1f"><b> %s </b></font>'
79
TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
81
logger = setup_gui_logging('ubuntu_sso.setup_account_page')
81
83
ERROR_EMAIL = 'email'
82
TERMS_LINK = ("<a href='{toc_link}'>"
83
"<span style='color:#df2d1f;'>{terms_text}</span></a>")
84
PRIVACY_POLICY_LINK = ("<a href='{policy_link}'>"
85
"<span style='color:#df2d1f;'>{privacy_policy_text}"
89
86
class SetupAccountPage(SSOWizardEnhancedEditPage):
90
87
"""Customized Setup Account page for SSO."""
92
userRegistered = QtCore.pyqtSignal('QString', 'QString')
89
ui_class = Ui_SetUpAccountPage
90
userRegistered = QtCore.pyqtSignal(unicode)
94
def __init__(self, ui, subtitle, toc_link, policy_link, *args, **kwargs):
95
super(SetupAccountPage, self).__init__(ui, *args, **kwargs)
96
self._subtitle = subtitle
92
def __init__(self, *args, **kwargs):
93
self.captcha_file = None
97
94
self.captcha_id = None
98
self.captcha_file = None
99
self.ui.captcha_view.setPixmap(QtGui.QPixmap())
100
self.ui.password_edit.textEdited.connect(
101
lambda: common.password_assistance(self.ui.password_edit,
102
self.ui.password_assistance,
106
terms_links = TERMS_LINK.format(toc_link=toc_link,
107
terms_text=TERMS_TEXT)
109
privacy_policy_link = PRIVACY_POLICY_LINK.format(
110
policy_link=policy_link,
111
privacy_policy_text=PRIVACY_POLICY_TEXT)
114
if toc_link and policy_link:
115
terms = AGREE_TO_TERMS_AND_PRIVACY_POLICY.format(
116
app_name=self.app_name,
117
terms_and_conditions=terms_links,
118
privacy_policy=privacy_policy_link)
120
terms = AGREE_TO_TERMS.format(app_name=self.app_name,
121
terms_and_conditions=terms_links)
123
terms = AGREE_TO_PRIVACY_POLICY.format(app_name=self.app_name,
124
privacy_policy=privacy_policy_link)
126
self.terms_checkbox = enhanced_check_box.EnhancedCheckBox(terms)
127
self.ui.hlayout_check.addWidget(self.terms_checkbox)
128
self.terms_checkbox.setVisible(bool(toc_link or policy_link))
95
self.captcha_received = False
130
96
self.set_up_button = None
131
self.captcha_received = False
97
self.terms_checkbox = None
98
super(SetupAccountPage, self).__init__(*args, **kwargs)
102
"""The signals to connect to the backend."""
133
104
'CaptchaGenerated':
134
105
self._filter_by_app_name(self.on_captcha_generated),
135
106
'CaptchaGenerationError':
139
110
'UserRegistrationError':
140
111
self._filter_by_app_name(self.on_user_registration_error),
144
@defer.inlineCallbacks
145
def setup_page(self):
146
"""Setup the widget components."""
147
# request the backend to be used with the ui
148
self.backend = yield self.get_backend()
149
# set the callbacks for the captcha generation
150
self._setup_signals()
151
self._connect_ui_elements()
152
self._refresh_captcha()
153
self._set_translated_strings()
154
self._set_line_edits_validations()
155
self._register_fields()
157
115
# Invalid name "initializePage"
158
116
# pylint: disable=C0103
160
118
def initializePage(self):
161
119
"""Setup UI details."""
162
# We need to override some texts from SSO
164
title_page = TITLE_STYLE % TITLE.format(app_name=self.app_name)
165
self.setTitle(title_page)
166
self.setSubTitle(self._subtitle)
167
120
# Set Setup Account button
168
121
self.wizard().setOption(QtGui.QWizard.HaveCustomButton3, True)
196
147
self.ui.confirm_email_assistance.setVisible(False)
197
148
self.ui.password_assistance.setVisible(False)
198
149
self.ui.refresh_label.setVisible(True)
199
#pylint: enable=C0103
151
# pylint: enable=C0103
201
153
def _set_translated_strings(self):
202
154
"""Set the strings."""
203
155
logger.debug('SetUpAccountPage._set_translated_strings')
204
156
# set the translated string
157
title_page = REGISTER_TITLE.format(app_name=self.app_name)
158
self.setTitle(title_page)
159
self.setSubTitle(self.help_text)
205
161
self.ui.name_label.setText(NAME_ENTRY)
206
162
self.ui.email_label.setText(EMAIL1_ENTRY)
207
163
self.ui.confirm_email_label.setText(EMAIL2_ENTRY)
208
164
self.ui.password_label.setText(PASSWORD1_ENTRY)
209
165
self.ui.confirm_password_label.setText(PASSWORD2_ENTRY)
210
self.ui.password_info_label.setText(PASSWORD_HELP)
166
self.ui.password_edit.setToolTip(PASSWORD_HELP)
211
167
self.ui.captcha_solution_edit.setPlaceholderText(
212
168
CAPTCHA_SOLUTION_ENTRY)
169
link = LINK_STYLE.format(link_url='#', link_text=CAPTCHA_RELOAD_TEXT)
170
self.ui.refresh_label.setText(CAPTCHA_RELOAD_MESSAGE %
171
{'reload_link': link})
174
terms_links = LINK_STYLE.format(link_url=self.tc_url,
175
link_text=TERMS_TEXT)
177
privacy_policy_link = LINK_STYLE.format(link_url=self.policy_url,
178
link_text=PRIVACY_POLICY_TEXT)
181
if self.tc_url and self.policy_url:
182
terms = AGREE_TO_TERMS_AND_PRIVACY_POLICY.format(
183
app_name=self.app_name,
184
terms_and_conditions=terms_links,
185
privacy_policy=privacy_policy_link)
187
terms = AGREE_TO_TERMS.format(app_name=self.app_name,
188
terms_and_conditions=terms_links)
189
elif self.policy_url:
190
terms = AGREE_TO_PRIVACY_POLICY.format(app_name=self.app_name,
191
privacy_policy=privacy_policy_link)
193
self.terms_checkbox = enhanced_check_box.EnhancedCheckBox(terms)
194
self.ui.hlayout_check.addWidget(self.terms_checkbox)
195
self.terms_checkbox.setVisible(bool(self.tc_url or self.policy_url))
197
self._register_fields()
214
199
def _set_line_edits_validations(self):
215
200
"""Set the validations to be performed on the edits."""
233
218
self.ui.password_edit.textChanged.connect(
234
219
self.ui.confirm_password_edit.textChanged.emit)
236
def _connect_ui_elements(self):
221
def _connect_ui(self):
237
222
"""Set the connection of signals."""
238
logger.debug('SetUpAccountPage._connect_ui_elements')
223
logger.debug('SetUpAccountPage._connect_ui')
224
self._set_line_edits_validations()
226
self.ui.captcha_view.setPixmap(QtGui.QPixmap())
227
self.ui.password_edit.textEdited.connect(
228
lambda: common.password_assistance(self.ui.password_edit,
229
self.ui.password_assistance,
239
232
self.ui.refresh_label.linkActivated.connect(lambda url: \
240
233
self._refresh_captcha())
241
234
# We need to check if we enable the button on many signals
272
267
email == confirm_email and len(name) > 0
274
269
self.set_up_button.setEnabled(enabled)
275
self.set_up_button.setProperty("DisabledState", not enabled)
276
self.set_up_button.style().unpolish(self.set_up_button)
277
self.set_up_button.style().polish(self.set_up_button)
279
271
def _refresh_captcha(self):
280
272
"""Refresh the captcha image shown in the ui."""
281
273
logger.debug('SetUpAccountPage._refresh_captcha')
282
275
# lets clean behind us, do we have the old file arround?
283
276
if self.captcha_file and os.path.exists(self.captcha_file):
284
277
os.unlink(self.captcha_file)
330
323
def on_captcha_generation_error(self, error, *args, **kwargs):
331
324
"""An error ocurred."""
332
325
logger.debug('SetUpAccountPage.on_captcha_generation_error')
333
self.message_box.critical(self, self.app_name, CAPTCHA_LOAD_ERROR)
326
self.show_error(self.app_name, CAPTCHA_LOAD_ERROR)
334
327
self.on_captcha_refresh_complete()
336
329
def on_user_registration_error(self, app_name, error):
342
335
self.set_error_message(self.ui.email_assistance, msg)
343
336
error_msg = build_general_error_message(error)
345
self.message_box.critical(self, self.app_name, error_msg)
338
self.show_error(self.app_name, error_msg)
346
339
self._refresh_captcha()
348
def on_user_registered(self, app_name, result):
341
def on_user_registered(self, app_name, email):
349
342
"""Execute when the user did register."""
350
344
logger.debug('SetUpAccountPage.on_user_registered')
351
345
email = unicode(self.ui.email_edit.text())
352
password = unicode(self.ui.password_edit.text())
353
self.userRegistered.emit(email, password)
346
self.userRegistered.emit(email)
355
348
def validate_form(self):
356
349
"""Validate the info of the form and return an error."""
383
376
messages.append(CAPTCHA_REQUIRED_ERROR)
384
377
if len(messages) > 0:
385
378
condition = False
386
self.message_box.critical(self, self.app_name, '\n'.join(messages))
379
self.show_error(self.app_name, '\n'.join(messages))
389
# pylint: disable=W0212
390
382
def set_next_validation(self):
391
383
"""Set the validation as the next page."""
392
384
logger.debug('SetUpAccountPage.set_next_validation')
398
390
# validate the current info of the form, try to perform the action
399
391
# to register the user, and then move foward
400
392
if self.validate_form():
401
395
args = (self.app_name, email, password, name, captcha_id,
402
396
captcha_solution)
403
397
f = self.backend.register_user
404
398
error_handler = partial(self._handle_error, f,
405
399
self.on_user_registration_error)
406
400
f(*args, reply_handler=NO_OP, error_handler=error_handler)
407
# Update validation page's title, which contains the email
408
self.userRegistered.emit(email, password)
409
# pylint: enable=W0212
411
402
def is_correct_email(self, email_address):
412
403
"""Return if the email is correct."""
475
466
def set_error_message(self, label, msg):
476
467
"""Set the message to the proper label applying the error style."""
477
label.setText(ERROR % msg)
468
label.setText(ERROR_STYLE % msg)
478
469
label.setVisible(True)
480
#pylint: disable=C0103
471
# pylint: disable=C0103
481
473
def showEvent(self, event):
482
474
"""Set set_up_button as default button when the page is shown."""
483
475
# This method should stays here because if we move it to initializePage
485
477
if self.set_up_button is not None:
486
478
self.set_up_button.setVisible(True)
487
479
self.set_up_button.setDefault(True)
488
if not self.set_up_button.isEnabled():
489
self.set_up_button.setProperty("DisabledState", True)
490
self.set_up_button.style().unpolish(self.set_up_button)
491
self.set_up_button.style().polish(self.set_up_button)
492
480
self.connect(QtGui.QApplication.instance(),
493
481
QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)"),
494
482
self.focus_changed)
495
483
super(SetupAccountPage, self).showEvent(event)
496
484
if not self.captcha_received:
499
487
def hideEvent(self, event):
500
488
"""Disconnect the focusChanged signal when the page change."""
507
495
except TypeError:
509
497
super(SetupAccountPage, self).hideEvent(event)
510
#pylint: enable=C0103
499
# pylint: enable=C0103
512
501
def on_captcha_refreshing(self):
513
502
"""Show overlay when captcha is refreshing."""
514
503
if self.isVisible():
516
505
self.captcha_received = False
518
507
def on_captcha_refresh_complete(self):
519
508
"""Hide overlay when captcha finished refreshing."""
521
510
self.captcha_received = True
523
512
def get_captcha_image(self):