1
# -*- coding: utf-8 -*-
3
# Copyright 2012 Canonical Ltd.
5
# This program is free software: you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License version 3, as published
7
# by the Free Software Foundation.
9
# This program is distributed in the hope that it will be useful, but
10
# WITHOUT ANY WARRANTY; without even the implied warranties of
11
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12
# PURPOSE. See the GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License along
15
# with this program. If not, see <http://www.gnu.org/licenses/>.
19
from PyQt4.QtCore import pyqtSignal
20
from PyQt4.QtGui import (
24
from twisted.internet import defer
26
from ubuntu_sso import NO_OP
27
from ubuntu_sso.qt.current_user_sign_in_page import CurrentUserSignInPage
28
from ubuntu_sso.qt.email_verification_page import EmailVerificationPage
29
from ubuntu_sso.qt.error_page import ErrorPage
30
from ubuntu_sso.qt.forgotten_password_page import ForgottenPasswordPage
31
from ubuntu_sso.qt.reset_password_page import ResetPasswordPage
32
from ubuntu_sso.qt.setup_account_page import SetupAccountPage
33
from ubuntu_sso.qt.sign_in_page import SignInPage
34
from ubuntu_sso.qt.success_page import SuccessPage
35
from ubuntu_sso.qt.ui.choose_sign_in_ui import Ui_ChooseSignInPage
36
from ubuntu_sso.qt.ui.current_user_sign_in_ui import Ui_CurrentUserSignInPage
37
from ubuntu_sso.qt.ui.email_verification_ui import Ui_EmailVerificationPage
38
from ubuntu_sso.qt.ui.error_message_ui import Ui_ErrorPage
39
from ubuntu_sso.qt.ui.setup_account_ui import Ui_SetUpAccountPage
40
from ubuntu_sso.qt.ui.success_message_ui import Ui_SuccessPage
41
from ubuntu_sso.qt.ui.forgotten_password_ui import Ui_ForgottenPasswordPage
42
from ubuntu_sso.qt.ui.reset_password_ui import Ui_ResetPasswordPage
43
from ubuntu_sso.logger import setup_logging
46
logger = setup_logging('ubuntu_sso.gui')
49
class UbuntuSSOWizard(QWizard):
50
"""Wizard used to create or use sso."""
52
# definition of the signals raised by the widget
53
recoverableError = pyqtSignal('QString', 'QString')
54
loginSuccess = pyqtSignal('QString', 'QString')
55
registrationSuccess = pyqtSignal('QString', 'QString')
57
def __init__(self, app_name, **kwargs):
58
"""Create a new wizard."""
59
parent = kwargs.get('parent')
60
super(UbuntuSSOWizard, self).__init__(parent)
62
# store common useful data provided by the app
63
self.app_name = app_name
64
self.ping_url = kwargs.get('ping_url', '')
65
self.tc_url = kwargs.get('tc_url', '')
66
self.policy_url = kwargs.get('policy_url', '')
67
self.help_text = kwargs.get('help_text', '')
68
self.login_only = kwargs.get('login_only', False)
69
self.close_callback = kwargs.get('close_callback', lambda: None)
70
self.login_success_callback = NO_OP
71
self.registration_success_callback = NO_OP
72
self.user_cancellation_callback = NO_OP
74
# set the diff pages of the QWizard
75
self.sign_in_page = SignInPage(Ui_ChooseSignInPage(),
77
app_name=self.app_name,
80
self.setup_account = SetupAccountPage(Ui_SetUpAccountPage(),
84
app_name=self.app_name,
86
self.current_user = CurrentUserSignInPage(Ui_CurrentUserSignInPage(),
87
app_name=self.app_name,
89
self.email_verification = EmailVerificationPage(
90
Ui_EmailVerificationPage(),
91
app_name=self.app_name)
92
self.success = SuccessPage(Ui_SuccessPage(),
93
app_name=self.app_name, parent=self)
94
self.error = ErrorPage(Ui_ErrorPage(),
95
app_name=self.app_name)
96
self.forgotten = ForgottenPasswordPage(Ui_ForgottenPasswordPage(),
97
app_name=self.app_name,
99
self.reset_password = ResetPasswordPage(Ui_ResetPasswordPage(),
100
app_name=self.app_name,
102
# store the ids of the pages so that it is easier to access them later
103
pages = [self.sign_in_page, self.setup_account,
104
self.email_verification, self.current_user, self.success,
105
self.error, self.forgotten, self.reset_password]
108
self._pages[page] = self.addPage(page)
110
# set the buttons layout to only have cancel and back since the next
111
# buttons are the ones used in the diff pages.
113
buttons_layout.append(QWizard.Stretch)
114
buttons_layout.append(QWizard.BackButton)
115
buttons_layout.append(QWizard.CancelButton)
116
self.setButtonLayout(buttons_layout)
117
self.setWindowTitle(self.app_name)
118
self.setWizardStyle(QWizard.ModernStyle)
119
self.button(QWizard.CancelButton).clicked.connect(
120
self.on_user_cancelation)
121
self.loginSuccess.connect(self.on_login_success)
122
self.registrationSuccess.connect(self.on_registration_success)
125
def sign_in_page_id(self):
126
"""Return the id of the page used for choosing sign in type."""
127
return self._pages[self.sign_in_page]
130
def setup_account_page_id(self):
131
"""Return the id of the page used for sign in."""
132
return self._pages[self.setup_account]
135
def email_verification_page_id(self):
136
"""Return the id of the verification page."""
137
return self._pages[self.email_verification]
140
def current_user_page_id(self):
141
"""Return the id used to signin by a current user."""
142
return self._pages[self.current_user]
145
def success_page_id(self):
146
"""Return the id of the success page."""
147
return self._pages[self.success]
150
def forgotten_password_page_id(self):
151
"""Return the id of the forgotten password page."""
152
return self._pages[self.forgotten]
155
def reset_password_page_id(self):
156
"""Return the id of the reset password page."""
157
return self._pages[self.reset_password]
160
def error_page_id(self):
161
"""Return the id of the error page."""
162
return self._pages[self.error]
164
def on_user_cancelation(self):
165
"""Process the cancel action."""
166
logger.debug('UbuntuSSOWizard.on_user_cancelation')
167
self.user_cancellation_callback(self.app_name)
170
@defer.inlineCallbacks
171
def on_login_success(self, app_name, email):
172
"""Process the success of a login."""
173
logger.debug('UbuntuSSOWizard.on_login_success')
174
result = yield self.login_success_callback(
175
unicode(app_name), unicode(email))
176
logger.debug('Result from callback is %s', result)
178
logger.info('Success in calling the given success_callback')
179
self.show_success_message()
181
logger.info('Error in calling the given success_callback')
182
self.show_error_message()
184
@defer.inlineCallbacks
185
def on_registration_success(self, app_name, email):
186
"""Process the success of a registration."""
187
logger.debug('UbuntuSSOWizard.on_registration_success')
188
result = yield self.registration_success_callback(unicode(app_name),
190
logger.debug('Result from callback is %s', result)
192
logger.info('Success in calling the given registration_callback')
193
self.show_success_message()
195
logger.info('Success in calling the given registration_callback')
196
self.show_error_message()
198
def show_success_message(self):
199
"""Show the success message in the view."""
200
logger.info('Showing success message.')
201
# get the id of the success page, set it as the next id of the
202
# current page and let the wizard move to the next step
203
self.currentPage().next = self.success_page_id
205
# show the finish button but with a close message
207
buttons_layout.append(QWizard.Stretch)
208
buttons_layout.append(QWizard.FinishButton)
209
self.setButtonLayout(buttons_layout)
211
def show_error_message(self):
212
"""Show the error page in the view."""
213
logger.info('Showing error message.')
214
# similar to the success page but using the error id
215
self.currentPage().next = self.error_page_id
217
# show the finish button but with a close message
219
buttons_layout.append(QWizard.Stretch)
220
buttons_layout.append(QWizard.FinishButton)
221
self.setButtonLayout(buttons_layout)
224
class UbuntuSSOClientGUI(object):
225
"""Ubuntu single sign-on GUI."""
227
def __init__(self, app_name, **kwargs):
228
"""Create a new instance."""
229
super(UbuntuSSOClientGUI, self).__init__()
230
logger.debug('UbuntuSSOClientGUI: app_name %r, kwargs %r.',
232
self.app_name = app_name
233
# create the controller and the ui, then set the cb and call the show
234
# method so that we can work
235
self.view = UbuntuSSOWizard(app_name=app_name, **kwargs)
238
def get_login_success_callback(self):
239
"""Return the log in success cb."""
240
return self.view.login_success_callback
242
def set_login_success_callback(self, cb):
243
"""Set log in success cb."""
244
self.view.login_success_callback = cb
246
login_success_callback = property(get_login_success_callback,
247
set_login_success_callback)
249
def get_registration_success_callback(self):
250
"""Return the registration success cb."""
251
return self.view.registration_success_callback
253
def set_registration_success_callback(self, cb):
254
"""Set registration success cb."""
255
self.view.registration_success_callback = cb
257
registration_success_callback = property(get_registration_success_callback,
258
set_registration_success_callback)
260
def get_user_cancellation_callback(self):
261
"""Return the user cancellation callback."""
262
return self.view.user_cancellation_callback
264
def set_user_cancellation_callback(self, cb):
265
"""Set the user cancellation callback."""
266
self.view.user_cancellation_callback = cb
268
user_cancellation_callback = property(get_user_cancellation_callback,
269
set_user_cancellation_callback)