~moovida-developers/moovida/account_browser

« back to all changes in this revision

Viewing changes to elisa-plugins/elisa/plugins/poblesec/login.py

  • Committer: Philippe Normand
  • Date: 2009-09-16 10:55:44 UTC
  • mfrom: (1497.1.25 moovida)
  • Revision ID: philippe@fluendo.com-20090916105544-aecwjz5ky8qm934o
merge with master

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
from elisa.core.utils.i18n import install_translation
21
21
 
22
22
from elisa.plugins.pigment.pigment_controller import PigmentController
23
 
from elisa.plugins.pigment.widgets.input import DEFAULT_PASSWORD_CHAR, \
24
 
                                                DEFAULT_OBFUSCATE_DELAY
25
23
 
26
24
from elisa.plugins.poblesec import modal_popup
27
25
from elisa.plugins.poblesec.widgets.keyboard import Keyboard, TextEntry, \
28
26
                                                    PasswordTextEntry
29
 
from elisa.plugins.poblesec.actions import OpenControllerAction
30
27
 
31
28
 
32
29
_ = install_translation('poblesec')
33
30
 
34
31
 
35
 
class LoginController(PigmentController):
36
 
 
37
 
    """
38
 
    A generic login controller presenting the user with an entry
39
 
    and a virtual keyboard to enter a username and a password.
40
 
    """
 
32
class GenericEntryValidationController(PigmentController):
 
33
 
 
34
    """
 
35
    A generic controller presenting the user with a number of text entries and
 
36
    a virtual keyboard to validate some data (e.g. username and password).
 
37
 
 
38
    @cvar layouts: a list of layout resources for the OSK
 
39
    @type layouts: C{list} of C{str}
 
40
    """
 
41
 
 
42
    layouts = ['elisa.plugins.poblesec.osk_qwerty',
 
43
               'elisa.plugins.poblesec.osk_123',
 
44
               'elisa.plugins.poblesec.osk_symbols']
41
45
 
42
46
    def set_frontend(self, frontend):
43
 
        super(LoginController, self).set_frontend(frontend)
44
 
 
45
 
        osk_qwerty = 'elisa.plugins.poblesec.osk_qwerty'
46
 
        osk_123 = 'elisa.plugins.poblesec.osk_123'
47
 
        osk_symbols = 'elisa.plugins.poblesec.osk_symbols'
48
 
        layouts = [osk_qwerty, osk_123, osk_symbols]
49
 
 
50
 
        self.keyboard = Keyboard(layouts)
 
47
        dfr = super(GenericEntryValidationController,
 
48
                    self).set_frontend(frontend)
 
49
        dfr.addCallback(self._create_keyboard)
 
50
        return dfr
 
51
 
 
52
    def _create_keyboard(self, result):
 
53
        self.keyboard = Keyboard(self.layouts)
 
54
        self.set_title()
 
55
        self.create_entries()
 
56
        self.keyboard.connect('validated', self._on_validated)
 
57
        self.keyboard.visible = True
 
58
        self.widget.add(self.keyboard)
 
59
        self.widget.set_focus_proxy(self.keyboard)
 
60
        return result
 
61
 
 
62
    def set_title(self):
 
63
        """
 
64
        Set the title of the keyboard widget.
 
65
 
 
66
        This method should be overridden by subclasses.
 
67
        """
 
68
        raise NotImplementedError('Override me!')
 
69
 
 
70
    def create_entries(self):
 
71
        """
 
72
        Create the desired text entries and add them to the keyboard widget.
 
73
 
 
74
        This method should be overridden by subclasses.
 
75
        """
 
76
        raise NotImplementedError('Override me!')
 
77
 
 
78
    def clean(self):
 
79
        self.keyboard.disconnect_by_func(self._on_validated)
 
80
        return super(GenericEntryValidationController, self).clean()
 
81
 
 
82
    def _on_validated(self, keyboard):
 
83
        dfr = self.validate()
 
84
        dfr.addCallbacks(self.success, self.failure)
 
85
        return dfr
 
86
 
 
87
    def validate(self):
 
88
        """
 
89
        Attempt to validate the contents of the entries against whatever
 
90
        validation process the subclasses will implement.
 
91
 
 
92
        This method should be overridden by subclasses to implement the desired
 
93
        validation logic. The default implementation fails.
 
94
 
 
95
        @return: a deferred fired when the validation is done
 
96
                 (successful or failed) with the result
 
97
        @rtype:  L{elisa.core.utils.defer.Deferred}
 
98
        """
 
99
        return defer.fail(NotImplementedError())
 
100
 
 
101
    def success(self, result):
 
102
        """
 
103
        Callback invoked when the validation succeeds.
 
104
 
 
105
        This method should be overridden by subclasses to implement the desired
 
106
        action to be taken when the validation succeeds. The default
 
107
        implementation return the original result as is.
 
108
 
 
109
        @param result: the result of the validation (may be of any type)
 
110
 
 
111
        @return: a deferred fired when the callback is executed
 
112
        @rtype:  L{elisa.core.utils.defer.Deferred}
 
113
        """
 
114
        # To be overridden by subclasses.
 
115
        return defer.succeed(result)
 
116
 
 
117
    def failure(self, failure):
 
118
        """
 
119
        Callback invoked when the validation fails.
 
120
 
 
121
        This method may be overridden by subclasses to implement a custom
 
122
        behaviour. The default implementation propagates the failure.
 
123
 
 
124
        @param failure: the failure object
 
125
        @type failure:  L{twisted.python.failure.Failure}
 
126
 
 
127
        @return: a deferred fired when the callback is executed
 
128
        @rtype:  L{elisa.core.utils.defer.Deferred}
 
129
        """
 
130
        return defer.fail(failure)
 
131
 
 
132
 
 
133
class GenericLoginController(GenericEntryValidationController):
 
134
 
 
135
    """
 
136
    A generic login controller presenting the user with two text entries
 
137
    (username and password) and a virtual keyboard to login to any service.
 
138
    """
 
139
 
 
140
    def set_title(self):
 
141
        # Overridden from base class.
51
142
        self.keyboard.title.foreground.label = \
52
143
            _('ENTER YOUR USERNAME & PASSWORD')
53
144
 
 
145
    def create_entries(self):
 
146
        # Overridden from base class.
54
147
        self._username = TextEntry()
55
148
        self._username.instructions = _('Username')
56
149
        self._username.decorations.set_name('username')
63
156
        self._password.visible = True
64
157
        self.keyboard.add_entry(self._password)
65
158
 
66
 
        self.keyboard.connect('validated', self._on_validated)
67
 
        self.keyboard.visible = True
68
 
        self.widget.add(self.keyboard)
69
 
        self.widget.set_focus_proxy(self.keyboard)
70
 
 
71
 
    def clean(self):
72
 
        self.keyboard.disconnect_by_func(self._on_validated)
73
 
        return super(LoginController, self).clean()
74
 
 
75
 
    def _on_validated(self, keyboard):
76
 
        dfr = self.login(self._username.content, self._password.content)
77
 
        dfr.addCallbacks(self.success, self.failure)
78
 
        return dfr
79
 
 
80
 
    def go_back(self):
81
 
        # Go back one screen.
82
 
        browser = self.frontend.retrieve_controllers('/poblesec/browser')[0]
83
 
        return browser.history.go_back()
84
 
 
85
 
    def close(self):
86
 
        """
87
 
        Close this controller.
88
 
 
89
 
        @return: a deferred fired when done closing
90
 
        @rtype:  L{elisa.core.utils.defer.Deferred}
91
 
        """
92
 
        return self.go_back()
 
159
    def validate(self):
 
160
        # Overridden from base class.
 
161
        return self.login(self._username.content, self._password.content)
93
162
 
94
163
    def login(self, username, password):
95
164
        """
96
 
        Attempt to log in user the supplied credentials (username and password).
 
165
        Attempt to log in with the supplied credentials
 
166
        (username and password).
97
167
 
98
168
        This method should be overridden by subclasses to implement the desired
99
169
        login logic. The default implementation fails.
109
179
        """
110
180
        return defer.fail(NotImplementedError())
111
181
 
112
 
    def success(self, result):
 
182
 
 
183
class LoginController(GenericLoginController):
 
184
 
 
185
    """
 
186
    A login controller specific to poblesec's browser controller with a default
 
187
    behaviour that should fit the most common cases when the login fails
 
188
    (show an error popup and offer the user to cancel or retry).
 
189
    """
 
190
 
 
191
    def go_back(self):
 
192
        # Go back one screen.
 
193
        main = self.frontend.controller
 
194
        return main.browser.history.go_back()
 
195
 
 
196
    def close(self):
113
197
        """
114
 
        Callback invoked when the login succeeds.
115
 
 
116
 
        This method should be overridden by subclasses to implement the desired
117
 
        action to be taken when the login succeeds. The default implementation
118
 
        does nothing.
119
 
 
120
 
        @param result: the result of the login (may be of any type)
121
 
 
122
 
        @return: a deferred fired when the callback is executed
 
198
        Close this controller.
 
199
 
 
200
        @return: a deferred fired when done closing
123
201
        @rtype:  L{elisa.core.utils.defer.Deferred}
124
202
        """
125
 
        # To be overridden by subclasses.
126
 
        return defer.succeed(None)
 
203
        return self.go_back()
127
204
 
128
205
    def failure(self, failure):
129
 
        """
130
 
        Callback invoked when the login fails.
131
 
 
132
 
        This method may be overridden by subclasses to implement a custom
133
 
        behaviour. The default implementation shows an error popup.
134
 
 
135
 
        @param failure: the failure object
136
 
        @type failure:  L{twisted.python.failure.Failure}
137
 
 
138
 
        @return: a deferred fired when the callback is executed
139
 
        @rtype:  L{elisa.core.utils.defer.Deferred}
140
 
        """
141
 
        main = self.frontend.retrieve_controllers('/poblesec')[0]
 
206
        # Overridden from base class.
 
207
        main = self.frontend.controller
142
208
        title = _('LOGIN FAILED')
143
209
        subtitle = _('Could Not Login')
144
210
        text = \
145
211
            _("Moovida was unable to login using the details you entered.\n" \
146
 
              "Please recheck the login information you provided and attempt " \
147
 
              "to login again by selecting 'Check Login Details'.\n" \
 
212
              "Please recheck the login information you provided and " \
 
213
              "attempt to login again by selecting 'Check Login Details'.\n" \
148
214
              "Alternatively, you can cancel the login process by selecting " \
149
215
              "'Cancel Login'.")
150
216
 
158
224
                        lambda: close_and_callback(self.close)))
159
225
        buttons.append((_('Check Login Details'), main.hide_popup))
160
226
 
161
 
        main.enqueue_popup(title, subtitle, text, buttons, modal_popup.ErrorPopup)
 
227
        main.enqueue_popup(title, subtitle, text, buttons,
 
228
                           modal_popup.ErrorPopup)
162
229
 
163
 
        # FIXME: the popup system not returning deferreds is a pain.
 
230
        # FIXME: the popup system does not return deferreds.
164
231
        return defer.succeed(None)