Merge lp:~nataliabidart/ubuntuone-control-panel/new-sso-iface into lp:ubuntuone-control-panel

Proposed by Natalia Bidart on 2010-12-18
Status: Merged
Approved by: Natalia Bidart on 2010-12-20
Approved revision: 37
Merged at revision: 37
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/new-sso-iface
Merge into: lp:ubuntuone-control-panel
Diff against target: 406 lines (+199/-92)
4 files modified
ubuntuone/controlpanel/backend.py (+1/-1)
ubuntuone/controlpanel/dbus_client.py (+63/-11)
ubuntuone/controlpanel/integrationtests/test_dbus_client_sso.py (+128/-80)
ubuntuone/controlpanel/tests/test_backend.py (+7/-0)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/new-sso-iface
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve on 2010-12-20
Roberto Alsina (community) 2010-12-18 Approve on 2010-12-20
Review via email: mp+44137@code.launchpad.net

Commit Message

* Migrated dbus_client to use non-deprectaed SSO D-Bus API.
* Added clear_credentials to dbus_client module.

Description of the Change

To run tests:

./run-tests

To post a comment you must log in.
Roberto Alsina (ralsina) wrote :

Looks good to me.

review: Approve
Manuel de la Peña (mandel) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntuone/controlpanel/backend.py'
2--- ubuntuone/controlpanel/backend.py 2010-12-16 21:09:46 +0000
3+++ ubuntuone/controlpanel/backend.py 2010-12-18 17:36:06 +0000
4@@ -120,7 +120,7 @@
5
6 @inlineCallbacks
7 def get_token(self):
8- """Return the token from the credentials"""
9+ """Return the token from the credentials."""
10 credentials = yield dbus_client.get_credentials()
11 returnValue(credentials["token"])
12
13
14=== modified file 'ubuntuone/controlpanel/dbus_client.py'
15--- ubuntuone/controlpanel/dbus_client.py 2010-12-13 22:13:05 +0000
16+++ ubuntuone/controlpanel/dbus_client.py 2010-12-18 17:36:06 +0000
17@@ -46,36 +46,88 @@
18 """Do nothing"""
19
20
21+def get_sso_proxy():
22+ """Get a DBus proxy for credentials management."""
23+ bus = dbus.SessionBus()
24+ obj = bus.get_object(bus_name=ubuntu_sso.DBUS_BUS_NAME,
25+ object_path=ubuntu_sso.DBUS_CREDENTIALS_PATH,
26+ follow_name_owner_changes=True)
27+ proxy = dbus.Interface(object=obj,
28+ dbus_interface=ubuntu_sso.DBUS_CREDENTIALS_IFACE)
29+ return proxy
30+
31+
32 def get_credentials():
33 """Get the credentials from the ubuntu-sso-client."""
34 d = defer.Deferred()
35- bus = dbus.SessionBus()
36- obj = bus.get_object(bus_name=ubuntu_sso.DBUS_BUS_NAME,
37- object_path=ubuntu_sso.DBUS_CRED_PATH,
38- follow_name_owner_changes=True)
39- proxy = dbus.Interface(object=obj,
40- dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME)
41+ proxy = get_sso_proxy()
42
43 def found_credentials(app_name, creds):
44 """Credentials have been found."""
45+ logger.debug('credentials were found for app_name %r.', app_name)
46 if app_name == APP_NAME:
47+ logger.info('credentials were found! (%r).', APP_NAME)
48 d.callback(creds)
49
50- def credentials_error(app_name, error_message, detailed_error):
51+ def credentials_error(app_name, error_dict=None):
52 """No credentials could be retrieved."""
53 if app_name == APP_NAME:
54- error = CredentialsError(app_name, error_message, detailed_error)
55+ if error_dict is None:
56+ error_dict = {'error_message': 'Credentials were not found.',
57+ 'detailed_error': ''}
58+
59+ logger.error('credentials error (%r, %r).', app_name, error_dict)
60+ error = CredentialsError(app_name, error_dict)
61 d.errback(error)
62
63 foundsig = proxy.connect_to_signal("CredentialsFound", found_credentials)
64+ notfoundsig = proxy.connect_to_signal("CredentialsNotFound",
65+ credentials_error)
66 errorsig = proxy.connect_to_signal("CredentialsError", credentials_error)
67- proxy.login_or_register_to_get_credentials(APP_NAME, "tcurl", "help", 0,
68- reply_handler=no_op,
69- error_handler=d.errback)
70+ logger.debug('calling get_credentials.')
71+ proxy.find_credentials(APP_NAME, {'': ''},
72+ reply_handler=no_op, error_handler=d.errback)
73
74 def cleanup_signals(result):
75 """Remove signals after use."""
76 foundsig.remove()
77+ notfoundsig.remove()
78+ errorsig.remove()
79+ return result
80+
81+ d.addBoth(cleanup_signals)
82+ return d
83+
84+
85+def clear_credentials():
86+ """Clear the credentials using the ubuntu-sso-client."""
87+ d = defer.Deferred()
88+ proxy = get_sso_proxy()
89+
90+ def credentials_cleared(app_name):
91+ """Credentials have been cleared."""
92+ logger.debug('credentials were cleared for app_name %r.', app_name)
93+ if app_name == APP_NAME:
94+ logger.info('credentials were cleared! (%r).', APP_NAME)
95+ d.callback(app_name)
96+
97+ def credentials_error(app_name, error_dict=None):
98+ """No credentials could be retrieved."""
99+ if app_name == APP_NAME:
100+ logger.error('credentials error (%r, %r).', app_name, error_dict)
101+ error = CredentialsError(app_name, error_dict)
102+ d.errback(error)
103+
104+ clearedsig = proxy.connect_to_signal("CredentialsCleared",
105+ credentials_cleared)
106+ errorsig = proxy.connect_to_signal("CredentialsError", credentials_error)
107+ logger.warning('calling clear_credentials.')
108+ proxy.clear_credentials(APP_NAME, {'': ''},
109+ reply_handler=no_op, error_handler=d.errback)
110+
111+ def cleanup_signals(result):
112+ """Remove signals after use."""
113+ clearedsig.remove()
114 errorsig.remove()
115 return result
116
117
118=== modified file 'ubuntuone/controlpanel/integrationtests/test_dbus_client_sso.py'
119--- ubuntuone/controlpanel/integrationtests/test_dbus_client_sso.py 2010-12-02 16:23:03 +0000
120+++ ubuntuone/controlpanel/integrationtests/test_dbus_client_sso.py 2010-12-18 17:36:06 +0000
121@@ -23,8 +23,9 @@
122 # DBus signals have CamelCased names
123
124 import dbus
125-import ubuntu_sso
126
127+from ubuntu_sso import (DBUS_BUS_NAME,
128+ DBUS_CREDENTIALS_PATH, DBUS_CREDENTIALS_IFACE)
129 from twisted.internet.defer import inlineCallbacks
130
131 from ubuntuone.controlpanel import dbus_client
132@@ -36,6 +37,8 @@
133 "token": "ABCDEF12345678",
134 "access_token": "DEADCAFE2010",
135 }
136+OTHER_CREDS = {"token": "other!"}
137+SAMPLE_ERROR = {"error message": "test", "detailed_error": "error details"}
138
139 # pylint: disable=C0322
140 # pylint, you have to go to decorator's school
141@@ -44,116 +47,161 @@
142 class MockDBusSSOService(dbus.service.Object):
143 """A mock object that mimicks ussoc."""
144
145- @dbus.service.method(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
146- in_signature="sssx")
147- def login_or_register_to_get_credentials(self, app_name, tcurl, hlp, wid):
148- """Get creds from the keyring, login/register if needed."""
149- self.CredentialsFound(app_name, SAMPLE_CREDS)
150-
151- @dbus.service.signal(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
152- signature="sa{ss}")
153- def CredentialsFound(self, app_name, credentials):
154- """Credentials were finally found."""
155-
156-
157-class MockDBusSSOServiceOther(dbus.service.Object):
158- """A mock object that mimicks ussoc."""
159-
160- @dbus.service.method(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
161- in_signature="sssx")
162- def login_or_register_to_get_credentials(self, app_name, tcurl, hlp, wid):
163- """Get creds from the keyring, login/register if needed."""
164- self.CredentialsFound("wrong app name", {})
165- self.CredentialsFound(app_name, SAMPLE_CREDS)
166-
167- @dbus.service.signal(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
168- signature="sa{ss}")
169- def CredentialsFound(self, app_name, credentials):
170- """Credentials were finally found."""
171-
172-
173-class MockDBusSSOClientOtherFailing(dbus.service.Object):
174- """A mock object that mimicks ussoc."""
175-
176- @dbus.service.method(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
177- in_signature="sssx")
178- def login_or_register_to_get_credentials(self, app_name, tcurl, hlp, wid):
179- """Get creds from the keyring, login/register if needed."""
180- self.CredentialsError("wrong app", "error message", "error details")
181- self.CredentialsFound(app_name, SAMPLE_CREDS)
182-
183- @dbus.service.signal(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
184- signature="sa{ss}")
185- def CredentialsFound(self, app_name, credentials):
186- """Credentials were finally found."""
187-
188- @dbus.service.signal(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
189- signature="sss")
190- def CredentialsError(self, app_name, error_message, detailed_error):
191- """Some error happened and credentials were not found."""
192-
193-
194-class MockDBusSSOClientFailing(dbus.service.Object):
195- """A mock object that mimicks ussoc but fails."""
196-
197- @dbus.service.method(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
198- in_signature="sssx")
199- def login_or_register_to_get_credentials(self, app_name, tcurl, hlp, wid):
200- """Fail while trying to get creds from the keyring."""
201- self.CredentialsError(app_name, "error message", "error details")
202-
203- @dbus.service.signal(dbus_interface=ubuntu_sso.DBUS_IFACE_CRED_NAME,
204- signature="sss")
205- def CredentialsError(self, app_name, error_message, detailed_error):
206- """Some error happened and credentials were not found."""
207+ found = True
208+ wrong_app = None
209+ error = None
210+
211+ @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
212+ in_signature='sa{ss}', out_signature='')
213+ def find_credentials(self, app_name, args):
214+ """Get creds from the keyring, login/register if needed."""
215+ if self.wrong_app is None and self.error is None:
216+ if self.found:
217+ self.CredentialsFound(app_name, SAMPLE_CREDS)
218+ else:
219+ self.CredentialsNotFound(app_name)
220+ elif self.wrong_app is not None and self.error is None:
221+ self.CredentialsFound(self.wrong_app, OTHER_CREDS)
222+ elif self.wrong_app is None and self.error is not None:
223+ self.CredentialsError(app_name, self.error)
224+ else:
225+ self.CredentialsError(self.wrong_app, self.error)
226+
227+ self.CredentialsFound(app_name, SAMPLE_CREDS)
228+
229+ @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
230+ in_signature='sa{ss}', out_signature='')
231+ def clear_credentials(self, app_name, args):
232+ """Clear the credentials for an application."""
233+ self.found = False
234+
235+ if self.wrong_app is None and self.error is None:
236+ self.CredentialsCleared(app_name)
237+ elif self.wrong_app is not None and self.error is None:
238+ self.CredentialsCleared(self.wrong_app)
239+ elif self.wrong_app is None and self.error is not None:
240+ self.CredentialsError(app_name, self.error)
241+ else:
242+ self.CredentialsError(self.wrong_app, self.error)
243+
244+ self.CredentialsCleared(app_name)
245+
246+ @dbus.service.signal(DBUS_CREDENTIALS_IFACE, signature='sa{ss}')
247+ def CredentialsFound(self, app_name, credentials):
248+ """Signal thrown when the credentials are found."""
249+
250+ @dbus.service.signal(DBUS_CREDENTIALS_IFACE, signature='s')
251+ def CredentialsNotFound(self, app_name):
252+ """Signal thrown when the credentials are not found."""
253+
254+ @dbus.service.signal(DBUS_CREDENTIALS_IFACE, signature='s')
255+ def CredentialsCleared(self, app_name):
256+ """Signal thrown when the credentials were cleared."""
257+
258+ @dbus.service.signal(DBUS_CREDENTIALS_IFACE, signature='s')
259+ def CredentialsStored(self, app_name):
260+ """Signal thrown when the credentials were cleared."""
261+
262+ @dbus.service.signal(DBUS_CREDENTIALS_IFACE, signature='sa{ss}')
263+ def CredentialsError(self, app_name, error_dict):
264+ """Signal thrown when there is a problem getting the credentials."""
265
266
267 class SSOClientTestCase(DBusClientTestCase):
268 """Test for the SSO dbus client."""
269
270+ def setUp(self):
271+ super(SSOClientTestCase, self).setUp()
272+ self.register_mockserver(DBUS_BUS_NAME, DBUS_CREDENTIALS_PATH,
273+ MockDBusSSOService)
274+ MockDBusSSOService.wrong_app = None
275+ MockDBusSSOService.error = None
276+ MockDBusSSOService.found = True
277+
278+ # get_credentials
279+
280 @inlineCallbacks
281 def test_get_credentials_ok(self):
282 """Test the success case for get_credentials."""
283- self.register_mockserver(ubuntu_sso.DBUS_BUS_NAME,
284- ubuntu_sso.DBUS_CRED_PATH, MockDBusSSOService)
285 creds = yield dbus_client.get_credentials()
286 self.assertEqual(creds, SAMPLE_CREDS)
287
288 @inlineCallbacks
289+ def test_get_credentials_not_found(self):
290+ """Credentials were not found."""
291+ yield dbus_client.clear_credentials() # not found will be sent
292+ yield self.assertFailure(dbus_client.get_credentials(),
293+ dbus_client.CredentialsError)
294+
295+ @inlineCallbacks
296 def test_get_credentials_other(self):
297 """Creds for other apps are ignored."""
298- self.register_mockserver(ubuntu_sso.DBUS_BUS_NAME,
299- ubuntu_sso.DBUS_CRED_PATH,
300- MockDBusSSOServiceOther)
301+ MockDBusSSOService.wrong_app = 'other app!'
302 creds = yield dbus_client.get_credentials()
303 self.assertEqual(creds, SAMPLE_CREDS)
304
305 @inlineCallbacks
306 def test_get_credentials_error(self):
307 """Test what happens when the creds can't be retrieved."""
308- self.register_mockserver(ubuntu_sso.DBUS_BUS_NAME,
309- ubuntu_sso.DBUS_CRED_PATH,
310- MockDBusSSOClientFailing)
311-
312+ MockDBusSSOService.error = SAMPLE_ERROR
313 yield self.assertFailure(dbus_client.get_credentials(),
314 dbus_client.CredentialsError)
315
316 @inlineCallbacks
317 def test_get_credentials_other_error(self):
318 """Other creds err before ours are retrieved."""
319- self.register_mockserver(ubuntu_sso.DBUS_BUS_NAME,
320- ubuntu_sso.DBUS_CRED_PATH,
321- MockDBusSSOClientOtherFailing)
322-
323+ MockDBusSSOService.wrong_app = 'other app!'
324+ MockDBusSSOService.error = SAMPLE_ERROR
325 creds = yield dbus_client.get_credentials()
326 self.assertEqual(creds, SAMPLE_CREDS)
327
328+ # clear_credentials
329+
330+ @inlineCallbacks
331+ def test_clear_credentials_ok(self):
332+ """Test the success case for clear_credentials."""
333+ result = yield dbus_client.clear_credentials()
334+ self.assertEqual(result, dbus_client.APP_NAME)
335+
336+ @inlineCallbacks
337+ def test_clear_credentials_other(self):
338+ """Creds for other apps are ignored."""
339+ MockDBusSSOService.wrong_app = 'other app!'
340+ result = yield dbus_client.clear_credentials()
341+ self.assertEqual(result, dbus_client.APP_NAME)
342+
343+ @inlineCallbacks
344+ def test_clear_credentials_error(self):
345+ """Test what happens when the creds can't be retrieved."""
346+ MockDBusSSOService.error = SAMPLE_ERROR
347+ yield self.assertFailure(dbus_client.clear_credentials(),
348+ dbus_client.CredentialsError)
349+
350+ @inlineCallbacks
351+ def test_clear_credentials_other_error(self):
352+ """Other creds err before ours are retrieved."""
353+ MockDBusSSOService.wrong_app = 'other app!'
354+ MockDBusSSOService.error = SAMPLE_ERROR
355+ result = yield dbus_client.clear_credentials()
356+ self.assertEqual(result, dbus_client.APP_NAME)
357+
358+
359+class NoMethodsSSOClientTestCase(DBusClientTestCase):
360+ """Test for the SSO dbus client when the service provides no methods."""
361+
362+ def setUp(self):
363+ super(NoMethodsSSOClientTestCase, self).setUp()
364+ self.register_mockserver(DBUS_BUS_NAME, DBUS_CREDENTIALS_PATH,
365+ MockDBusNoMethods)
366+
367 @inlineCallbacks
368 def test_get_credentials_dbus_error(self):
369 """Test what happens when there's a DBus error."""
370- self.register_mockserver(ubuntu_sso.DBUS_BUS_NAME,
371- ubuntu_sso.DBUS_CRED_PATH,
372- MockDBusNoMethods)
373+ yield self.assertFailure(dbus_client.get_credentials(),
374+ dbus.DBusException)
375
376- yield self.assertFailure(dbus_client.get_credentials(),
377+ @inlineCallbacks
378+ def test_clear_credentials_dbus_error(self):
379+ """Test what happens when there's a DBus error."""
380+ yield self.assertFailure(dbus_client.clear_credentials(),
381 dbus.DBusException)
382
383=== modified file 'ubuntuone/controlpanel/tests/test_backend.py'
384--- ubuntuone/controlpanel/tests/test_backend.py 2010-12-16 21:01:43 +0000
385+++ ubuntuone/controlpanel/tests/test_backend.py 2010-12-18 17:36:06 +0000
386@@ -211,6 +211,11 @@
387 """Return the mock credentials."""
388 return defer.succeed(self.creds)
389
390+ def clear_credentials(self):
391+ """Clear the mock credentials."""
392+ MockDBusClient.creds = None
393+ return defer.succeed(None)
394+
395 def get_throttling_limits(self):
396 """Return the sample speed limits."""
397 return self.limits
398@@ -284,6 +289,8 @@
399 self.memento = MementoHandler()
400 backend.logger.addHandler(self.memento)
401
402+ MockDBusClient.creds = SAMPLE_CREDENTIALS
403+
404 def test_backend_creation(self):
405 """The backend instance is successfully created."""
406 self.assertEqual(self.be.wc.__class__, MockWebClient)

Subscribers

People subscribed via source and target branches