Merge lp:~alecu/ubuntu-sso-client/credentials-interface into lp:ubuntu-sso-client

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
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

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

keyring.py needs tests but they are coming on a different branch.

review: Approve
565. By Alejandro J. Cura

do not store the keyring tokens yet

Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :

Looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bin/ubuntu-sso-login'
--- bin/ubuntu-sso-login 2010-08-03 20:03:44 +0000
+++ bin/ubuntu-sso-login 2010-08-06 02:49:40 +0000
@@ -30,12 +30,13 @@
3030
31from dbus.mainloop.glib import DBusGMainLoop31from dbus.mainloop.glib import DBusGMainLoop
3232
33from ubuntu_sso import DBUS_IFACE_AUTH_NAME, DBUS_BUS_NAME33from ubuntu_sso import DBUS_IFACE_AUTH_NAME, DBUS_BUS_NAME, DBUS_CRED_PATH
34from ubuntu_sso.main import Login, SSOLogin34from ubuntu_sso.main import Login, SSOLogin, SSOCredentials
3535
36from ubuntu_sso.logger import setupLogging36from ubuntu_sso.logger import setupLogging
37logger = setupLogging("ubuntu-sso-login")37logger = setupLogging("ubuntu-sso-login")
3838
39gtk.gdk.threads_init()
39DBusGMainLoop(set_as_default=True)40DBusGMainLoop(set_as_default=True)
4041
41_ = gettext.gettext42_ = gettext.gettext
@@ -235,5 +236,9 @@
235 bus=dbus.SessionBus()))236 bus=dbus.SessionBus()))
236 ssoLogin = SSOLogin(dbus.service.BusName(DBUS_BUS_NAME,237 ssoLogin = SSOLogin(dbus.service.BusName(DBUS_BUS_NAME,
237 bus=dbus.SessionBus()))238 bus=dbus.SessionBus()))
239 SSOCredentials(dbus.service.BusName(DBUS_BUS_NAME,
240 bus=dbus.SessionBus()),
241 object_path=DBUS_CRED_PATH)
242
238 manager = LoginMain()243 manager = LoginMain()
239 manager.main()244 manager.main()
240245
=== modified file 'ubuntu_sso/__init__.py'
--- ubuntu_sso/__init__.py 2010-08-03 15:02:15 +0000
+++ ubuntu_sso/__init__.py 2010-08-06 02:49:40 +0000
@@ -19,6 +19,7 @@
19DBUS_PATH_AUTH = "/"19DBUS_PATH_AUTH = "/"
20DBUS_BUS_NAME = "com.ubuntu.sso"20DBUS_BUS_NAME = "com.ubuntu.sso"
21DBUS_PATH = "/sso"21DBUS_PATH = "/sso"
22DBUS_CRED_PATH = "/credentials"
22DBUS_IFACE_AUTH_NAME = "com.ubuntu.sso"23DBUS_IFACE_AUTH_NAME = "com.ubuntu.sso"
23DBUS_IFACE_USER_NAME = "com.ubuntu.sso.UserManagement"24DBUS_IFACE_USER_NAME = "com.ubuntu.sso.UserManagement"
24DBUS_IFACE_CRED_NAME = "com.ubuntu.sso.ApplicationCredentials"25DBUS_IFACE_CRED_NAME = "com.ubuntu.sso.ApplicationCredentials"
2526
=== added file 'ubuntu_sso/keyring.py'
--- ubuntu_sso/keyring.py 1970-01-01 00:00:00 +0000
+++ ubuntu_sso/keyring.py 2010-08-06 02:49:40 +0000
@@ -0,0 +1,111 @@
1# Copyright (C) 2010 Canonical
2#
3# Authors:
4# Andrew Higginson
5#
6# This program is free software; you can redistribute it and/or modify it under
7# the terms of the GNU General Public License as published by the Free Software
8# Foundation; version 3.
9#
10# This program is distributed in the hope that it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13# details.
14#
15# You should have received a copy of the GNU General Public License along with
16# this program; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19import gnomekeyring
20
21from urllib import urlencode
22from urlparse import parse_qs
23
24class Keyring(object):
25
26 KEYRING_NAME = "login"
27
28 def __init__(self, app_name):
29
30 if not gnomekeyring.is_available():
31 raise gnomekeyring.NoKeyringDaemonError
32 self.app_name = app_name
33
34 def _create_keyring(self, name):
35 """
36 Creates a keyring, if it already exists,
37 it does nothing
38 """
39 keyring_names = gnomekeyring.list_keyring_names_sync()
40 if not name in keyring_names:
41 gnomekeyring.create_sync(name)
42
43 def _item_exists(self, sync, name):
44 """
45 Returns whether a named item exists in a
46 named keyring
47 """
48 return self._get_item_id_from_name(sync, name) != None
49
50 def _get_item_id_from_name(self, sync, name):
51 """
52 Returns the ID for a named item
53 """
54 for item_id in gnomekeyring.list_item_ids_sync(sync):
55 item_info = gnomekeyring.item_get_info_sync(sync, item_id)
56 display_name = item_info.get_display_name()
57 if display_name == name:
58 return item_id
59 return None
60
61 def _get_item_info_from_name(self, sync, name):
62 """
63 Returns the ID for a named item
64 """
65 for item_id in gnomekeyring.list_item_ids_sync(sync):
66 item_info = gnomekeyring.item_get_info_sync(sync, item_id)
67 display_name = item_info.get_display_name()
68 if display_name == name:
69 return item_info
70 return None
71
72 def set_ubuntusso_attr(self, attr):
73 """
74 Sets the attributes of the Ubuntu SSO item
75 """
76 # Creates the secret from the attributes
77 secret = urlencode(attr)
78
79 # Create the keyring
80 self._create_keyring(self.KEYRING_NAME)
81
82 # If the item already exists, delete it
83 if self._item_exists(self.KEYRING_NAME, self.app_name):
84 item_id = self._get_item_id_from_name(self.KEYRING_NAME,
85 self.app_name)
86 gnomekeyring.item_delete_sync(self.KEYRING_NAME, item_id)
87
88 # Add our SSO item
89 gnomekeyring.item_create_sync(self.KEYRING_NAME,
90 gnomekeyring.ITEM_GENERIC_SECRET, self.app_name, {},
91 secret, True)
92
93 def get_ubuntusso_attr(self):
94 """
95 Returns the secret of the SSO item in a dictionary
96 """
97 # If we have no attributes, return None
98 if self._get_item_info_from_name(self.KEYRING_NAME,
99 self.app_name) == None:
100 return None
101 secret = self._get_item_info_from_name(self.KEYRING_NAME,
102 self.app_name).get_secret()
103 return parse_qs(secret)
104
105if __name__ == "__main__":
106 SSO_ITEM_NAME = "Software Center UbuntuSSO token"
107 keyring = Keyring(SSO_ITEM_NAME)
108 keyring.set_ubuntusso_attr({"ha":"hehddddeff", "hi":"hggehes", "ho":"he"})
109 print keyring.get_ubuntusso_attr()
110
111
0112
=== modified file 'ubuntu_sso/main.py'
--- ubuntu_sso/main.py 2010-08-05 02:24:33 +0000
+++ ubuntu_sso/main.py 2010-08-06 02:49:40 +0000
@@ -34,6 +34,7 @@
3434
35import dbus.service35import dbus.service
36import gobject36import gobject
37import gtk
37import pynotify38import pynotify
3839
39from dbus.mainloop.glib import DBusGMainLoop40from dbus.mainloop.glib import DBusGMainLoop
@@ -43,20 +44,18 @@
43from lazr.restfulclient.resource import ServiceRoot44from lazr.restfulclient.resource import ServiceRoot
44from oauth.oauth import OAuthToken45from oauth.oauth import OAuthToken
4546
47from keyring import Keyring
46from ubuntu_sso import (DBUS_IFACE_AUTH_NAME,48from ubuntu_sso import (DBUS_IFACE_AUTH_NAME,
47 DBUS_IFACE_USER_NAME,49 DBUS_IFACE_USER_NAME,
48 DBUS_IFACE_CRED_NAME,50 DBUS_IFACE_CRED_NAME,
51 DBUS_CRED_PATH,
49 DBUS_BUS_NAME)52 DBUS_BUS_NAME)
50from ubuntu_sso.config import get_config53from ubuntu_sso.config import get_config
5154
52from ubuntu_sso.logger import setupLogging55from ubuntu_sso.logger import setupLogging
53logger = setupLogging("ubuntu_sso.main")56logger = setupLogging("ubuntu_sso.main")
5457
55
56DBusGMainLoop(set_as_default=True)58DBusGMainLoop(set_as_default=True)
57dbus.mainloop.glib.threads_init()
58gobject.threads_init()
59
60# Disable the invalid name warning, as we have a lot of DBus style names59# Disable the invalid name warning, as we have a lot of DBus style names
61# pylint: disable-msg=C010360# pylint: disable-msg=C0103
6261
@@ -92,6 +91,21 @@
92 """The email token is not valid."""91 """The email token is not valid."""
9392
9493
94def keyring_store_token(token_name, token):
95 """Store the credentials in the keyring."""
96 attr = {"token": token}
97 Keyring(token_name).set_ubuntusso_attr(attr)
98
99
100def keyring_get_token(token_name):
101 """Get the credentials from the keyring or None if not there."""
102 d = Keyring(token_name).get_ubuntusso_attr()
103 if d is not None:
104 return d["token"]
105 else:
106 return None
107
108
95class SSOLoginProcessor(object):109class SSOLoginProcessor(object):
96 """Login and register users using the Ubuntu Single Sign On service."""110 """Login and register users using the Ubuntu Single Sign On service."""
97111
@@ -208,7 +222,7 @@
208 try:222 try:
209 result_cb(f())223 result_cb(f())
210 except Exception, e:224 except Exception, e:
211 logger.error(e)225 logger.exception(e)
212 error_cb(str(e))226 error_cb(str(e))
213 threading.Thread(target=_in_thread).start()227 threading.Thread(target=_in_thread).start()
214228
@@ -230,9 +244,6 @@
230 return self.sso_login_processor_class(244 return self.sso_login_processor_class(
231 sso_service_class=self.sso_service_class)245 sso_service_class=self.sso_service_class)
232246
233 # ========================================
234 # DBUS_IFACE_USER_NAME methods and signals
235
236 # generate_capcha signals247 # generate_capcha signals
237 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="s")248 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="s")
238 def CaptchaGenerated(self, result):249 def CaptchaGenerated(self, result):
@@ -285,7 +296,10 @@
285 """Call the matching method in the processor."""296 """Call the matching method in the processor."""
286 def f():297 def f():
287 """Inner function that will be run in a thread."""298 """Inner function that will be run in a thread."""
288 return self.processor().login(email, password, token_name)299 token = self.processor().login(email, password, token_name)
300 # XXX: will be fixed in upcoming branch
301 #keyring_store_token(token_name, token)
302 return "Ok"
289 return blocking(f, self.LoggedIn, self.LoginError)303 return blocking(f, self.LoggedIn, self.LoginError)
290304
291 # validate_email signals305 # validate_email signals
@@ -307,8 +321,9 @@
307 token_name, email_token)321 token_name, email_token)
308 return blocking(f, self.EmailValidated, self.EmailValidationError)322 return blocking(f, self.EmailValidated, self.EmailValidationError)
309323
310 # ----------------------------------------324
311 # DBUS_IFACE_CRED_NAME methods and signals325class SSOCredentials(dbus.service.Object):
326 """DBus object that gets credentials, and login/registers if needed."""
312327
313 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="s")328 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="s")
314 def CredentialsFound(self, result):329 def CredentialsFound(self, result):
@@ -319,17 +334,53 @@
319 """Signal thrown when there is a problem finding the credentials."""334 """Signal thrown when there is a problem finding the credentials."""
320335
321 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,336 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,
322 in_signature="s", out_signature="")337 in_signature="s", out_signature="s")
323 def find_credentials(self, application_name):338 def find_credentials(self, token_name):
324 # XXX: placeholder; coming in the following branch339 """Get the credentials from the keyring or '' if not there."""
325 pass340 token = keyring_get_token(token_name)
341 if token is None:
342 return ""
343 else:
344 return token
345
346 def _response_cb(self, dialog, response, token_name):
347 """Handles the response from the UI dialog."""
348 # XXX: to be replaced in the following branch
349 try:
350 token = "token%d" % response
351 keyring_store_token(token_name, token)
352 self.CredentialsFound(token)
353 except Exception, e:
354 self.CredentialsError(str(e))
355 dialog.destroy()
356
357 def _show_login_or_register_ui(self, token_name, terms_and_conditions_url):
358 """Shows the UI so the user can login or register."""
359 # XXX: to be replaced in the following branch
360 try:
361 dialog = gtk.MessageDialog(None,
362 gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO,
363 gtk.BUTTONS_CLOSE, terms_and_conditions_url)
364 dialog.connect("response", self._response_cb, token_name)
365 dialog.show()
366 except Exception, e:
367 self.CredentialsError(str(e))
326368
327 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,369 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,
328 in_signature="ss", out_signature="")370 in_signature="ss", out_signature="")
329 def login_or_register_to_get_credentials(self, application_name,371 def login_or_register_to_get_credentials(self, token_name,
330 terms_and_conditions_url):372 terms_and_conditions_url):
331 # XXX: placeholder; coming in the following branch373
332 pass374 """Get credentials if found else prompt to login or register first."""
375 try:
376 token = keyring_get_token(token_name)
377 if token is None:
378 gobject.idle_add(self._show_login_or_register_ui, token_name,
379 terms_and_conditions_url)
380 else:
381 self.CredentialsFound(token)
382 except Exception, e:
383 self.CredentialsError(str(e))
333384
334385
335class LoginProcessor:386class LoginProcessor:
@@ -558,6 +609,8 @@
558609
559def main():610def main():
560 """Start everything"""611 """Start everything"""
612 dbus.mainloop.glib.threads_init()
613 gobject.threads_init()
561 logger.debug("Starting up at %s", time.asctime())614 logger.debug("Starting up at %s", time.asctime())
562 logger.debug("Installing the Twisted glib2reactor")615 logger.debug("Installing the Twisted glib2reactor")
563 from twisted.internet import glib2reactor # for non-GUI apps616 from twisted.internet import glib2reactor # for non-GUI apps
@@ -569,6 +622,9 @@
569 bus=dbus.SessionBus()))622 bus=dbus.SessionBus()))
570 SSOLogin(dbus.service.BusName(DBUS_BUS_NAME,623 SSOLogin(dbus.service.BusName(DBUS_BUS_NAME,
571 bus=dbus.SessionBus()))624 bus=dbus.SessionBus()))
625 SSOCredentials(dbus.service.BusName(DBUS_BUS_NAME,
626 bus=dbus.SessionBus()),
627 object_path=DBUS_CRED_PATH)
572 # cleverness here to say:628 # cleverness here to say:
573 # am I already running (bound to this d-bus name)?629 # am I already running (bound to this d-bus name)?
574 # if so, send a signal to the already running instance630 # if so, send a signal to the already running instance
575631
=== modified file 'ubuntu_sso/tests/test_gui.py'
--- ubuntu_sso/tests/test_gui.py 2010-08-05 02:24:33 +0000
+++ ubuntu_sso/tests/test_gui.py 2010-08-06 02:49:40 +0000
@@ -46,12 +46,6 @@
46EMAIL_TOKEN = 'B2Pgtf'46EMAIL_TOKEN = 'B2Pgtf'
4747
4848
49def process_pending():
50 """Process all the pending GTK events."""
51 while gtk.events_pending():
52 gtk.main_iteration()
53
54
55class FakedSSOBackend(object):49class FakedSSOBackend(object):
56 """Fake a SSO Backend (acts as a dbus.Interface as well)."""50 """Fake a SSO Backend (acts as a dbus.Interface as well)."""
5751
@@ -149,7 +143,6 @@
149 """Grab focus on widget, if None use self.entry."""143 """Grab focus on widget, if None use self.entry."""
150 direction = 'in' if focus_in else 'out'144 direction = 'in' if focus_in else 'out'
151 self.entry.emit('focus-%s-event' % direction, None)145 self.entry.emit('focus-%s-event' % direction, None)
152 process_pending()
153146
154 def assert_correct_label(self):147 def assert_correct_label(self):
155 """Check that the entry has the correct label."""148 """Check that the entry has the correct label."""
@@ -212,7 +205,6 @@
212 self.grab_focus() # grab focus205 self.grab_focus() # grab focus
213206
214 self.entry.set_text(' ') # add empty text to the entry207 self.entry.set_text(' ') # add empty text to the entry
215 process_pending()
216208
217 self.grab_focus(focus_in=False) # loose focus209 self.grab_focus(focus_in=False) # loose focus
218210
@@ -227,7 +219,6 @@
227 self.grab_focus() # grab focus219 self.grab_focus() # grab focus
228220
229 self.entry.set_text(expected) # add empty text to the entry221 self.entry.set_text(expected) # add empty text to the entry
230 process_pending()
231222
232 self.grab_focus(focus_in=False) # loose focus223 self.grab_focus(focus_in=False) # loose focus
233224
@@ -241,7 +232,6 @@
241 self.grab_focus() # grab focus232 self.grab_focus() # grab focus
242233
243 self.entry.set_text(expected) # add text to the entry234 self.entry.set_text(expected) # add text to the entry
244 process_pending()
245235
246 self.grab_focus(focus_in=False) # loose focus236 self.grab_focus(focus_in=False) # loose focus
247 self.grab_focus() # grab focus again!237 self.grab_focus() # grab focus again!
248238
=== modified file 'ubuntu_sso/tests/test_main.py'
--- ubuntu_sso/tests/test_main.py 2010-08-04 00:10:14 +0000
+++ ubuntu_sso/tests/test_main.py 2010-08-06 02:49:40 +0000
@@ -31,7 +31,8 @@
31from ubuntu_sso import config31from ubuntu_sso import config
32from ubuntu_sso.main import (32from ubuntu_sso.main import (
33 AuthenticationError, BadRealmError, blocking, EmailTokenError,33 AuthenticationError, BadRealmError, blocking, EmailTokenError,
34 InvalidEmailError, InvalidPasswordError, SSOLogin,34 InvalidEmailError, InvalidPasswordError, SSOLogin, SSOCredentials,
35 keyring_get_token, keyring_store_token,
35 LoginProcessor, SSOLoginProcessor, RegistrationError)36 LoginProcessor, SSOLoginProcessor, RegistrationError)
3637
3738
@@ -110,7 +111,7 @@
110 self.accounts = FakedAccounts()111 self.accounts = FakedAccounts()
111112
112113
113class SSOLoginProcessorTestCase(TestCase):114class SSOLoginProcessorTestCase(TestCase, MockerTestCase):
114 """Test suite for the SSO login processor."""115 """Test suite for the SSO login processor."""
115116
116 def setUp(self):117 def setUp(self):
@@ -436,14 +437,14 @@
436 email = "sample email"437 email = "sample email"
437 password = "sample password"438 password = "sample password"
438 token_name = "sample token_name"439 token_name = "sample token_name"
439 expected_result = "expected result"440 sample_result = {"sample": "tokens"}
440 self.create_mock_processor().login(email, password, token_name)441 self.create_mock_processor().login(email, password, token_name)
441 self.mocker.result(expected_result)442 self.mocker.result(sample_result)
442 self.patch(ubuntu_sso.main, "blocking", self.fake_ok_blocking)443 self.patch(ubuntu_sso.main, "blocking", self.fake_ok_blocking)
443 self.mocker.replay()444 self.mocker.replay()
444445
445 def verify(result):446 def verify(result):
446 self.assertEqual(result, expected_result)447 self.assertEqual(result, "Ok")
447 d.callback(result)448 d.callback(result)
448449
449 client = SSOLogin(self.mockbusname,450 client = SSOLogin(self.mockbusname,
@@ -556,8 +557,148 @@
556 raise BlockingSampleException(expected_error_message)557 raise BlockingSampleException(expected_error_message)
557558
558 def verify(error):559 def verify(error):
559 self.assertEquals(error, expected_error_message)560 self.assertEqual(error, expected_error_message)
560 d.callback("Ok")561 d.callback("Ok")
561562
562 blocking(f, d.errback, verify)563 blocking(f, d.errback, verify)
563 return d564 return d
565
566
567class KeyringTokenTestCase(MockerTestCase):
568 """Checks the functions that access the keyring."""
569
570 def test_keyring_store_token(self):
571 """Verify the method that stores tokens."""
572 token_name = "token_name"
573 token_value = "token value"
574 mockKeyringClass = self.mocker.replace("ubuntu_sso.keyring.Keyring")
575 mockKeyringClass(token_name)
576 mockKeyring = self.mocker.mock()
577 self.mocker.result(mockKeyring)
578 mockKeyring.set_ubuntusso_attr({"token": token_value})
579 self.mocker.replay()
580
581 keyring_store_token(token_name, token_value)
582
583 def test_keyring_get_token(self):
584 """The method returns the right token."""
585 token_name = "token_name"
586 token_value = "token value"
587 mockKeyringClass = self.mocker.replace("ubuntu_sso.keyring.Keyring")
588 mockKeyringClass(token_name)
589 mockKeyring = self.mocker.mock()
590 self.mocker.result(mockKeyring)
591 mockKeyring.get_ubuntusso_attr()
592 self.mocker.result({"token": token_value})
593 self.mocker.replay()
594
595 token = keyring_get_token(token_name)
596 self.assertEqual(token, token_value)
597
598 def test_keyring_get_token_not_found(self):
599 """The method returns None when the token is not found."""
600 token_name = "token_name"
601 mockKeyringClass = self.mocker.replace("ubuntu_sso.keyring.Keyring")
602 mockKeyringClass(token_name)
603 mockKeyring = self.mocker.mock()
604 self.mocker.result(mockKeyring)
605 mockKeyring.get_ubuntusso_attr()
606 self.mocker.result(None)
607 self.mocker.replay()
608
609 token = keyring_get_token(token_name)
610 self.assertEqual(token, None)
611
612
613class RegisterSampleException(Exception):
614 """A mock exception thrown just when testing."""
615
616
617class CredentialsTestCase(TestCase, MockerTestCase):
618 """Tests for the credentials related DBus methods."""
619
620 def test_find_credentials(self):
621 """find_credentials immediately returns the token when found."""
622 expected_token = "expected token"
623 kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token")
624 kgt(ARGS)
625 self.mocker.result(expected_token)
626 self.mocker.replay()
627
628 client = SSOCredentials(self.mocker.mock())
629 token = client.find_credentials("token_name")
630 self.assertEqual(token, expected_token)
631
632 def test_credentials_not_found(self):
633 """find_credentials immediately returns '' when no token found."""
634 expected_token = ""
635 kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token")
636 kgt(ARGS)
637 self.mocker.result(None)
638 self.mocker.replay()
639
640 client = SSOCredentials(self.mocker.mock())
641 token = client.find_credentials("token_name")
642 self.assertEqual(token, expected_token)
643
644 def test_login_or_register(self):
645 """login_or_register_... throws the signal when token is found."""
646 expected_token = "expected token"
647 d = Deferred()
648
649 def verify(result):
650 self.assertEqual(result, expected_token)
651 d.callback("ok")
652
653 kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token")
654 kgt(ARGS)
655 self.mocker.result(expected_token)
656 self.mocker.replay()
657 client = SSOCredentials(self.mocker.mock())
658 self.patch(client, "_show_login_or_register_ui", self.fail)
659 self.patch(client, "CredentialsFound", verify)
660 self.patch(client, "CredentialsError", self.fail)
661 client.login_or_register_to_get_credentials("token name", "tcurl")
662 return d
663
664 def test_login_or_register_not_found(self):
665 """Check that login_or_register_... opens the ui when no cred found."""
666 token_name = "token name"
667 d = Deferred()
668
669 def verify(result, *a):
670 self.assertEqual(result, token_name)
671 d.callback("ok")
672
673 kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token")
674 kgt(ARGS)
675 self.mocker.result(None)
676 self.mocker.replay()
677
678 client = SSOCredentials(self.mocker.mock())
679 self.patch(client, "_show_login_or_register_ui", verify)
680 self.patch(client, "CredentialsFound", self.fail)
681 self.patch(client, "CredentialsError", self.fail)
682 client.login_or_register_to_get_credentials(token_name, "tcurl")
683 return d
684
685 def test_login_or_register_problem(self):
686 """login_or_register_... returns the right signal on error."""
687 expected_error = "Sample Error - not for resale"
688 d = Deferred()
689
690 def verify(result, *a):
691 self.assertEqual(result, expected_error)
692 d.callback("ok")
693
694 kgt = self.mocker.replace("ubuntu_sso.main.keyring_get_token")
695 kgt(ARGS)
696 self.mocker.throw(RegisterSampleException(expected_error))
697 self.mocker.replay()
698
699 client = SSOCredentials(self.mocker.mock())
700 self.patch(client, "_show_login_or_register_ui", self.fail)
701 self.patch(client, "CredentialsFound", self.fail)
702 self.patch(client, "CredentialsError", verify)
703 client.login_or_register_to_get_credentials("token name", "tcurl")
704 return d

Subscribers

People subscribed via source and target branches