Merge lp:~nataliabidart/ubuntu/natty/ubuntu-sso-client/ubuntu-sso-client-1.1.7 into lp:ubuntu/natty/ubuntu-sso-client

Proposed by Natalia Bidart
Status: Merged
Merged at revision: 22
Proposed branch: lp:~nataliabidart/ubuntu/natty/ubuntu-sso-client/ubuntu-sso-client-1.1.7
Merge into: lp:ubuntu/natty/ubuntu-sso-client
Diff against target: 360 lines (+236/-17)
8 files modified
PKG-INFO (+1/-1)
README (+213/-1)
debian/changelog (+11/-0)
setup.py (+1/-1)
ubuntu_sso/account.py (+4/-6)
ubuntu_sso/main.py (+1/-3)
ubuntu_sso/tests/test_account.py (+3/-3)
ubuntu_sso/tests/test_main.py (+2/-2)
To merge this branch: bzr merge lp:~nataliabidart/ubuntu/natty/ubuntu-sso-client/ubuntu-sso-client-1.1.7
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+43939@code.launchpad.net

Description of the change

  * New upstream release.
    [ Natalia B. Bidart <email address hidden> ]
       * Avoid generating an extra token when attempting to validate a user
         account (LP: #687523).
       * Documented CredentialsManagement interface (LP: #673054).

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'PKG-INFO'
2--- PKG-INFO 2010-11-30 13:21:17 +0000
3+++ PKG-INFO 2010-12-16 17:45:45 +0000
4@@ -1,6 +1,6 @@
5 Metadata-Version: 1.1
6 Name: ubuntu-sso-client
7-Version: 1.1.5
8+Version: 1.1.7
9 Summary: Ubuntu Single Sign-On client
10 Home-page: https://launchpad.net/ubuntu-sso-client
11 Author: Natalia Bidart
12
13=== modified file 'README'
14--- README 2010-06-16 15:11:04 +0000
15+++ README 2010-12-16 17:45:45 +0000
16@@ -1,1 +1,213 @@
17-This is the Ubuntu Single Sign-On client.
18+= Ubuntu Single Sign-On Client =
19+
20+ubuntu-sso-client is a desktop application that provides a D-Bus interface to
21+let other applications store and manage credentials in the local keyring.
22+
23+When requesting a set of credentials for a given application, if those
24+credentials are not yet present on the user's keyring, the user is presented
25+with a GUI to either register a new account, or log in using an existing
26+account by means of the Ubuntu SSO web service.
27+
28+Since version 1.1.5, this service does not depend on the gnome-keyring
29+service, but on any keyring service that implements the freedesktop secrets
30+specification (see
31+http://freedesktop.org/wiki/Specifications/secret-storage-spec for reference).
32+
33+== ubuntu-sso-client D-Bus API ==
34+
35+This section details the API that ubuntu-sso-client exposes through D-Bus. It
36+is available under the:
37+
38+ * {{{com.ubuntu.sso}}} bus name, on the
39+ * {{{/com/ubuntu/sso/credentials}}} object path.
40+
41+That object implements the {{{com.ubuntu.sso.CredentialsManagement}}}
42+interface, that has the methods and signals listed below. All of these methods
43+are asynchronous, and return immediately with no value. Signal handlers are
44+required to handle results specially, where necessary.
45+
46+They all return information to the caller through signals, since all the
47+operations (either against the keyring, or against the SSO web service) are
48+blocking, and so the Ubuntu SSO API is entirely asynchronous.
49+
50+NOTE: formerly, the {{{ApplicationCredentials}}} interface was implemented
51+under the {{{/credentials}}} object path. That interface is deprecated and
52+should not be used. However, current applications using this interface will be
53+able to do so until the Ubuntu 11.04 release inclusive, since it won't be
54+removed it until 11.10.
55+
56+=== com.ubuntu.sso.CredentialsManagement Methods ===
57+
58+Any of these methods may emit the {{{CredentialsError}}} signal, with the
59+caller's "app_name" as the first parameter, and a dictionary with key and value
60+both as strings describing the error. See below for details about this signal.
61+
62+==== find_credentials(String app_name, Dict of {String, String} extra_params) ====
63+
64+Look for credentials on the user's keyring for "app_name". Currently, the
65+parameter "extra_params" is not used and an empty dict must be passed.
66+
67+If credentials were found for "app_name", the signal {{{CredentialsFound}}} is
68+emitted with "app_name" and the corresponding credentials dict as the result.
69+
70+If credentials were not found, the signal {{{CredentialsNotFound}}} is emitted
71+with "app_name" as the only parameter.
72+
73+==== clear_credentials(String app_name, Dict of {String, String} extra_params) ====
74+
75+Clear the credentials on the user's keyring for "app_name". Currently, the
76+parameter "extra_params" is not used and an empty dict should be passed.
77+
78+This method always emits the signal {{{CredentialsCleared}}} with "app_name" as
79+only parameter (except on error when {{{CredentialsError}}} is emitted).
80+
81+==== store_credentials(String app_name, Dict of {String, String} credentials) ====
82+
83+Store the given set of 'credentials' on the user's keyring, for "app_name".
84+Second parameter 'credentials' must provide at least these 4 keys with valid
85+values:
86+
87+ * 'token'
88+ * 'token_secret'
89+ * 'consumer_key'
90+ * 'consumer_secret'
91+
92+If the credentials were successfully set for "app_name", the signal
93+{{{CredentialsStored}}} is emitted with "app_name" as the only parameter.
94+
95+==== register(String app_name, Dict of {String, String} ui_settings) ====
96+
97+This method will try to fetch the credentials from the user's keyring for
98+"app_name", and will emit the {{{CredentialsFound}}} signal if they are found.
99+
100+If existing credentials are not found, it will open a graphical dialog to let
101+the user create a new account for "app_name", or login to an existing SSO
102+account. Once the user is successfully registered or logged in, the newly
103+acquired credentials for "app_name" will be stored in the keyring and will be
104+returned to the caller through the {{{CredentialsFound}}} signal.
105+
106+ * 'app_name': will be displayed in the GUI header (so it should be human
107+ readable), plus it will be used to find/build/clear tokens. Special attention
108+ must be paid to this value since if it collides with some other app name,
109+ return signals may be misleading because the identifier is the application
110+ name.
111+
112+The second parameter 'ui_settings' can contain any of the following (none is
113+required):
114+
115+ * 'help_text': an explanatory text for the end-users, will be shown below the
116+ header in most of the registration process.
117+
118+ * 'ping_url': an url to open after successful token retrieval. If defined, the
119+ email will be attached to the url and will be pinged with a OAuth-signed
120+ request (this is usually useful for server application to keep track of new
121+ tokens).
122+
123+ * 'tc_url': the link to a Terms and Conditions web page. If defined, a
124+ checkbox to agree to the terms will be presented to the user, and will be
125+ required to be checked to continue the registration. Also, a link to the terms
126+ will be offered for browsing. If not defined, nothing will be shown.
127+
128+ * 'window_id': an X11 window identifier to be used for
129+ gtk.gdk.set_transient_for, so the dialog is always shown above the specified
130+ parent window. Usually it is str(!GtkWidget.window.xid) for GTK callers. If
131+ not defined, no parent will be set.
132+
133+Additionally, this 'ui_settings' can provide 2 extra keys to define which UI
134+module and UI class should be used in case the service needs to open a
135+graphical interface to the end user. These keys are:
136+
137+ * 'ui_class': the name of a class that lives within 'ui_module' and that
138+ accepts proper parameters (TODO: document parameters). An example of this
139+ class can be seen at ubuntu_sso.gtk.gui.UbuntuSSOClientGUI.
140+
141+ * 'ui_module': a string pointing to a python module that holds 'ui_class' in
142+ it, and is importable from the system PYTHONPATH.
143+
144+==== login(String app_name, Dict of {String, String} ui_settings) ====
145+
146+This method behaves like 'register' except that the graphical interface, if
147+shown to the user, will offer login only functionality.
148+
149+So, it will try to fetch the credentials from the user's keyring for
150+"app_name", and will emit the {{{CredentialsFound}}} signal if found. If
151+existing credentials are not found, it will open a graphical dialog to let the
152+user log in into an existing SSO account. Once the user is successfully logged
153+in, the newly acquired credentials for "app_name" will be stored in the keyring
154+and will be returned to the caller through the {{{CredentialsFound}}} signal.
155+
156+Options for parameters on 'ui_settings' match the one listed above for
157+'register', except that the 'tc_url' will not be used even if defined.
158+
159+=== com.ubuntu.sso.CredentialsManagement Signals ===
160+
161+The applications listening for this signals should make sure the app_name sent
162+as parameter for each signal matches the one they used for calling the methods
163+defined in the previous section. If the app_name does not match, then the
164+calling applications can safely assume those credentials or error messages are
165+meant for another application and just discard them.
166+
167+==== CredentialsFound(String app_name, Dict of {String, String} credentials) ====
168+
169+The credentials are returned when this signal is emitted. It means that the
170+credentials were either on the keyring, or that the login and/or register
171+process was successful and a set of credentials has been stored on the keyring.
172+
173+ * "app_name" is the application name as passed to the called method.
174+
175+ * "credentials" is a dictionary that contains at least four keys with the
176+ token and consumer keys and secrets. The dictionary keys are named:
177+
178+ * 'token'
179+ * 'token_secret'
180+ * 'consumer_key'
181+ * 'consumer_secret'
182+
183+==== CredentialsNotFound(String app_name) ====
184+
185+Emitted after 'find_credentials' was called and the credentials for "app_name"
186+were not found in the user's keyring.
187+
188+ * "app_name" is the application name as passed to the called method.
189+
190+==== AuthorizationDenied(String app_name) ====
191+
192+Emitted when the user was presented with a graphical interface and s/he
193+canceled the request for login and/or register by clicking on a 'Cancel'
194+button before the process was completed.
195+
196+ * "app_name" is the application name as passed to the called method.
197+
198+==== CredentialsError(String app_name, Dict of {String, String} error_dict) ====
199+
200+This signal is raised when there is any problem getting, setting or clearing
201+the credentials.
202+
203+ * "app_name" is the application name as passed to the called method.
204+
205+ * "error_dict" is a dictionary containing at least 2 fields:
206+
207+ * "error_message" a simple message that can be shown to the user explaining
208+ the error (is not translated to any language).
209+
210+ * "detailed_error" is a string containing a Python stacktrace or something
211+ similar to help the developers debug the problem. The application calling
212+ ubuntu-sso-client may choose to show it to the user using a !GtkExpander, or
213+ write it to a log file, etc.
214+
215+==== CredentialsCleared(String app_name) ====
216+
217+Emitted when the credentials for "app_name" were successfully removed from the
218+user's keyring. Note that if an application requested the removal of
219+non-existent credentials, this signals will be emitted if no error occurred.
220+
221+ * "app_name" is the application name as passed to the called method.
222+
223+==== CredentialsStored(String app_name) ====
224+
225+Emitted when the credentials passed as the parameter to 'store_credentials'
226+were successfully stored.
227+
228+ * "app_name" is the application name as passed to the called method.
229+
230+== To be done: add API docs for accounts service ==
231
232=== modified file 'debian/changelog'
233--- debian/changelog 2010-12-09 11:53:18 +0000
234+++ debian/changelog 2010-12-16 17:45:45 +0000
235@@ -1,3 +1,14 @@
236+ubuntu-sso-client (1.1.7-0ubuntu1) UNRELEASED; urgency=low
237+
238+ * New upstream release.
239+
240+ [ Natalia B. Bidart <natalia.bidart@canonical.com> ]
241+ * Avoid generating an extra token when attempting to validate a user
242+ account (LP: #687523).
243+ * Documented CredentialsManagement interface (LP: #673054).
244+
245+ -- Natalia Bidart (nessita) <nataliabidart@gmail.com> Thu, 16 Dec 2010 13:32:36 -0300
246+
247 ubuntu-sso-client (1.1.5-0ubuntu2) natty; urgency=low
248
249 * No change rebuild with the new python
250
251=== modified file 'setup.py'
252--- setup.py 2010-11-30 13:21:17 +0000
253+++ setup.py 2010-12-16 17:45:45 +0000
254@@ -87,7 +87,7 @@
255
256 DistUtilsExtra.auto.setup(
257 name='ubuntu-sso-client',
258- version='1.1.5',
259+ version='1.1.7',
260 license='GPL v3',
261 author='Natalia Bidart',
262 author_email='natalia.bidart@canonical.com',
263
264=== modified file 'ubuntu_sso/account.py'
265--- ubuntu_sso/account.py 2010-11-30 13:21:17 +0000
266+++ ubuntu_sso/account.py 2010-12-16 17:45:45 +0000
267@@ -172,12 +172,10 @@
268 'token_name: %r', credentials['consumer_key'], token_name)
269 return credentials
270
271- def is_validated(self, email, password, token_name, sso_service=None):
272+ def is_validated(self, token, sso_service=None):
273 """Return if user with 'email' and 'password' is validated."""
274+ logger.debug('is_validated: requesting accounts.me() info.')
275 if sso_service is None:
276- token = self.login(email=email, password=password,
277- token_name=token_name)
278-
279 oauth_token = oauth.OAuthToken(token['token'],
280 token['token_secret'])
281 authorizer = OAuthAuthorizer(token['consumer_key'],
282@@ -189,8 +187,8 @@
283 key = 'preferred_email'
284 result = key in me_info and me_info[key] != None
285
286- logger.debug('is_validated: email: %r token_name: %r, result: %r.',
287- email, token_name, result)
288+ logger.info('is_validated: consumer_key: %r, result: %r.',
289+ token['consumer_key'], result)
290 return result
291
292 def validate_email(self, email, password, email_token, token_name):
293
294=== modified file 'ubuntu_sso/main.py'
295--- ubuntu_sso/main.py 2010-11-30 13:21:17 +0000
296+++ ubuntu_sso/main.py 2010-12-16 17:45:45 +0000
297@@ -192,9 +192,7 @@
298
299 def success_cb(app_name, credentials):
300 """Login finished successfull."""
301- token_name = get_token_name(app_name)
302- is_validated = self.processor.is_validated(email, password,
303- token_name)
304+ is_validated = self.processor.is_validated(credentials)
305 logger.debug('user is validated? %r.', is_validated)
306 if is_validated:
307 # pylint: disable=E1101
308
309=== modified file 'ubuntu_sso/tests/test_account.py'
310--- ubuntu_sso/tests/test_account.py 2010-11-30 13:21:17 +0000
311+++ ubuntu_sso/tests/test_account.py 2010-12-16 17:45:45 +0000
312@@ -249,7 +249,7 @@
313
314 def test_is_validated(self):
315 """If preferred email is not None, user is validated."""
316- result = self.processor.is_validated(**self.login_kwargs)
317+ result = self.processor.is_validated(token=TOKEN)
318 self.assertTrue(result, 'user must be validated.')
319
320 def test_is_not_validated(self):
321@@ -257,7 +257,7 @@
322 service = FakedSSOServer(None, None)
323 service.accounts.preferred_email = None
324 result = self.processor.is_validated(sso_service=service,
325- **self.login_kwargs)
326+ token=TOKEN)
327 self.assertFalse(result, 'user must not be validated.')
328
329 def test_is_not_validated_empty_result(self):
330@@ -265,7 +265,7 @@
331 service = FakedSSOServer(None, None)
332 service.accounts.me = lambda: {}
333 result = self.processor.is_validated(sso_service=service,
334- **self.login_kwargs)
335+ token=TOKEN)
336 self.assertFalse(result, 'user must not be validated.')
337
338 # validate_email
339
340=== modified file 'ubuntu_sso/tests/test_main.py'
341--- ubuntu_sso/tests/test_main.py 2010-11-30 13:21:17 +0000
342+++ ubuntu_sso/tests/test_main.py 2010-12-16 17:45:45 +0000
343@@ -210,7 +210,7 @@
344 processor = self.create_mock_processor()
345 processor.login(EMAIL, PASSWORD, TOKEN_NAME)
346 self.mocker.result(TOKEN)
347- processor.is_validated(EMAIL, PASSWORD, TOKEN_NAME)
348+ processor.is_validated(TOKEN)
349 self.mocker.result(True)
350 self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
351 self.mocker.replay()
352@@ -236,7 +236,7 @@
353 processor = self.create_mock_processor()
354 processor.login(EMAIL, PASSWORD, TOKEN_NAME)
355 self.mocker.result(TOKEN)
356- processor.is_validated(EMAIL, PASSWORD, TOKEN_NAME)
357+ processor.is_validated(TOKEN)
358 self.mocker.result(False)
359 self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
360 self.mocker.replay()

Subscribers

People subscribed via source and target branches