~nataliabidart/ubuntu-sso-client/find-me-bin-dir

« back to all changes in this revision

Viewing changes to ubuntu_sso/qt/ubuntu_sso_wizard.py

- Refactor the pages and controller in sso (LP: #929686).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
 
 
3
# Copyright 2012 Canonical Ltd.
 
4
#
 
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.
 
8
#
 
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.
 
13
#
 
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/>.
 
16
 
 
17
"""SSO Wizard UI."""
 
18
 
 
19
from PyQt4.QtCore import pyqtSignal
 
20
from PyQt4.QtGui import (
 
21
    QPixmap,
 
22
    QWizard,
 
23
)
 
24
from twisted.internet import defer
 
25
 
 
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
 
44
 
 
45
 
 
46
logger = setup_logging('ubuntu_sso.gui')
 
47
 
 
48
 
 
49
class UbuntuSSOWizard(QWizard):
 
50
    """Wizard used to create or use sso."""
 
51
 
 
52
    # definition of the signals raised by the widget
 
53
    recoverableError = pyqtSignal('QString', 'QString')
 
54
    loginSuccess = pyqtSignal('QString', 'QString')
 
55
    registrationSuccess = pyqtSignal('QString', 'QString')
 
56
 
 
57
    def __init__(self, app_name, **kwargs):
 
58
        """Create a new wizard."""
 
59
        parent = kwargs.get('parent')
 
60
        super(UbuntuSSOWizard, self).__init__(parent)
 
61
 
 
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
 
73
 
 
74
        # set the diff pages of the QWizard
 
75
        self.sign_in_page = SignInPage(Ui_ChooseSignInPage(),
 
76
                                       QPixmap(),
 
77
                                       app_name=self.app_name,
 
78
                                       title='Sign in',
 
79
                                       parent=self)
 
80
        self.setup_account = SetupAccountPage(Ui_SetUpAccountPage(),
 
81
                                              self.help_text,
 
82
                                              self.tc_url,
 
83
                                              self.policy_url,
 
84
                                              app_name=self.app_name,
 
85
                                              parent=self)
 
86
        self.current_user = CurrentUserSignInPage(Ui_CurrentUserSignInPage(),
 
87
                                                  app_name=self.app_name,
 
88
                                                  parent=self)
 
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,
 
98
                                               parent=self)
 
99
        self.reset_password = ResetPasswordPage(Ui_ResetPasswordPage(),
 
100
                                                app_name=self.app_name,
 
101
                                                parent=self)
 
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]
 
106
        self._pages = {}
 
107
        for page in pages:
 
108
            self._pages[page] = self.addPage(page)
 
109
 
 
110
        # set the buttons layout to only have cancel and back since the next
 
111
        # buttons are the ones used in the diff pages.
 
112
        buttons_layout = []
 
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)
 
123
 
 
124
    @property
 
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]
 
128
 
 
129
    @property
 
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]
 
133
 
 
134
    @property
 
135
    def email_verification_page_id(self):
 
136
        """Return the id of the verification page."""
 
137
        return self._pages[self.email_verification]
 
138
 
 
139
    @property
 
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]
 
143
 
 
144
    @property
 
145
    def success_page_id(self):
 
146
        """Return the id of the success page."""
 
147
        return self._pages[self.success]
 
148
 
 
149
    @property
 
150
    def forgotten_password_page_id(self):
 
151
        """Return the id of the forgotten password page."""
 
152
        return self._pages[self.forgotten]
 
153
 
 
154
    @property
 
155
    def reset_password_page_id(self):
 
156
        """Return the id of the reset password page."""
 
157
        return self._pages[self.reset_password]
 
158
 
 
159
    @property
 
160
    def error_page_id(self):
 
161
        """Return the id of the error page."""
 
162
        return self._pages[self.error]
 
163
 
 
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)
 
168
        self.close()
 
169
 
 
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)
 
177
        if result == 0:
 
178
            logger.info('Success in calling the given success_callback')
 
179
            self.show_success_message()
 
180
        else:
 
181
            logger.info('Error in calling the given success_callback')
 
182
            self.show_error_message()
 
183
 
 
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),
 
189
                                                          unicode(email))
 
190
        logger.debug('Result from callback is %s', result)
 
191
        if result == 0:
 
192
            logger.info('Success in calling the given registration_callback')
 
193
            self.show_success_message()
 
194
        else:
 
195
            logger.info('Success in calling the given registration_callback')
 
196
            self.show_error_message()
 
197
 
 
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
 
204
        self.next()
 
205
        # show the finish button but with a close message
 
206
        buttons_layout = []
 
207
        buttons_layout.append(QWizard.Stretch)
 
208
        buttons_layout.append(QWizard.FinishButton)
 
209
        self.setButtonLayout(buttons_layout)
 
210
 
 
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
 
216
        self.next()
 
217
        # show the finish button but with a close message
 
218
        buttons_layout = []
 
219
        buttons_layout.append(QWizard.Stretch)
 
220
        buttons_layout.append(QWizard.FinishButton)
 
221
        self.setButtonLayout(buttons_layout)
 
222
 
 
223
 
 
224
class UbuntuSSOClientGUI(object):
 
225
    """Ubuntu single sign-on GUI."""
 
226
 
 
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.',
 
231
                     app_name, kwargs)
 
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)
 
236
        self.view.show()
 
237
 
 
238
    def get_login_success_callback(self):
 
239
        """Return the log in success cb."""
 
240
        return self.view.login_success_callback
 
241
 
 
242
    def set_login_success_callback(self, cb):
 
243
        """Set log in success cb."""
 
244
        self.view.login_success_callback = cb
 
245
 
 
246
    login_success_callback = property(get_login_success_callback,
 
247
                                      set_login_success_callback)
 
248
 
 
249
    def get_registration_success_callback(self):
 
250
        """Return the registration success cb."""
 
251
        return self.view.registration_success_callback
 
252
 
 
253
    def set_registration_success_callback(self, cb):
 
254
        """Set registration success cb."""
 
255
        self.view.registration_success_callback = cb
 
256
 
 
257
    registration_success_callback = property(get_registration_success_callback,
 
258
                                             set_registration_success_callback)
 
259
 
 
260
    def get_user_cancellation_callback(self):
 
261
        """Return the user cancellation callback."""
 
262
        return self.view.user_cancellation_callback
 
263
 
 
264
    def set_user_cancellation_callback(self, cb):
 
265
        """Set the user cancellation callback."""
 
266
        self.view.user_cancellation_callback = cb
 
267
 
 
268
    user_cancellation_callback = property(get_user_cancellation_callback,
 
269
                                          set_user_cancellation_callback)