Merge lp:~alecu/ubuntu-sso-client/credentials-interface into lp:ubuntu-sso-client
- credentials-interface
- Merge into trunk
Proposed by
Alejandro J. Cura
Status: | Merged |
---|---|
Approved by: | Rodrigo Moya |
Approved revision: | 565 |
Merged at revision: | 559 |
Proposed branch: | lp:~alecu/ubuntu-sso-client/credentials-interface |
Merge into: | lp:ubuntu-sso-client |
Diff against target: |
577 lines (+340/-36) 6 files modified
bin/ubuntu-sso-login (+7/-2) ubuntu_sso/__init__.py (+1/-0) ubuntu_sso/keyring.py (+111/-0) ubuntu_sso/main.py (+74/-18) ubuntu_sso/tests/test_gui.py (+0/-10) ubuntu_sso/tests/test_main.py (+147/-6) |
To merge this branch: | bzr merge lp:~alecu/ubuntu-sso-client/credentials-interface |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Rodrigo Moya (community) | Approve | ||
Natalia Bidart (community) | Approve | ||
Review via email: mp+31896@code.launchpad.net |
Commit message
DBus interface for getting the credentials from the keyring, or show a dialog to login/register
Description of the change
DBus interface for getting the credentials from the keyring, or show a dialog to login/register
To post a comment you must log in.
- 564. By Alejandro J. Cura
-
nessita's eagle eye spotted this pring
- 565. By Alejandro J. Cura
-
do not store the keyring tokens yet
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/ubuntu-sso-login' |
2 | --- bin/ubuntu-sso-login 2010-08-03 20:03:44 +0000 |
3 | +++ bin/ubuntu-sso-login 2010-08-06 02:49:40 +0000 |
4 | @@ -30,12 +30,13 @@ |
5 | |
6 | from dbus.mainloop.glib import DBusGMainLoop |
7 | |
8 | -from ubuntu_sso import DBUS_IFACE_AUTH_NAME, DBUS_BUS_NAME |
9 | -from ubuntu_sso.main import Login, SSOLogin |
10 | +from ubuntu_sso import DBUS_IFACE_AUTH_NAME, DBUS_BUS_NAME, DBUS_CRED_PATH |
11 | +from ubuntu_sso.main import Login, SSOLogin, SSOCredentials |
12 | |
13 | from ubuntu_sso.logger import setupLogging |
14 | logger = setupLogging("ubuntu-sso-login") |
15 | |
16 | +gtk.gdk.threads_init() |
17 | DBusGMainLoop(set_as_default=True) |
18 | |
19 | _ = gettext.gettext |
20 | @@ -235,5 +236,9 @@ |
21 | bus=dbus.SessionBus())) |
22 | ssoLogin = SSOLogin(dbus.service.BusName(DBUS_BUS_NAME, |
23 | bus=dbus.SessionBus())) |
24 | + SSOCredentials(dbus.service.BusName(DBUS_BUS_NAME, |
25 | + bus=dbus.SessionBus()), |
26 | + object_path=DBUS_CRED_PATH) |
27 | + |
28 | manager = LoginMain() |
29 | manager.main() |
30 | |
31 | === modified file 'ubuntu_sso/__init__.py' |
32 | --- ubuntu_sso/__init__.py 2010-08-03 15:02:15 +0000 |
33 | +++ ubuntu_sso/__init__.py 2010-08-06 02:49:40 +0000 |
34 | @@ -19,6 +19,7 @@ |
35 | DBUS_PATH_AUTH = "/" |
36 | DBUS_BUS_NAME = "com.ubuntu.sso" |
37 | DBUS_PATH = "/sso" |
38 | +DBUS_CRED_PATH = "/credentials" |
39 | DBUS_IFACE_AUTH_NAME = "com.ubuntu.sso" |
40 | DBUS_IFACE_USER_NAME = "com.ubuntu.sso.UserManagement" |
41 | DBUS_IFACE_CRED_NAME = "com.ubuntu.sso.ApplicationCredentials" |
42 | |
43 | === added file 'ubuntu_sso/keyring.py' |
44 | --- ubuntu_sso/keyring.py 1970-01-01 00:00:00 +0000 |
45 | +++ ubuntu_sso/keyring.py 2010-08-06 02:49:40 +0000 |
46 | @@ -0,0 +1,111 @@ |
47 | +# Copyright (C) 2010 Canonical |
48 | +# |
49 | +# Authors: |
50 | +# Andrew Higginson |
51 | +# |
52 | +# This program is free software; you can redistribute it and/or modify it under |
53 | +# the terms of the GNU General Public License as published by the Free Software |
54 | +# Foundation; version 3. |
55 | +# |
56 | +# This program is distributed in the hope that it will be useful, but WITHOUT |
57 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
58 | +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
59 | +# details. |
60 | +# |
61 | +# You should have received a copy of the GNU General Public License along with |
62 | +# this program; if not, write to the Free Software Foundation, Inc., |
63 | +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
64 | + |
65 | +import gnomekeyring |
66 | + |
67 | +from urllib import urlencode |
68 | +from urlparse import parse_qs |
69 | + |
70 | +class Keyring(object): |
71 | + |
72 | + KEYRING_NAME = "login" |
73 | + |
74 | + def __init__(self, app_name): |
75 | + |
76 | + if not gnomekeyring.is_available(): |
77 | + raise gnomekeyring.NoKeyringDaemonError |
78 | + self.app_name = app_name |
79 | + |
80 | + def _create_keyring(self, name): |
81 | + """ |
82 | + Creates a keyring, if it already exists, |
83 | + it does nothing |
84 | + """ |
85 | + keyring_names = gnomekeyring.list_keyring_names_sync() |
86 | + if not name in keyring_names: |
87 | + gnomekeyring.create_sync(name) |
88 | + |
89 | + def _item_exists(self, sync, name): |
90 | + """ |
91 | + Returns whether a named item exists in a |
92 | + named keyring |
93 | + """ |
94 | + return self._get_item_id_from_name(sync, name) != None |
95 | + |
96 | + def _get_item_id_from_name(self, sync, name): |
97 | + """ |
98 | + Returns the ID for a named item |
99 | + """ |
100 | + for item_id in gnomekeyring.list_item_ids_sync(sync): |
101 | + item_info = gnomekeyring.item_get_info_sync(sync, item_id) |
102 | + display_name = item_info.get_display_name() |
103 | + if display_name == name: |
104 | + return item_id |
105 | + return None |
106 | + |
107 | + def _get_item_info_from_name(self, sync, name): |
108 | + """ |
109 | + Returns the ID for a named item |
110 | + """ |
111 | + for item_id in gnomekeyring.list_item_ids_sync(sync): |
112 | + item_info = gnomekeyring.item_get_info_sync(sync, item_id) |
113 | + display_name = item_info.get_display_name() |
114 | + if display_name == name: |
115 | + return item_info |
116 | + return None |
117 | + |
118 | + def set_ubuntusso_attr(self, attr): |
119 | + """ |
120 | + Sets the attributes of the Ubuntu SSO item |
121 | + """ |
122 | + # Creates the secret from the attributes |
123 | + secret = urlencode(attr) |
124 | + |
125 | + # Create the keyring |
126 | + self._create_keyring(self.KEYRING_NAME) |
127 | + |
128 | + # If the item already exists, delete it |
129 | + if self._item_exists(self.KEYRING_NAME, self.app_name): |
130 | + item_id = self._get_item_id_from_name(self.KEYRING_NAME, |
131 | + self.app_name) |
132 | + gnomekeyring.item_delete_sync(self.KEYRING_NAME, item_id) |
133 | + |
134 | + # Add our SSO item |
135 | + gnomekeyring.item_create_sync(self.KEYRING_NAME, |
136 | + gnomekeyring.ITEM_GENERIC_SECRET, self.app_name, {}, |
137 | + secret, True) |
138 | + |
139 | + def get_ubuntusso_attr(self): |
140 | + """ |
141 | + Returns the secret of the SSO item in a dictionary |
142 | + """ |
143 | + # If we have no attributes, return None |
144 | + if self._get_item_info_from_name(self.KEYRING_NAME, |
145 | + self.app_name) == None: |
146 | + return None |
147 | + secret = self._get_item_info_from_name(self.KEYRING_NAME, |
148 | + self.app_name).get_secret() |
149 | + return parse_qs(secret) |
150 | + |
151 | +if __name__ == "__main__": |
152 | + SSO_ITEM_NAME = "Software Center UbuntuSSO token" |
153 | + keyring = Keyring(SSO_ITEM_NAME) |
154 | + keyring.set_ubuntusso_attr({"ha":"hehddddeff", "hi":"hggehes", "ho":"he"}) |
155 | + print keyring.get_ubuntusso_attr() |
156 | + |
157 | + |
158 | |
159 | === modified file 'ubuntu_sso/main.py' |
160 | --- ubuntu_sso/main.py 2010-08-05 02:24:33 +0000 |
161 | +++ ubuntu_sso/main.py 2010-08-06 02:49:40 +0000 |
162 | @@ -34,6 +34,7 @@ |
163 | |
164 | import dbus.service |
165 | import gobject |
166 | +import gtk |
167 | import pynotify |
168 | |
169 | from dbus.mainloop.glib import DBusGMainLoop |
170 | @@ -43,20 +44,18 @@ |
171 | from lazr.restfulclient.resource import ServiceRoot |
172 | from oauth.oauth import OAuthToken |
173 | |
174 | +from keyring import Keyring |
175 | from ubuntu_sso import (DBUS_IFACE_AUTH_NAME, |
176 | DBUS_IFACE_USER_NAME, |
177 | DBUS_IFACE_CRED_NAME, |
178 | + DBUS_CRED_PATH, |
179 | DBUS_BUS_NAME) |
180 | from ubuntu_sso.config import get_config |
181 | |
182 | from ubuntu_sso.logger import setupLogging |
183 | logger = setupLogging("ubuntu_sso.main") |
184 | |
185 | - |
186 | DBusGMainLoop(set_as_default=True) |
187 | -dbus.mainloop.glib.threads_init() |
188 | -gobject.threads_init() |
189 | - |
190 | # Disable the invalid name warning, as we have a lot of DBus style names |
191 | # pylint: disable-msg=C0103 |
192 | |
193 | @@ -92,6 +91,21 @@ |
194 | """The email token is not valid.""" |
195 | |
196 | |
197 | +def keyring_store_token(token_name, token): |
198 | + """Store the credentials in the keyring.""" |
199 | + attr = {"token": token} |
200 | + Keyring(token_name).set_ubuntusso_attr(attr) |
201 | + |
202 | + |
203 | +def keyring_get_token(token_name): |
204 | + """Get the credentials from the keyring or None if not there.""" |
205 | + d = Keyring(token_name).get_ubuntusso_attr() |
206 | + if d is not None: |
207 | + return d["token"] |
208 | + else: |
209 | + return None |
210 | + |
211 | + |
212 | class SSOLoginProcessor(object): |
213 | """Login and register users using the Ubuntu Single Sign On service.""" |
214 | |
215 | @@ -208,7 +222,7 @@ |
216 | try: |
217 | result_cb(f()) |
218 | except Exception, e: |
219 | - logger.error(e) |
220 | + logger.exception(e) |
221 | error_cb(str(e)) |
222 | threading.Thread(target=_in_thread).start() |
223 | |
224 | @@ -230,9 +244,6 @@ |
225 | return self.sso_login_processor_class( |
226 | sso_service_class=self.sso_service_class) |
227 | |
228 | - # ======================================== |
229 | - # DBUS_IFACE_USER_NAME methods and signals |
230 | - |
231 | # generate_capcha signals |
232 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="s") |
233 | def CaptchaGenerated(self, result): |
234 | @@ -285,7 +296,10 @@ |
235 | """Call the matching method in the processor.""" |
236 | def f(): |
237 | """Inner function that will be run in a thread.""" |
238 | - return self.processor().login(email, password, token_name) |
239 | + token = self.processor().login(email, password, token_name) |
240 | + # XXX: will be fixed in upcoming branch |
241 | + #keyring_store_token(token_name, token) |
242 | + return "Ok" |
243 | return blocking(f, self.LoggedIn, self.LoginError) |
244 | |
245 | # validate_email signals |
246 | @@ -307,8 +321,9 @@ |
247 | token_name, email_token) |
248 | return blocking(f, self.EmailValidated, self.EmailValidationError) |
249 | |
250 | - # ---------------------------------------- |
251 | - # DBUS_IFACE_CRED_NAME methods and signals |
252 | + |
253 | +class SSOCredentials(dbus.service.Object): |
254 | + """DBus object that gets credentials, and login/registers if needed.""" |
255 | |
256 | @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="s") |
257 | def CredentialsFound(self, result): |
258 | @@ -319,17 +334,53 @@ |
259 | """Signal thrown when there is a problem finding the credentials.""" |
260 | |
261 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, |
262 | - in_signature="s", out_signature="") |
263 | - def find_credentials(self, application_name): |
264 | - # XXX: placeholder; coming in the following branch |
265 | - pass |
266 | + in_signature="s", out_signature="s") |
267 | + def find_credentials(self, token_name): |
268 | + """Get the credentials from the keyring or '' if not there.""" |
269 | + token = keyring_get_token(token_name) |
270 | + if token is None: |
271 | + return "" |
272 | + else: |
273 | + return token |
274 | + |
275 | + def _response_cb(self, dialog, response, token_name): |
276 | + """Handles the response from the UI dialog.""" |
277 | + # XXX: to be replaced in the following branch |
278 | + try: |
279 | + token = "token%d" % response |
280 | + keyring_store_token(token_name, token) |
281 | + self.CredentialsFound(token) |
282 | + except Exception, e: |
283 | + self.CredentialsError(str(e)) |
284 | + dialog.destroy() |
285 | + |
286 | + def _show_login_or_register_ui(self, token_name, terms_and_conditions_url): |
287 | + """Shows the UI so the user can login or register.""" |
288 | + # XXX: to be replaced in the following branch |
289 | + try: |
290 | + dialog = gtk.MessageDialog(None, |
291 | + gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO, |
292 | + gtk.BUTTONS_CLOSE, terms_and_conditions_url) |
293 | + dialog.connect("response", self._response_cb, token_name) |
294 | + dialog.show() |
295 | + except Exception, e: |
296 | + self.CredentialsError(str(e)) |
297 | |
298 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, |
299 | in_signature="ss", out_signature="") |
300 | - def login_or_register_to_get_credentials(self, application_name, |
301 | + def login_or_register_to_get_credentials(self, token_name, |
302 | terms_and_conditions_url): |
303 | - # XXX: placeholder; coming in the following branch |
304 | - pass |
305 | + |
306 | + """Get credentials if found else prompt to login or register first.""" |
307 | + try: |
308 | + token = keyring_get_token(token_name) |
309 | + if token is None: |
310 | + gobject.idle_add(self._show_login_or_register_ui, token_name, |
311 | + terms_and_conditions_url) |
312 | + else: |
313 | + self.CredentialsFound(token) |
314 | + except Exception, e: |
315 | + self.CredentialsError(str(e)) |
316 | |
317 | |
318 | class LoginProcessor: |
319 | @@ -558,6 +609,8 @@ |
320 | |
321 | def main(): |
322 | """Start everything""" |
323 | + dbus.mainloop.glib.threads_init() |
324 | + gobject.threads_init() |
325 | logger.debug("Starting up at %s", time.asctime()) |
326 | logger.debug("Installing the Twisted glib2reactor") |
327 | from twisted.internet import glib2reactor # for non-GUI apps |
328 | @@ -569,6 +622,9 @@ |
329 | bus=dbus.SessionBus())) |
330 | SSOLogin(dbus.service.BusName(DBUS_BUS_NAME, |
331 | bus=dbus.SessionBus())) |
332 | + SSOCredentials(dbus.service.BusName(DBUS_BUS_NAME, |
333 | + bus=dbus.SessionBus()), |
334 | + object_path=DBUS_CRED_PATH) |
335 | # cleverness here to say: |
336 | # am I already running (bound to this d-bus name)? |
337 | # if so, send a signal to the already running instance |
338 | |
339 | === modified file 'ubuntu_sso/tests/test_gui.py' |
340 | --- ubuntu_sso/tests/test_gui.py 2010-08-05 02:24:33 +0000 |
341 | +++ ubuntu_sso/tests/test_gui.py 2010-08-06 02:49:40 +0000 |
342 | @@ -46,12 +46,6 @@ |
343 | EMAIL_TOKEN = 'B2Pgtf' |
344 | |
345 | |
346 | -def process_pending(): |
347 | - """Process all the pending GTK events.""" |
348 | - while gtk.events_pending(): |
349 | - gtk.main_iteration() |
350 | - |
351 | - |
352 | class FakedSSOBackend(object): |
353 | """Fake a SSO Backend (acts as a dbus.Interface as well).""" |
354 | |
355 | @@ -149,7 +143,6 @@ |
356 | """Grab focus on widget, if None use self.entry.""" |
357 | direction = 'in' if focus_in else 'out' |
358 | self.entry.emit('focus-%s-event' % direction, None) |
359 | - process_pending() |
360 | |
361 | def assert_correct_label(self): |
362 | """Check that the entry has the correct label.""" |
363 | @@ -212,7 +205,6 @@ |
364 | self.grab_focus() # grab focus |
365 | |
366 | self.entry.set_text(' ') # add empty text to the entry |
367 | - process_pending() |
368 | |
369 | self.grab_focus(focus_in=False) # loose focus |
370 | |
371 | @@ -227,7 +219,6 @@ |
372 | self.grab_focus() # grab focus |
373 | |
374 | self.entry.set_text(expected) # add empty text to the entry |
375 | - process_pending() |
376 | |
377 | self.grab_focus(focus_in=False) # loose focus |
378 | |
379 | @@ -241,7 +232,6 @@ |
380 | self.grab_focus() # grab focus |
381 | |
382 | self.entry.set_text(expected) # add text to the entry |
383 | - process_pending() |
384 | |
385 | self.grab_focus(focus_in=False) # loose focus |
386 | self.grab_focus() # grab focus again! |
387 | |
388 | === modified file 'ubuntu_sso/tests/test_main.py' |
389 | --- ubuntu_sso/tests/test_main.py 2010-08-04 00:10:14 +0000 |
390 | +++ ubuntu_sso/tests/test_main.py 2010-08-06 02:49:40 +0000 |
391 | @@ -31,7 +31,8 @@ |
392 | from ubuntu_sso import config |
393 | from ubuntu_sso.main import ( |
394 | AuthenticationError, BadRealmError, blocking, EmailTokenError, |
395 | - InvalidEmailError, InvalidPasswordError, SSOLogin, |
396 | + InvalidEmailError, InvalidPasswordError, SSOLogin, SSOCredentials, |
397 | + keyring_get_token, keyring_store_token, |
398 | LoginProcessor, SSOLoginProcessor, RegistrationError) |
399 | |
400 | |
401 | @@ -110,7 +111,7 @@ |
402 | self.accounts = FakedAccounts() |
403 | |
404 | |
405 | -class SSOLoginProcessorTestCase(TestCase): |
406 | +class SSOLoginProcessorTestCase(TestCase, MockerTestCase): |
407 | """Test suite for the SSO login processor.""" |
408 | |
409 | def setUp(self): |
410 | @@ -436,14 +437,14 @@ |
411 | email = "sample email" |
412 | password = "sample password" |
413 | token_name = "sample token_name" |
414 | - expected_result = "expected result" |
415 | + sample_result = {"sample": "tokens"} |
416 | self.create_mock_processor().login(email, password, token_name) |
417 | - self.mocker.result(expected_result) |
418 | + self.mocker.result(sample_result) |
419 | self.patch(ubuntu_sso.main, "blocking", self.fake_ok_blocking) |
420 | self.mocker.replay() |
421 | |
422 | def verify(result): |
423 | - self.assertEqual(result, expected_result) |
424 | + self.assertEqual(result, "Ok") |
425 | d.callback(result) |
426 | |
427 | client = SSOLogin(self.mockbusname, |
428 | @@ -556,8 +557,148 @@ |
429 | raise BlockingSampleException(expected_error_message) |
430 | |
431 | def verify(error): |
432 | - self.assertEquals(error, expected_error_message) |
433 | + self.assertEqual(error, expected_error_message) |
434 | d.callback("Ok") |
435 | |
436 | blocking(f, d.errback, verify) |
437 | return d |
438 | + |
439 | + |
440 | +class KeyringTokenTestCase(MockerTestCase): |
441 | + """Checks the functions that access the keyring.""" |
442 | + |
443 | + def test_keyring_store_token(self): |
444 | + """Verify the method that stores tokens.""" |
445 | + token_name = "token_name" |
446 | + token_value = "token value" |
447 | + mockKeyringClass = self.mocker.replace("ubuntu_sso.keyring.Keyring") |
448 | + mockKeyringClass(token_name) |
449 | + mockKeyring = self.mocker.mock() |
450 | + self.mocker.result(mockKeyring) |
451 | + mockKeyring.set_ubuntusso_attr({"token": token_value}) |
452 | + self.mocker.replay() |
453 | + |
454 | + keyring_store_token(token_name, token_value) |
455 | + |
456 | + def test_keyring_get_token(self): |
457 | + """The method returns the right token.""" |
458 | + token_name = "token_name" |
459 | + token_value = "token value" |
460 | + mockKeyringClass = self.mocker.replace("ubuntu_sso.keyring.Keyring") |
461 | + mockKeyringClass(token_name) |
462 | + mockKeyring = self.mocker.mock() |
463 | + self.mocker.result(mockKeyring) |
464 | + mockKeyring.get_ubuntusso_attr() |
465 | + self.mocker.result({"token": token_value}) |
466 | + self.mocker.replay() |
467 | + |
468 | + token = keyring_get_token(token_name) |
469 | + self.assertEqual(token, token_value) |
470 | + |
471 | + def test_keyring_get_token_not_found(self): |
472 | + """The method returns None when the token is not found.""" |
473 | + token_name = "token_name" |
474 | + mockKeyringClass = self.mocker.replace("ubuntu_sso.keyring.Keyring") |
475 | + mockKeyringClass(token_name) |
476 | + mockKeyring = self.mocker.mock() |
477 | + self.mocker.result(mockKeyring) |
478 | + mockKeyring.get_ubuntusso_attr() |
479 | + self.mocker.result(None) |
480 | + self.mocker.replay() |
481 | + |
482 | + token = keyring_get_token(token_name) |
483 | + self.assertEqual(token, None) |
484 | + |
485 | + |
486 | +class RegisterSampleException(Exception): |
487 | + """A mock exception thrown just when testing.""" |
488 | + |
489 | + |
490 | +class CredentialsTestCase(TestCase, MockerTestCase): |
491 | + """Tests for the credentials related DBus methods.""" |
492 | + |
493 | + def test_find_credentials(self): |
494 | + """find_credentials immediately returns the token when found.""" |
495 | + expected_token = "expected token" |
496 | + kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token") |
497 | + kgt(ARGS) |
498 | + self.mocker.result(expected_token) |
499 | + self.mocker.replay() |
500 | + |
501 | + client = SSOCredentials(self.mocker.mock()) |
502 | + token = client.find_credentials("token_name") |
503 | + self.assertEqual(token, expected_token) |
504 | + |
505 | + def test_credentials_not_found(self): |
506 | + """find_credentials immediately returns '' when no token found.""" |
507 | + expected_token = "" |
508 | + kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token") |
509 | + kgt(ARGS) |
510 | + self.mocker.result(None) |
511 | + self.mocker.replay() |
512 | + |
513 | + client = SSOCredentials(self.mocker.mock()) |
514 | + token = client.find_credentials("token_name") |
515 | + self.assertEqual(token, expected_token) |
516 | + |
517 | + def test_login_or_register(self): |
518 | + """login_or_register_... throws the signal when token is found.""" |
519 | + expected_token = "expected token" |
520 | + d = Deferred() |
521 | + |
522 | + def verify(result): |
523 | + self.assertEqual(result, expected_token) |
524 | + d.callback("ok") |
525 | + |
526 | + kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token") |
527 | + kgt(ARGS) |
528 | + self.mocker.result(expected_token) |
529 | + self.mocker.replay() |
530 | + client = SSOCredentials(self.mocker.mock()) |
531 | + self.patch(client, "_show_login_or_register_ui", self.fail) |
532 | + self.patch(client, "CredentialsFound", verify) |
533 | + self.patch(client, "CredentialsError", self.fail) |
534 | + client.login_or_register_to_get_credentials("token name", "tcurl") |
535 | + return d |
536 | + |
537 | + def test_login_or_register_not_found(self): |
538 | + """Check that login_or_register_... opens the ui when no cred found.""" |
539 | + token_name = "token name" |
540 | + d = Deferred() |
541 | + |
542 | + def verify(result, *a): |
543 | + self.assertEqual(result, token_name) |
544 | + d.callback("ok") |
545 | + |
546 | + kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token") |
547 | + kgt(ARGS) |
548 | + self.mocker.result(None) |
549 | + self.mocker.replay() |
550 | + |
551 | + client = SSOCredentials(self.mocker.mock()) |
552 | + self.patch(client, "_show_login_or_register_ui", verify) |
553 | + self.patch(client, "CredentialsFound", self.fail) |
554 | + self.patch(client, "CredentialsError", self.fail) |
555 | + client.login_or_register_to_get_credentials(token_name, "tcurl") |
556 | + return d |
557 | + |
558 | + def test_login_or_register_problem(self): |
559 | + """login_or_register_... returns the right signal on error.""" |
560 | + expected_error = "Sample Error - not for resale" |
561 | + d = Deferred() |
562 | + |
563 | + def verify(result, *a): |
564 | + self.assertEqual(result, expected_error) |
565 | + d.callback("ok") |
566 | + |
567 | + kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token") |
568 | + kgt(ARGS) |
569 | + self.mocker.throw(RegisterSampleException(expected_error)) |
570 | + self.mocker.replay() |
571 | + |
572 | + client = SSOCredentials(self.mocker.mock()) |
573 | + self.patch(client, "_show_login_or_register_ui", self.fail) |
574 | + self.patch(client, "CredentialsFound", self.fail) |
575 | + self.patch(client, "CredentialsError", verify) |
576 | + client.login_or_register_to_get_credentials("token name", "tcurl") |
577 | + return d |
keyring.py needs tests but they are coming on a different branch.