Merge lp:~mandel/ubuntuone-client/provide_credentials_management into lp:ubuntuone-client

Proposed by Manuel de la Peña
Status: Merged
Approved by: dobey
Approved revision: 1004
Merged at revision: 998
Proposed branch: lp:~mandel/ubuntuone-client/provide_credentials_management
Merge into: lp:ubuntuone-client
Diff against target: 944 lines (+586/-259)
8 files modified
po/POTFILES.in (+1/-1)
tests/platform/linux/test_credentials.py (+17/-5)
tests/test_credentials.py (+98/-0)
ubuntuone/credentials.py (+264/-0)
ubuntuone/platform/linux/__init__.py (+1/-1)
ubuntuone/platform/linux/credentials.py (+78/-251)
ubuntuone/platform/windows/__init__.py (+1/-1)
ubuntuone/platform/windows/credentials.py (+126/-0)
To merge this branch: bzr merge lp:~mandel/ubuntuone-client/provide_credentials_management
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+62627@code.launchpad.net

Commit message

Rearranged the code so that the API is kept as it was before the port to Windows.

Description of the change

Rearranged the code so that the API is kept as it was before the port to Windows.

To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Imports should be sorted alphabetically, for example:

http://pastebin.ubuntu.com/613765/

For the particular case of tests/platform/linux/test_credentials.py, I think there is no need for adding diff lines since the imports itself are not changing (as far as I can see).

If you're changing import from this style:

from ubuntu_sso.credentials import HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY

to:

from ubuntu_sso.credentials import (
    HELP_TEXT_KEY,
    PING_URL_KEY,
    TC_URL_KEY)

please make the last import to have a comma and the closing parenthesis on a single line. That is:

from ubuntu_sso.credentials import (
    HELP_TEXT_KEY,
    PING_URL_KEY,
    TC_URL_KEY,
)

Can you please move the line:

CredentialsError = CredentialsErrorRoot

so when looking at the diff it replaces the definition of the old CredentialsError exception? (this way we make the diff clearer).

Can you please move the definition of the NO_OP and logging setup to ubuntuone/credentials.py? that way you can import those from linux/windows without duplicating the code.

Please remove all your #!/usr/bin/env python from the python modules. The shebang is only needed on executable code (so, pretty much never when we develop libraries :-)).

Every occurrence of "ubuntu one" should be capitalized ("Ubuntu One").

review: Needs Fixing
Revision history for this message
Roberto Alsina (ralsina) wrote :

Looks good to me.

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

./ubuntuone/platform/linux/credentials.py:
    20: 'os' imported but unused
    25: 'basic_formatter' imported but unused
    25: 'LOGFOLDER' imported but unused
    25: 'CustomRotatingFileHandler' imported but unused
    25: 'logging' imported but unused

./ubuntuone/platform/windows/credentials.py:
    20: 'os' imported but unused
    25: 'basic_formatter' imported but unused
    25: 'LOGFOLDER' imported but unused
    25: 'CustomRotatingFileHandler' imported but unused
    25: 'logging' imported but unused
    32: 'logger' imported but unused

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

Approving so mandel can land this once the lint issues are solved.

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (603.6 KiB)

The attempt to merge lp:~mandel/ubuntuone-client/provide_credentials_management into lp:ubuntuone-client failed. Below is the output from the failed tests.

/usr/bin/gnome-autogen.sh
checking for autoconf >= 2.53...
  testing autoconf2.50... not found.
  testing autoconf... found 2.67
checking for automake >= 1.10...
  testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
  testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
  testing intltoolize... found 0.41.1
checking for pkg-config >= 0.14.0...
  testing pkg-config... found 0.25
checking for gtk-doc >= 1.0...
  testing gtkdocize... found 1.17
Checking for required M4 macros...
Checking for forbidden M4 macros...
Processing ./configure.ac
Running libtoolize...
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
Running gtkdocize...
Running aclocal-1.11...
Running autoconf...
Running autoheader...
Running automake-1.11...
Running ./configure --enable-gtk-doc --enable-debug ...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize ...

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (219.6 KiB)

The attempt to merge lp:~mandel/ubuntuone-client/provide_credentials_management into lp:ubuntuone-client failed. Below is the output from the failed tests.

/usr/bin/gnome-autogen.sh
checking for autoconf >= 2.53...
  testing autoconf2.50... not found.
  testing autoconf... found 2.67
checking for automake >= 1.10...
  testing automake-1.11... found 1.11.1
checking for libtool >= 1.5...
  testing libtoolize... found 2.2.6b
checking for intltool >= 0.30...
  testing intltoolize... found 0.41.1
checking for pkg-config >= 0.14.0...
  testing pkg-config... found 0.25
checking for gtk-doc >= 1.0...
  testing gtkdocize... found 1.17
Checking for required M4 macros...
Checking for forbidden M4 macros...
Processing ./configure.ac
Running libtoolize...
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
Running intltoolize...
Running gtkdocize...
Running aclocal-1.11...
Running autoconf...
Running autoheader...
Running automake-1.11...
Running ./configure --enable-gtk-doc --enable-debug ...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... gcc3
checking for library containing strerror... none required
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking dependency style of gcc... (cached) gcc3
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by gcc... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B
checking the name lister (/usr/bin/nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking for /usr/bin/ld option to reload object files... -r
checking for objdump... objdump
checking how to recognize ...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/test-send-signal.py' (properties changed: +x to -x)
2=== modified file 'po/POTFILES.in'
3--- po/POTFILES.in 2011-05-24 18:19:52 +0000
4+++ po/POTFILES.in 2011-06-02 10:17:29 +0000
5@@ -1,6 +1,6 @@
6 ubuntuone/clientdefs.py.in
7 ubuntuone/status/aggregator.py
8-ubuntuone/platform/linux/credentials.py
9+ubuntuone/credentials.py
10 data/emblem-ubuntuone-downloading.icon.in
11 data/emblem-ubuntuone-unsynchronized.icon.in
12 data/emblem-ubuntuone-uploading.icon.in
13
14=== modified file 'tests/platform/linux/test_credentials.py'
15--- tests/platform/linux/test_credentials.py 2011-05-24 18:19:52 +0000
16+++ tests/platform/linux/test_credentials.py 2011-06-02 10:17:29 +0000
17@@ -24,12 +24,24 @@
18 from ubuntuone.devtools.testcase import DBusTestCase as TestCase
19 from ubuntuone.devtools.handlers import MementoHandler
20
21-from ubuntuone.platform.linux.credentials import (dbus, logger, logging,
22- CredentialsManagement, CredentialsManagementTool, CredentialsError,
23+from ubuntuone.credentials import logging, logger
24+from ubuntuone.platform.linux.credentials import (
25+ APP_NAME,
26+ CredentialsError,
27+ CredentialsManagement,
28+ CredentialsManagementTool,
29+ dbus,
30+ DBUS_BUS_NAME,
31+ DBUS_CREDENTIALS_IFACE,
32+ DBUS_CREDENTIALS_PATH,
33+ DESCRIPTION,
34+ HELP_TEXT_KEY,
35+ PING_URL,
36+ PING_URL_KEY,
37+ TC_URL_KEY,
38+ TC_URL,
39+ TIMEOUT_INTERVAL,
40 ubuntu_sso,
41- DBUS_BUS_NAME, DBUS_CREDENTIALS_PATH, DBUS_CREDENTIALS_IFACE,
42- APP_NAME, HELP_TEXT_KEY, DESCRIPTION, TC_URL_KEY, TC_URL,
43- PING_URL_KEY, PING_URL, TIMEOUT_INTERVAL,
44 )
45
46 FAKED_CREDENTIALS = {
47
48=== added file 'tests/test_credentials.py'
49--- tests/test_credentials.py 1970-01-01 00:00:00 +0000
50+++ tests/test_credentials.py 2011-06-02 10:17:29 +0000
51@@ -0,0 +1,98 @@
52+# -*- coding: utf-8 -*-
53+#
54+# Author: Manuel de la Pena<manuel@canonical.com>
55+#
56+# Copyright 2011 Canonical Ltd.
57+#
58+# This program is free software: you can redistribute it and/or modify it
59+# under the terms of the GNU General Public License version 3, as published
60+# by the Free Software Foundation.
61+#
62+# This program is distributed in the hope that it will be useful, but
63+# WITHOUT ANY WARRANTY; without even the implied warranties of
64+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
65+# PURPOSE. See the GNU General Public License for more details.
66+#
67+# You should have received a copy of the GNU General Public License along
68+# with this program. If not, see <http://www.gnu.org/licenses/>.
69+"""Platform independent tests for the credentials management."""
70+
71+from mocker import MockerTestCase, MATCH
72+
73+from ubuntuone.platform.credentials import CredentialsManagementTool
74+
75+
76+class TestCredentialsManagementTool(MockerTestCase):
77+ """Test the crendentials management tool mocking the proxy."""
78+
79+ def setUp(self):
80+ """Set the diff tests."""
81+ super(TestCredentialsManagementTool, self).setUp()
82+ self.get_cred_proxy = self.mocker.mock()
83+ self.proxy = self.mocker.mock()
84+ self.management_tool = CredentialsManagementTool()
85+ self.management_tool.get_creds_proxy = self.get_cred_proxy
86+
87+ def test_find_credentials(self):
88+ """Test that we do ask for the credentials correctly."""
89+ signals = ['creds_found', 'creds_not_found', 'creds_erro']
90+ self.get_cred_proxy()
91+ self.mocker.result(self.proxy)
92+ self.proxy.register_to_credentials_found(MATCH(callable))
93+ self.mocker.result(signals[0])
94+ self.proxy.register_to_credentials_not_found(MATCH(callable))
95+ self.mocker.result(signals[1])
96+ self.proxy.register_to_credentials_error(MATCH(callable))
97+ self.mocker.result(signals[2])
98+ self.proxy.find_credentials(reply_handler=MATCH(callable),
99+ error_handler=MATCH(callable))
100+ self.mocker.replay()
101+ return self.management_tool.find_credentials()
102+
103+ def test_clear_credentials(self):
104+ """Test that we clear the credentials correctly."""
105+ signals = ['creds_cleared', 'creds_error']
106+ self.get_cred_proxy()
107+ self.mocker.result(self.proxy)
108+ self.proxy.register_to_credentials_cleared(MATCH(callable))
109+ self.mocker.result(signals[0])
110+ self.proxy.register_to_credentials_error(MATCH(callable))
111+ self.mocker.result(signals[1])
112+ self.proxy.clear_credentials(reply_handler=MATCH(callable),
113+ error_handler=MATCH(callable))
114+ self.mocker.replay()
115+ return self.management_tool.clear_credentials()
116+
117+ def test_store_credentials(self):
118+ """Test that we store the credentials correctly."""
119+ token = 'token'
120+ signals = ['creds_stored','creds_error']
121+ self.get_cred_proxy()
122+ self.mocker.result(self.proxy)
123+ self.proxy.register_to_credentials_stored(MATCH(callable))
124+ self.mocker.result(signals[0])
125+ self.proxy.register_to_credentials_error(MATCH(callable))
126+ self.mocker.result(signals[1])
127+ self.proxy.store_credentials(token, reply_handler=MATCH(callable),
128+ error_handler=MATCH(callable))
129+ self.mocker.replay()
130+ return self.management_tool.store_credentials(token)
131+
132+ def test_register(self):
133+ """Test that we correctly register."""
134+ window_id = 10
135+ window_id_dict = dict(window_id=str(window_id))
136+ signals = ['creds_found', 'creds_denied', 'creds_error']
137+ self.get_cred_proxy()
138+ self.mocker.result(self.proxy)
139+ self.proxy.register_to_credentials_found(MATCH(callable))
140+ self.mocker.result(signals[0])
141+ self.proxy.register_to_authorization_denied(MATCH(callable))
142+ self.mocker.result(signals[1])
143+ self.proxy.register_to_credentials_error(MATCH(callable))
144+ self.mocker.result(signals[2])
145+ self.proxy.register(window_id_dict, reply_handler=MATCH(callable),
146+ error_handler=MATCH(callable))
147+ self.mocker.replay()
148+ return self.management_tool.register(window_id=window_id)
149+
150
151=== added file 'ubuntuone/credentials.py'
152--- ubuntuone/credentials.py 1970-01-01 00:00:00 +0000
153+++ ubuntuone/credentials.py 2011-06-02 10:17:29 +0000
154@@ -0,0 +1,264 @@
155+# -*- coding: utf-8 -*-
156+#
157+# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
158+# Author: Manuel de la Pena<manuel@canonical.com>
159+#
160+# Copyright 2011 Canonical Ltd.
161+#
162+# This program is free software: you can redistribute it and/or modify it
163+# under the terms of the GNU General Public License version 3, as published
164+# by the Free Software Foundation.
165+#
166+# This program is distributed in the hope that it will be useful, but
167+# WITHOUT ANY WARRANTY; without even the implied warranties of
168+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
169+# PURPOSE. See the GNU General Public License for more details.
170+#
171+# You should have received a copy of the GNU General Public License along
172+# with this program. If not, see <http://www.gnu.org/licenses/>.
173+"""Common code for the credentials management."""
174+
175+import os
176+import gettext
177+
178+from twisted.internet import defer
179+
180+from ubuntuone.logger import (basic_formatter, logging,
181+ CustomRotatingFileHandler, LOGFOLDER)
182+from ubuntuone.clientdefs import GETTEXT_PACKAGE
183+
184+LOG_LEVEL = logging.DEBUG
185+path = os.path.join(LOGFOLDER, 'credentials.log')
186+MAIN_HANDLER = CustomRotatingFileHandler(path)
187+MAIN_HANDLER.setFormatter(basic_formatter)
188+MAIN_HANDLER.setLevel(LOG_LEVEL)
189+
190+logger = logging.getLogger("ubuntuone.credentials")
191+logger.setLevel(LOG_LEVEL)
192+logger.addHandler(MAIN_HANDLER)
193+
194+NO_OP = lambda *args, **kwargs: None
195+Q_ = lambda string: gettext.dgettext(GETTEXT_PACKAGE, string)
196+APP_NAME = "Ubuntu One"
197+TC_URL = "https://one.ubuntu.com/terms/"
198+PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/"
199+DESCRIPTION = Q_('Ubuntu One requires an Ubuntu Single Sign On (SSO) account. '
200+ 'This process will allow you to create a new account, '
201+ 'if you do not yet have one.')
202+
203+class CredentialsError(Exception):
204+ """A general exception when hadling credentilas."""
205+
206+
207+class CredentialsManagementToolRoot(object):
208+ """Wrapper to CredentialsManagement.
209+
210+ The goal of this class is to abstract the caller from calling the DBus
211+ service implemented in the class CredentialsManagement.
212+
213+ """
214+
215+ def __init__(self, get_proxy_fn):
216+ self._cleanup_signals = []
217+ self.get_creds_proxy = get_proxy_fn
218+
219+ def cleanup(self, _):
220+ """Disconnect all the DBus signals."""
221+ for sig in self._cleanup_signals:
222+ logger.debug('cleanup: removing signal match %r', sig)
223+ sig.remove()
224+
225+ return _
226+
227+ @defer.inlineCallbacks
228+ def find_credentials(self):
229+ """Find credentials for Ubuntu One.
230+
231+ Return a deferred that, when fired, will return the credentials for
232+ Ubuntu One for the current logged in user.
233+
234+ The credentials is a dictionary with both string keys and values. The
235+ dictionary may be either empty if there are no credentials for the
236+ user, or will hold five items as follow:
237+
238+ - "name"
239+ - "token"
240+ - "token_secret"
241+ - "consumer_key"
242+ - "consumer_secret"
243+
244+ """
245+ d = defer.Deferred()
246+ d.addBoth(self.cleanup)
247+
248+ proxy = self.get_creds_proxy()
249+
250+ sig = proxy.register_to_credentials_found(d.callback)
251+ self._cleanup_signals.append(sig)
252+
253+ sig = proxy.register_to_credentials_not_found(lambda: d.callback({}))
254+ self._cleanup_signals.append(sig)
255+
256+ sig = proxy.register_to_credentials_error(
257+ lambda error_dict: d.errback(CredentialsError(error_dict)))
258+ self._cleanup_signals.append(sig)
259+
260+ done = defer.Deferred()
261+ proxy.find_credentials(reply_handler=lambda: done.callback(None),
262+ error_handler=lambda *a: done.errback(a))
263+
264+ yield done
265+
266+ result = yield d
267+ defer.returnValue(result)
268+
269+ @defer.inlineCallbacks
270+ def clear_credentials(self):
271+ """Clear credentials for Ubuntu One.
272+
273+ Return a deferred that, when fired, will return no result but will
274+ indicate that the Ubuntu One credentials for the current user were
275+ removed from the local keyring.
276+
277+ """
278+ d = defer.Deferred()
279+ d.addBoth(self.cleanup)
280+
281+ proxy = self.get_creds_proxy()
282+ sig = proxy.register_to_credentials_cleared(lambda: d.callback(None))
283+ self._cleanup_signals.append(sig)
284+
285+ sig = proxy.register_to_credentials_error(
286+ lambda error_dict: d.errback(CredentialsError(error_dict)))
287+ self._cleanup_signals.append(sig)
288+
289+ done = defer.Deferred()
290+ proxy.clear_credentials(reply_handler=lambda: done.callback(None),
291+ error_handler=lambda *a: done.errback(a))
292+
293+ yield done
294+
295+ yield d
296+
297+ @defer.inlineCallbacks
298+ def store_credentials(self, token):
299+ """Store credentials for Ubuntu One.
300+
301+ The parameter 'token' should be a dictionary that matches the
302+ description of the result of 'find_credentials'.
303+
304+ Return a deferred that, when fired, will return no result but will
305+ indicate that 'token' was stored in the local keyring as the new Ubuntu
306+ One credentials for the current user.
307+
308+ """
309+ d = defer.Deferred()
310+ d.addBoth(self.cleanup)
311+
312+ proxy = self.get_creds_proxy()
313+ sig = proxy.register_to_credentials_stored(lambda: d.callback(None))
314+ self._cleanup_signals.append(sig)
315+
316+ sig = proxy.register_to_credentials_error(
317+ lambda error_dict: d.errback(CredentialsError(error_dict)))
318+ self._cleanup_signals.append(sig)
319+
320+ done = defer.Deferred()
321+ proxy.store_credentials(token,
322+ reply_handler=lambda: done.callback(None),
323+ error_handler=lambda *a: done.errback(a))
324+
325+ yield done
326+
327+ yield d
328+
329+ @defer.inlineCallbacks
330+ def register(self, window_id=0):
331+ """Register to Ubuntu One.
332+
333+ Return a deferred that, when fired, will return the credentials for
334+ Ubuntu One for the current logged in user.
335+
336+ If there are no credentials for the current user, a GTK UI will be
337+ opened to invite the user to register to Ubuntu One. This UI provides
338+ options to either register (main screen) or login (secondary screen).
339+
340+ You can pass an optional 'window_id' parameter that will be used by the
341+ GTK UI to be set transient for it.
342+
343+ The returned credentials will be either a non-empty dictionary like the
344+ one described in 'find_credentials', or None. The latter indicates that
345+ there were no credentials for the user in the local keyring and that
346+ the user refused to register to Ubuntu One.
347+
348+ """
349+ d = defer.Deferred()
350+ d.addBoth(self.cleanup)
351+
352+ proxy = self.get_creds_proxy()
353+
354+ sig = proxy.register_to_credentials_found(d.callback)
355+ self._cleanup_signals.append(sig)
356+
357+ sig = proxy.register_to_authorization_denied(lambda: d.callback(None))
358+ self._cleanup_signals.append(sig)
359+
360+ sig = proxy.register_to_credentials_error(
361+ lambda error_dict: d.errback(CredentialsError(error_dict)))
362+ self._cleanup_signals.append(sig)
363+
364+ done = defer.Deferred()
365+ proxy.register({'window_id': str(window_id)},
366+ reply_handler=lambda: done.callback(None),
367+ error_handler=lambda *a: done.errback(a))
368+
369+ yield done
370+
371+ result = yield d
372+ defer.returnValue(result)
373+
374+ @defer.inlineCallbacks
375+ def login(self, window_id=0):
376+ """Login to Ubuntu One.
377+
378+ Return a deferred that, when fired, will return the credentials for
379+ Ubuntu One for the current logged in user.
380+
381+ If there are no credentials for the current user, a GTK UI will be
382+ opened to invite the user to login to Ubuntu One. This UI provides
383+ options to either login (main screen) or retrieve password (secondary
384+ screen).
385+
386+ You can pass an optional 'window_id' parameter that will be used by the
387+ GTK UI to be set transient for it.
388+
389+ The returned credentials will be either a non-empty dictionary like the
390+ one described in 'find_credentials', or None. The latter indicates that
391+ there were no credentials for the user in the local keyring and that
392+ the user refused to login to Ubuntu One.
393+
394+ """
395+ d = defer.Deferred()
396+ d.addBoth(self.cleanup)
397+
398+ proxy = self.get_creds_proxy()
399+
400+ sig = proxy.register_to_credentials_found(d.callback)
401+ self._cleanup_signals.append(sig)
402+
403+ sig = proxy.register_to_authorization_denied(lambda: d.callback(None))
404+ self._cleanup_signals.append(sig)
405+
406+ sig = proxy.register_to_credentials_error(
407+ lambda error_dict: d.errback(CredentialsError(error_dict)))
408+ self._cleanup_signals.append(sig)
409+
410+ done = defer.Deferred()
411+ proxy.login({'window_id': str(window_id)},
412+ reply_handler=lambda: done.callback(None),
413+ error_handler=lambda *a: done.errback(a))
414+
415+ yield done
416+
417+ result = yield d
418+ defer.returnValue(result)
419
420=== modified file 'ubuntuone/platform/linux/__init__.py'
421--- ubuntuone/platform/linux/__init__.py 2011-05-24 18:19:52 +0000
422+++ ubuntuone/platform/linux/__init__.py 2011-06-02 10:17:29 +0000
423@@ -55,7 +55,7 @@
424 get_udf_path,
425 VMMetadataUpgraderMixIn
426 )
427-from ubuntuone.platform.linux.credentials import CredentialsManagement
428+from ubuntuone.platform.linux.credentials import CredentialsManagementTool
429 from ubuntuone.platform.linux.logger import setup_filesystem_logging, get_filesystem_logger
430 from ubuntuone.platform.linux.filesystem_notifications import FilesystemMonitor
431 from ubuntuone.platform.linux.notification import Notification
432
433=== modified file 'ubuntuone/platform/linux/credentials.py'
434--- ubuntuone/platform/linux/credentials.py 2011-05-24 18:19:52 +0000
435+++ ubuntuone/platform/linux/credentials.py 2011-06-02 10:17:29 +0000
436@@ -15,48 +15,37 @@
437 #
438 # You should have received a copy of the GNU General Public License along
439 # with this program. If not, see <http://www.gnu.org/licenses/>.
440-
441 """Ubuntu One credentials management dbus service."""
442
443-import os
444
445 import dbus.service
446-import gettext
447 import ubuntu_sso
448
449-from twisted.internet import defer
450-from ubuntu_sso.credentials import HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY
451-
452-from ubuntuone.logger import (basic_formatter, logging,
453- CustomRotatingFileHandler, LOGFOLDER)
454-from ubuntuone.clientdefs import GETTEXT_PACKAGE
455-
456-
457-Q_ = lambda string: gettext.dgettext(GETTEXT_PACKAGE, string)
458-NO_OP = lambda *args, **kwargs: None
459+from ubuntu_sso.credentials import (
460+ HELP_TEXT_KEY,
461+ PING_URL_KEY,
462+ TC_URL_KEY,
463+)
464+from ubuntuone.credentials import (
465+ CredentialsManagementToolRoot,
466+ logger,
467+ APP_NAME,
468+ DESCRIPTION,
469+ NO_OP,
470+ PING_URL,
471+ TC_URL,
472+)
473+from ubuntuone.credentials import CredentialsError as CredentialsErrorRoot
474+
475+
476 TIMEOUT_INTERVAL = 10000 # 10 seconds
477
478-LOG_LEVEL = logging.DEBUG
479-path = os.path.join(LOGFOLDER, 'credentials.log')
480-MAIN_HANDLER = CustomRotatingFileHandler(path)
481-MAIN_HANDLER.setFormatter(basic_formatter)
482-MAIN_HANDLER.setLevel(LOG_LEVEL)
483-
484-logger = logging.getLogger("ubuntuone.credentials")
485-logger.setLevel(LOG_LEVEL)
486-logger.addHandler(MAIN_HANDLER)
487-
488 # constants
489 DBUS_BUS_NAME = "com.ubuntuone.Credentials"
490 DBUS_CREDENTIALS_PATH = "/credentials"
491 DBUS_CREDENTIALS_IFACE = "com.ubuntuone.CredentialsManagement"
492
493-APP_NAME = "Ubuntu One"
494-TC_URL = "https://one.ubuntu.com/terms/"
495-PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/"
496-DESCRIPTION = Q_('Ubuntu One requires an Ubuntu Single Sign On (SSO) account. '
497- 'This process will allow you to create a new account, '
498- 'if you do not yet have one.')
499+CredentialsError = CredentialsErrorRoot
500
501
502 class CredentialsManagement(dbus.service.Object):
503@@ -238,237 +227,75 @@
504 reply_handler=reply_handler, error_handler=error_handler)
505
506
507-class CredentialsError(Exception):
508- """A general exception when hadling credentilas."""
509-
510-
511-class CredentialsManagementTool(object):
512- """Wrapper to CredentialsManagement.
513-
514- The goal of this class is to abstract the caller from calling the DBus
515- service implemented in the class CredentialsManagement.
516-
517+class CredentialsManagementProxy(object):
518+ """Proxy that allows to work with the dbus api.
519+
520+ This proxy has been added to hide the exact details of
521+ how the signals are connected. This allows the reuse of
522+ the CredentialsManagementTool in diff platforms.
523 """
524
525 def __init__(self):
526- self._cleanup_signals = []
527-
528- def _get_creds_proxy(self):
529- """Get the CredentialsManagement dbus proxy."""
530+ """Create a new instance."""
531 bus = dbus.SessionBus()
532 try:
533 obj = bus.get_object(DBUS_BUS_NAME,
534 DBUS_CREDENTIALS_PATH,
535 follow_name_owner_changes=True)
536- proxy = dbus.Interface(obj, DBUS_CREDENTIALS_IFACE)
537+ self.proxy = dbus.Interface(obj, DBUS_CREDENTIALS_IFACE)
538 except:
539 logger.exception('get_creds_proxy:')
540 raise
541
542- return proxy
543-
544- def cleanup(self, _):
545- """Disconnect all the DBus signals."""
546- for sig in self._cleanup_signals:
547- logger.debug('cleanup: removing signal match %r', sig)
548- sig.remove()
549-
550- return _
551-
552- @defer.inlineCallbacks
553- def find_credentials(self):
554- """Find credentials for Ubuntu One.
555-
556- Return a deferred that, when fired, will return the credentials for
557- Ubuntu One for the current logged in user.
558-
559- The credentials is a dictionary with both string keys and values. The
560- dictionary may be either empty if there are no credentials for the
561- user, or will hold five items as follow:
562-
563- - "name"
564- - "token"
565- - "token_secret"
566- - "consumer_key"
567- - "consumer_secret"
568-
569- """
570- d = defer.Deferred()
571- d.addBoth(self.cleanup)
572-
573- proxy = self._get_creds_proxy()
574-
575- sig = proxy.connect_to_signal('CredentialsFound', d.callback)
576- self._cleanup_signals.append(sig)
577-
578- sig = proxy.connect_to_signal('CredentialsNotFound',
579- lambda: d.callback({}))
580- self._cleanup_signals.append(sig)
581-
582- sig = proxy.connect_to_signal('CredentialsError',
583- lambda error_dict: d.errback(CredentialsError(error_dict)))
584- self._cleanup_signals.append(sig)
585-
586- done = defer.Deferred()
587- proxy.find_credentials(reply_handler=lambda: done.callback(None),
588- error_handler=lambda *a: done.errback(a))
589-
590- yield done
591-
592- result = yield d
593- defer.returnValue(result)
594-
595- @defer.inlineCallbacks
596- def clear_credentials(self):
597- """Clear credentials for Ubuntu One.
598-
599- Return a deferred that, when fired, will return no result but will
600- indicate that the Ubuntu One credentials for the current user were
601- removed from the local keyring.
602-
603- """
604- d = defer.Deferred()
605- d.addBoth(self.cleanup)
606-
607- proxy = self._get_creds_proxy()
608- sig = proxy.connect_to_signal('CredentialsCleared',
609- lambda: d.callback(None))
610- self._cleanup_signals.append(sig)
611-
612- sig = proxy.connect_to_signal('CredentialsError',
613- lambda error_dict: d.errback(CredentialsError(error_dict)))
614- self._cleanup_signals.append(sig)
615-
616- done = defer.Deferred()
617- proxy.clear_credentials(reply_handler=lambda: done.callback(None),
618- error_handler=lambda *a: done.errback(a))
619-
620- yield done
621-
622- yield d
623-
624- @defer.inlineCallbacks
625- def store_credentials(self, token):
626- """Store credentials for Ubuntu One.
627-
628- The parameter 'token' should be a dictionary that matches the
629- description of the result of 'find_credentials'.
630-
631- Return a deferred that, when fired, will return no result but will
632- indicate that 'token' was stored in the local keyring as the new Ubuntu
633- One credentials for the current user.
634-
635- """
636- d = defer.Deferred()
637- d.addBoth(self.cleanup)
638-
639- proxy = self._get_creds_proxy()
640- sig = proxy.connect_to_signal('CredentialsStored',
641- lambda: d.callback(None))
642- self._cleanup_signals.append(sig)
643-
644- sig = proxy.connect_to_signal('CredentialsError',
645- lambda error_dict: d.errback(CredentialsError(error_dict)))
646- self._cleanup_signals.append(sig)
647-
648- done = defer.Deferred()
649- proxy.store_credentials(token,
650- reply_handler=lambda: done.callback(None),
651- error_handler=lambda *a: done.errback(a))
652-
653- yield done
654-
655- yield d
656-
657- @defer.inlineCallbacks
658- def register(self, window_id=0):
659- """Register to Ubuntu One.
660-
661- Return a deferred that, when fired, will return the credentials for
662- Ubuntu One for the current logged in user.
663-
664- If there are no credentials for the current user, a GTK UI will be
665- opened to invite the user to register to Ubuntu One. This UI provides
666- options to either register (main screen) or login (secondary screen).
667-
668- You can pass an optional 'window_id' parameter that will be used by the
669- GTK UI to be set transient for it.
670-
671- The returned credentials will be either a non-empty dictionary like the
672- one described in 'find_credentials', or None. The latter indicates that
673- there were no credentials for the user in the local keyring and that
674- the user refused to register to Ubuntu One.
675-
676- """
677- d = defer.Deferred()
678- d.addBoth(self.cleanup)
679-
680- proxy = self._get_creds_proxy()
681-
682- sig = proxy.connect_to_signal('CredentialsFound', d.callback)
683- self._cleanup_signals.append(sig)
684-
685- sig = proxy.connect_to_signal('AuthorizationDenied',
686- lambda: d.callback(None))
687- self._cleanup_signals.append(sig)
688-
689- sig = proxy.connect_to_signal('CredentialsError',
690- lambda error_dict: d.errback(CredentialsError(error_dict)))
691- self._cleanup_signals.append(sig)
692-
693- done = defer.Deferred()
694- proxy.register({'window_id': str(window_id)},
695- reply_handler=lambda: done.callback(None),
696- error_handler=lambda *a: done.errback(a))
697-
698- yield done
699-
700- result = yield d
701- defer.returnValue(result)
702-
703- @defer.inlineCallbacks
704- def login(self, window_id=0):
705- """Login to Ubuntu One.
706-
707- Return a deferred that, when fired, will return the credentials for
708- Ubuntu One for the current logged in user.
709-
710- If there are no credentials for the current user, a GTK UI will be
711- opened to invite the user to login to Ubuntu One. This UI provides
712- options to either login (main screen) or retrieve password (secondary
713- screen).
714-
715- You can pass an optional 'window_id' parameter that will be used by the
716- GTK UI to be set transient for it.
717-
718- The returned credentials will be either a non-empty dictionary like the
719- one described in 'find_credentials', or None. The latter indicates that
720- there were no credentials for the user in the local keyring and that
721- the user refused to login to Ubuntu One.
722-
723- """
724- d = defer.Deferred()
725- d.addBoth(self.cleanup)
726-
727- proxy = self._get_creds_proxy()
728-
729- sig = proxy.connect_to_signal('CredentialsFound', d.callback)
730- self._cleanup_signals.append(sig)
731-
732- sig = proxy.connect_to_signal('AuthorizationDenied',
733- lambda: d.callback(None))
734- self._cleanup_signals.append(sig)
735-
736- sig = proxy.connect_to_signal('CredentialsError',
737- lambda error_dict: d.errback(CredentialsError(error_dict)))
738- self._cleanup_signals.append(sig)
739-
740- done = defer.Deferred()
741- proxy.login({'window_id': str(window_id)},
742- reply_handler=lambda: done.callback(None),
743- error_handler=lambda *a: done.errback(a))
744-
745- yield done
746-
747- result = yield d
748- defer.returnValue(result)
749+ def find_credentials(self, *args, **kwargs):
750+ """Relay the find_credentials method."""
751+ return self.proxy.find_credentials(*args, **kwargs)
752+
753+ def clear_credentials(self, *args, **kwargs):
754+ """Relay the clear_credentials method."""
755+ return self.proxy.clear_credentials(*args, **kwargs)
756+
757+ def store_credentials(self, *args, **kwargs):
758+ """Relay the store_credentials method."""
759+ return self.proxy.store_credentials(*args, **kwargs)
760+
761+ def register(self, *args, **kwargs):
762+ """Relay the register method."""
763+ return self.proxy.register(*args, **kwargs)
764+
765+ def login(self, *args, **kwargs):
766+ """Relay the login method."""
767+ return self.proxy.login(*args, **kwargs)
768+
769+ def register_to_credentials_stored(self, callback):
770+ """Register to the CredentialsStored dbus signal."""
771+ return self.proxy.connect_to_signal('CredentialsStored', callback)
772+
773+ def register_to_credentials_cleared(self, callback):
774+ """Register to the CredentialsCleared dbus signal."""
775+ return self.proxy.connect_to_signal('CredentialsCleared', callback)
776+
777+ def register_to_credentials_found(self, callback):
778+ """Register to the CredentialsFound dbus signal."""
779+ return self.proxy.connect_to_signal('CredentialsFound', callback)
780+
781+ def register_to_credentials_not_found(self, callback):
782+ """Register to the CredentialsFound dbus signal."""
783+ return self.proxy.connect_to_signal('CredentialsNotFound', callback)
784+
785+ def register_to_authorization_denied(self, callback):
786+ """Register to the AuthorizationDenied dbus signal."""
787+ return self.proxy.connect_to_signal('AuthorizationDenied', callback)
788+
789+ def register_to_credentials_error(self, callback):
790+ """Register to the CredentialsError dbus signal."""
791+ return self.proxy.connect_to_signal('CredentialsError', callback)
792+
793+
794+class CredentialsManagementTool(CredentialsManagementToolRoot):
795+ """Wrapper used to manage the creds of ubuntu one."""
796+
797+ def __init__(self):
798+ """Create a new instance."""
799+ super(CredentialsManagementTool, self).__init__(
800+ CredentialsManagementProxy)
801
802=== modified file 'ubuntuone/platform/windows/__init__.py'
803--- ubuntuone/platform/windows/__init__.py 2011-05-03 15:22:19 +0000
804+++ ubuntuone/platform/windows/__init__.py 2011-06-02 10:17:29 +0000
805@@ -57,7 +57,7 @@
806 validate_path_from_unix
807 )
808
809-from ubuntuone.platform.windows.credentials import get_creds_proxy
810+from ubuntuone.platform.windows.credentials import CredentialsManagementTool
811 from ubuntuone.platform.windows import event_logging
812 from ubuntuone.platform.windows.logger import (
813 setup_filesystem_logging,
814
815=== added file 'ubuntuone/platform/windows/credentials.py'
816--- ubuntuone/platform/windows/credentials.py 1970-01-01 00:00:00 +0000
817+++ ubuntuone/platform/windows/credentials.py 2011-06-02 10:17:29 +0000
818@@ -0,0 +1,126 @@
819+# -*- coding: utf-8 -*-
820+#
821+# Author: Manuel de la Pena<manuel@canonical.com>
822+#
823+# Copyright 2011 Canonical Ltd.
824+#
825+# This program is free software: you can redistribute it and/or modify it
826+# under the terms of the GNU General Public License version 3, as published
827+# by the Free Software Foundation.
828+#
829+# This program is distributed in the hope that it will be useful, but
830+# WITHOUT ANY WARRANTY; without even the implied warranties of
831+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
832+# PURPOSE. See the GNU General Public License for more details.
833+#
834+# You should have received a copy of the GNU General Public License along
835+# with this program. If not, see <http://www.gnu.org/licenses/>.
836+"""Ubuntu One credentials management IPC service."""
837+
838+
839+from ubuntu_sso.main.windows import UbuntuSSOClient
840+from twisted.internet import defer
841+
842+from ubuntu_sso.credentials import (
843+ HELP_TEXT_KEY,
844+ PING_URL_KEY,
845+ TC_URL_KEY,
846+)
847+from ubuntuone.credentials import (
848+ CredentialsManagementToolRoot,
849+ APP_NAME,
850+ DESCRIPTION,
851+ NO_OP,
852+ PING_URL,
853+ TC_URL,
854+)
855+from ubuntuone.credentials import CredentialsError as CredentialsErrorRoot
856+
857+CredentialsError = CredentialsErrorRoot
858+
859+
860+class CredentialsManagement(object):
861+ """Object that manages Ubuntu One credentials."""
862+
863+ def __init__(self, proxy, *args, **kwargs):
864+ super(CredentialsManagement, self).__init__(*args, **kwargs)
865+ self.sso_proxy = proxy
866+
867+ def find_credentials(self, reply_handler=NO_OP, error_handler=NO_OP):
868+ """Ask the Ubuntu One credentials."""
869+ self.sso_proxy.find_credentials(APP_NAME, {},
870+ reply_handler=reply_handler, error_handler=error_handler)
871+
872+
873+ def clear_credentials(self, reply_handler=NO_OP, error_handler=NO_OP):
874+ """Clear the Ubuntu One credentials."""
875+ self.sso_proxy.clear_credentials(APP_NAME, {},
876+ reply_handler=reply_handler, error_handler=error_handler)
877+
878+ def store_credentials(self, credentials,
879+ reply_handler=NO_OP, error_handler=NO_OP):
880+ """Store the token for Ubuntu One application."""
881+ self.sso_proxy.store_credentials(APP_NAME, credentials,
882+ reply_handler=reply_handler, error_handler=error_handler)
883+
884+ def register(self, args, reply_handler=NO_OP, error_handler=NO_OP):
885+ """Get credentials if found else prompt to register to Ubuntu One."""
886+ params = {HELP_TEXT_KEY: DESCRIPTION, TC_URL_KEY: TC_URL,
887+ PING_URL_KEY: PING_URL}
888+ params.update(args)
889+ self.sso_proxy.register(APP_NAME, params,
890+ reply_handler=reply_handler, error_handler=error_handler)
891+
892+ def login(self, args, reply_handler=NO_OP, error_handler=NO_OP):
893+ """Get credentials if found else prompt to login to Ubuntu One."""
894+ params = {HELP_TEXT_KEY: DESCRIPTION, TC_URL_KEY: TC_URL,
895+ PING_URL_KEY: PING_URL}
896+ params.update(args)
897+ self.sso_proxy.login(APP_NAME, params,
898+ reply_handler=reply_handler, error_handler=error_handler)
899+
900+ def register_to_credentials_stored(self, callback):
901+ """Register to the CredentialsStored dbus signal."""
902+ self.sso_proxy.on_credentials_stored_cb = callback
903+ return self.sso_proxy.on_credentials_stored_cb
904+
905+ def register_to_credentials_cleared(self, callback):
906+ """Register to the CredentialsCleared dbus signal."""
907+ self.sso_proxy.on_credentials_cleared_cb = callback
908+ return self.sso_proxy.on_credentials_cleared_cb
909+
910+ def register_to_credentials_found(self, callback):
911+ """Register to the CredentialsFound dbus signal."""
912+ self.sso_proxy.on_credentials_found_cb = callback
913+ return self.sso_proxy.on_credentials_found_cb
914+
915+ def register_to_credentials_not_found(self, callback):
916+ """Register to the CredentialsFound dbus signal."""
917+ self.sso_proxy.on_credentials_not_found_cb = callback
918+ return self.sso_proxy.on_credentials_not_found_cb
919+
920+ def register_to_authorization_denied(self, callback):
921+ """Register to the AuthorizationDenied dbus signal."""
922+ self.sso_proxy.on_authorization_denied_cb = callback
923+ return self.sso_proxy.on_authorization_denied_cb
924+
925+ def register_to_credentials_error(self, callback):
926+ """Register to the CredentialsError dbus signal."""
927+ self.sso_proxy.on_credentials_error_cb = callback
928+ return self.sso_proxy.on_credentials_error_cb
929+
930+
931+@defer.inlineCallbacks
932+def get_creds_proxy():
933+ """Get the CredentialsManagement dbus proxy."""
934+ client = UbuntuSSOClient()
935+ client = yield client.connect()
936+ defer.returnValue(CredentialsManagement(client.cred_management))
937+
938+
939+class CredentialsManagementTool(CredentialsManagementToolRoot):
940+ """Wrapper used to manage the creds of ubuntu one."""
941+
942+ def __init__(self):
943+ """Create a new instance."""
944+ super(CredentialsManagementTool, self).__init__(get_creds_proxy)

Subscribers

People subscribed via source and target branches