20
20
from elisa.core.utils.i18n import install_translation
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
26
24
from elisa.plugins.poblesec import modal_popup
27
25
from elisa.plugins.poblesec.widgets.keyboard import Keyboard, TextEntry, \
29
from elisa.plugins.poblesec.actions import OpenControllerAction
32
29
_ = install_translation('poblesec')
35
class LoginController(PigmentController):
38
A generic login controller presenting the user with an entry
39
and a virtual keyboard to enter a username and a password.
32
class GenericEntryValidationController(PigmentController):
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).
38
@cvar layouts: a list of layout resources for the OSK
39
@type layouts: C{list} of C{str}
42
layouts = ['elisa.plugins.poblesec.osk_qwerty',
43
'elisa.plugins.poblesec.osk_123',
44
'elisa.plugins.poblesec.osk_symbols']
42
46
def set_frontend(self, frontend):
43
super(LoginController, self).set_frontend(frontend)
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]
50
self.keyboard = Keyboard(layouts)
47
dfr = super(GenericEntryValidationController,
48
self).set_frontend(frontend)
49
dfr.addCallback(self._create_keyboard)
52
def _create_keyboard(self, result):
53
self.keyboard = Keyboard(self.layouts)
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)
64
Set the title of the keyboard widget.
66
This method should be overridden by subclasses.
68
raise NotImplementedError('Override me!')
70
def create_entries(self):
72
Create the desired text entries and add them to the keyboard widget.
74
This method should be overridden by subclasses.
76
raise NotImplementedError('Override me!')
79
self.keyboard.disconnect_by_func(self._on_validated)
80
return super(GenericEntryValidationController, self).clean()
82
def _on_validated(self, keyboard):
84
dfr.addCallbacks(self.success, self.failure)
89
Attempt to validate the contents of the entries against whatever
90
validation process the subclasses will implement.
92
This method should be overridden by subclasses to implement the desired
93
validation logic. The default implementation fails.
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}
99
return defer.fail(NotImplementedError())
101
def success(self, result):
103
Callback invoked when the validation succeeds.
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.
109
@param result: the result of the validation (may be of any type)
111
@return: a deferred fired when the callback is executed
112
@rtype: L{elisa.core.utils.defer.Deferred}
114
# To be overridden by subclasses.
115
return defer.succeed(result)
117
def failure(self, failure):
119
Callback invoked when the validation fails.
121
This method may be overridden by subclasses to implement a custom
122
behaviour. The default implementation propagates the failure.
124
@param failure: the failure object
125
@type failure: L{twisted.python.failure.Failure}
127
@return: a deferred fired when the callback is executed
128
@rtype: L{elisa.core.utils.defer.Deferred}
130
return defer.fail(failure)
133
class GenericLoginController(GenericEntryValidationController):
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.
141
# Overridden from base class.
51
142
self.keyboard.title.foreground.label = \
52
143
_('ENTER YOUR USERNAME & PASSWORD')
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)
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)
72
self.keyboard.disconnect_by_func(self._on_validated)
73
return super(LoginController, self).clean()
75
def _on_validated(self, keyboard):
76
dfr = self.login(self._username.content, self._password.content)
77
dfr.addCallbacks(self.success, self.failure)
82
browser = self.frontend.retrieve_controllers('/poblesec/browser')[0]
83
return browser.history.go_back()
87
Close this controller.
89
@return: a deferred fired when done closing
90
@rtype: L{elisa.core.utils.defer.Deferred}
160
# Overridden from base class.
161
return self.login(self._username.content, self._password.content)
94
163
def login(self, username, password):
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).
98
168
This method should be overridden by subclasses to implement the desired
99
169
login logic. The default implementation fails.
110
180
return defer.fail(NotImplementedError())
112
def success(self, result):
183
class LoginController(GenericLoginController):
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).
192
# Go back one screen.
193
main = self.frontend.controller
194
return main.browser.history.go_back()
114
Callback invoked when the login succeeds.
116
This method should be overridden by subclasses to implement the desired
117
action to be taken when the login succeeds. The default implementation
120
@param result: the result of the login (may be of any type)
122
@return: a deferred fired when the callback is executed
198
Close this controller.
200
@return: a deferred fired when done closing
123
201
@rtype: L{elisa.core.utils.defer.Deferred}
125
# To be overridden by subclasses.
126
return defer.succeed(None)
203
return self.go_back()
128
205
def failure(self, failure):
130
Callback invoked when the login fails.
132
This method may be overridden by subclasses to implement a custom
133
behaviour. The default implementation shows an error popup.
135
@param failure: the failure object
136
@type failure: L{twisted.python.failure.Failure}
138
@return: a deferred fired when the callback is executed
139
@rtype: L{elisa.core.utils.defer.Deferred}
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')
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'.")