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

Proposed by Manuel de la Peña
Status: Merged
Approved by: Roberto Alsina
Approved revision: 995
Merged at revision: 984
Proposed branch: lp:~mandel/ubuntuone-client/provide_credentials_management
Merge into: lp:ubuntuone-client
Prerequisite: lp:~mandel/ubuntuone-client/pass_main_to_ipc_root
Diff against target: 1019 lines (+702/-230)
8 files modified
po/POTFILES.in (+1/-0)
tests/platform/linux/test_credentials.py (+4/-5)
tests/platform/windows/test_credentials.py (+155/-0)
tests/test_credentials.py (+99/-0)
ubuntuone/credentials.py (+255/-0)
ubuntuone/platform/linux/__init__.py (+1/-1)
ubuntuone/platform/linux/credentials.py (+56/-224)
ubuntuone/platform/windows/credentials.py (+131/-0)
To merge this branch: bzr merge lp:~mandel/ubuntuone-client/provide_credentials_management
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Shane Fagan (community) Approve
Review via email: mp+59743@code.launchpad.net

Commit message

This branch fixed the issue where windows does not have credential management code. This branch does the following:

* Refactor the CredentialsManagementTool so that it can be used by other platforms.
* Implemented the CredentialsManagement code for Windows.

Description of the change

This branch fixed the issue where windows does not have credential management code. This branch does the following:

* Refactor the CredentialsManagementTool so that it can be used by other platforms.
* Implemented the CredentialsManagement code for Windows.

This branch might break control panel (to be confirmed) and has to be tested in both platforms (windows/linux)

On Linux:
$ ./autogen
$ make check

On Windows:

python C:\Python27\Scripts\u1trial tests\platform\windows\test_credentials

To post a comment you must log in.
Revision history for this message
Shane Fagan (shanepatrickfagan) wrote :

Passes tests and nothing big pops out in the code

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

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'po/POTFILES.in'
--- po/POTFILES.in 2011-02-21 23:16:03 +0000
+++ po/POTFILES.in 2011-05-03 09:17:06 +0000
@@ -1,6 +1,7 @@
1ubuntuone/clientdefs.py.in1ubuntuone/clientdefs.py.in
2ubuntuone/status/aggregator.py2ubuntuone/status/aggregator.py
3ubuntuone/platform/linux/credentials.py3ubuntuone/platform/linux/credentials.py
4ubuntuone/platform/windows/credentials.py
4data/emblem-ubuntuone-downloading.icon.in5data/emblem-ubuntuone-downloading.icon.in
5data/emblem-ubuntuone-unsynchronized.icon.in6data/emblem-ubuntuone-unsynchronized.icon.in
6data/emblem-ubuntuone-uploading.icon.in7data/emblem-ubuntuone-uploading.icon.in
78
=== modified file 'tests/platform/linux/test_credentials.py'
--- tests/platform/linux/test_credentials.py 2011-02-15 20:32:42 +0000
+++ tests/platform/linux/test_credentials.py 2011-05-03 09:17:06 +0000
@@ -25,12 +25,11 @@
25from ubuntuone.devtools.handlers import MementoHandler25from ubuntuone.devtools.handlers import MementoHandler
2626
27from ubuntuone.platform.linux.credentials import (dbus, logger, logging,27from ubuntuone.platform.linux.credentials import (dbus, logger, logging,
28 CredentialsManagement, CredentialsManagementTool, CredentialsError,28 CredentialsManagement, ubuntu_sso, DBUS_BUS_NAME, DBUS_CREDENTIALS_PATH,
29 ubuntu_sso,29 DBUS_CREDENTIALS_IFACE, APP_NAME, HELP_TEXT_KEY, DESCRIPTION,
30 DBUS_BUS_NAME, DBUS_CREDENTIALS_PATH, DBUS_CREDENTIALS_IFACE,30 TC_URL_KEY, TC_URL, PING_URL_KEY, PING_URL, TIMEOUT_INTERVAL,
31 APP_NAME, HELP_TEXT_KEY, DESCRIPTION, TC_URL_KEY, TC_URL,
32 PING_URL_KEY, PING_URL, TIMEOUT_INTERVAL,
33)31)
32from ubuntuone.credentials import CredentialsManagementTool, CredentialsError
3433
35FAKED_CREDENTIALS = {34FAKED_CREDENTIALS = {
36 'consumer_key': 'faked_consumer_key',35 'consumer_key': 'faked_consumer_key',
3736
=== added file 'tests/platform/windows/test_credentials.py'
--- tests/platform/windows/test_credentials.py 1970-01-01 00:00:00 +0000
+++ tests/platform/windows/test_credentials.py 2011-05-03 09:17:06 +0000
@@ -0,0 +1,155 @@
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Author: Manuel de la Pena <manuel@canonical.com>
4#
5# Copyright 2011 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18"""Tests for the credentials management on Windows."""
19
20from mocker import MockerTestCase
21
22from ubuntu_sso.credentials import HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY
23from ubuntuone.platform.windows.credentials import (
24 CredentialsManagement,
25 APP_NAME,
26 DESCRIPTION,
27 PING_URL,
28 TC_URL)
29
30
31class TestCredentialsManagement(MockerTestCase):
32 """Test that the credentials management is correctly used."""
33
34 def setUp(self):
35 """Set the different tests."""
36 super(TestCredentialsManagement, self).setUp()
37 self.proxy = self.mocker.mock()
38 self.management = CredentialsManagement(self.proxy)
39
40 def test_find_credentials(self):
41 """Ensure we do ask corectly for the credentials."""
42 reply_handler = lambda: None
43 error_handler = lambda: None
44 self.proxy.find_credentials(APP_NAME, {}, reply_handler=reply_handler,
45 error_handler=error_handler)
46 self.mocker.replay()
47 self.management.find_credentials(reply_handler=reply_handler,
48 error_handler=error_handler)
49
50 def test_clear_credentials(self):
51 """Ensure we do clear the credentials."""
52 reply_handler = lambda: None
53 error_handler = lambda: None
54 self.proxy.clear_credentials(APP_NAME, {}, reply_handler=reply_handler,
55 error_handler=error_handler)
56 self.mocker.replay()
57 self.management.clear_credentials(reply_handler=reply_handler,
58 error_handler=error_handler)
59
60 def test_store_credentials(self):
61 """Store the token for Ubuntu One application."""
62 credentials = 'creds'
63 reply_handler = lambda: None
64 error_handler = lambda: None
65 self.proxy.store_credentials(APP_NAME, credentials,
66 reply_handler=reply_handler, error_handler=error_handler)
67 self.mocker.replay()
68 self.management.store_credentials(credentials,
69 reply_handler=reply_handler, error_handler=error_handler)
70
71 def test_register(self):
72 """Get credentials if found else prompt to register to Ubuntu One."""
73 reply_handler = lambda: None
74 error_handler = lambda: None
75 args = dict(test='test', args='args')
76 extra_params = {HELP_TEXT_KEY: DESCRIPTION, TC_URL_KEY: TC_URL,
77 PING_URL_KEY: PING_URL}
78 extra_params.update(args)
79 self.proxy.register(APP_NAME, extra_params,
80 reply_handler=reply_handler, error_handler=error_handler)
81 self.mocker.replay()
82 self.management.register(args, reply_handler, error_handler)
83
84 def test_login(self):
85 """Get credentials if found else prompt to login to Ubuntu One."""
86 reply_handler = lambda: None
87 error_handler = lambda: None
88 args = dict(test='test', args='args')
89 extra_params = {HELP_TEXT_KEY: DESCRIPTION, TC_URL_KEY: TC_URL,
90 PING_URL_KEY: PING_URL}
91 extra_params.update(args)
92 self.proxy.login(APP_NAME, extra_params,
93 reply_handler=reply_handler, error_handler=error_handler)
94 self.mocker.replay()
95 self.management.login(args, reply_handler, error_handler)
96
97 def test_register_to_credentials_stored(self):
98 """Register to the CredentialsStored dbus signal."""
99 callback = lambda: None
100 self.proxy.on_credentials_stored_cb = callback
101 self.proxy.on_credentials_stored_cb
102 self.mocker.result(callback)
103 self.mocker.replay()
104 self.assertIs(callback,
105 self.management.register_to_credentials_stored(callback))
106
107 def test_register_to_credentials_cleared(self):
108 """Register to the CredentialsCleared dbus signal."""
109 callback = lambda: None
110 self.proxy.on_credentials_cleared_cb = callback
111 self.proxy.on_credentials_cleared_cb
112 self.mocker.result(callback)
113 self.mocker.replay()
114 self.assertIs(callback,
115 self.management.register_to_credentials_cleared(callback))
116
117 def test_register_to_credentials_found(self):
118 """Register to the CredentialsFound dbus signal."""
119 callback = lambda: None
120 self.proxy.on_credentials_found_cb = callback
121 self.proxy.on_credentials_found_cb
122 self.mocker.result(callback)
123 self.mocker.replay()
124 self.assertIs(callback,
125 self.management.register_to_credentials_found(callback))
126
127 def test_register_to_credentials_not_found(self):
128 """Register to the CredentialsFound dbus signal."""
129 callback = lambda: None
130 self.proxy.on_credentials_not_found_cb = callback
131 self.proxy.on_credentials_not_found_cb
132 self.mocker.result(callback)
133 self.mocker.replay()
134 self.assertIs(callback,
135 self.management.register_to_credentials_not_found(callback))
136
137 def test_register_to_authorization_denied(self):
138 """Register to the AuthorizationDenied dbus signal."""
139 callback = lambda: None
140 self.proxy.on_authorization_denied_cb = callback
141 self.proxy.on_authorization_denied_cb
142 self.mocker.result(callback)
143 self.mocker.replay()
144 self.assertIs(callback,
145 self.management.register_to_authorization_denied(callback))
146
147 def test_register_to_credentials_error(self):
148 """Register to the CredentialsError dbus signal."""
149 callback = lambda: None
150 self.proxy.on_credentials_error_cb = callback
151 self.proxy.on_credentials_error_cb
152 self.mocker.result(callback)
153 self.mocker.replay()
154 self.assertIs(callback,
155 self.management.register_to_credentials_error(callback))
0156
=== added file 'tests/test_credentials.py'
--- tests/test_credentials.py 1970-01-01 00:00:00 +0000
+++ tests/test_credentials.py 2011-05-03 09:17:06 +0000
@@ -0,0 +1,99 @@
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Author: Manuel de la Pena<manuel@canonical.com>
5#
6# Copyright 2011 Canonical Ltd.
7#
8# This program is free software: you can redistribute it and/or modify it
9# under the terms of the GNU General Public License version 3, as published
10# by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranties of
14# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15# PURPOSE. See the GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program. If not, see <http://www.gnu.org/licenses/>.
19"""Platform independent tests for the credentials management."""
20
21from mocker import MockerTestCase, MATCH
22
23from ubuntuone.credentials import CredentialsManagementTool
24
25
26class TestCredentialsManagementTool(MockerTestCase):
27 """Test the crendentials management tool mocking the proxy."""
28
29 def setUp(self):
30 """Set the diff tests."""
31 super(TestCredentialsManagementTool, self).setUp()
32 self.get_cred_proxy = self.mocker.replace(
33 'ubuntuone.platform.get_creds_proxy')
34 self.proxy = self.mocker.mock()
35 self.management_tool = CredentialsManagementTool()
36
37 def test_find_credentials(self):
38 """Test that we do ask for the credentials correctly."""
39 signals = ['creds_found', 'creds_not_found', 'creds_erro']
40 self.get_cred_proxy()
41 self.mocker.result(self.proxy)
42 self.proxy.register_to_credentials_found(MATCH(callable))
43 self.mocker.result(signals[0])
44 self.proxy.register_to_credentials_not_found(MATCH(callable))
45 self.mocker.result(signals[1])
46 self.proxy.register_to_credentials_error(MATCH(callable))
47 self.mocker.result(signals[2])
48 self.proxy.find_credentials(reply_handler=MATCH(callable),
49 error_handler=MATCH(callable))
50 self.mocker.replay()
51 return self.management_tool.find_credentials()
52
53 def test_clear_credentials(self):
54 """Test that we clear the credentials correctly."""
55 signals = ['creds_cleared', 'creds_error']
56 self.get_cred_proxy()
57 self.mocker.result(self.proxy)
58 self.proxy.register_to_credentials_cleared(MATCH(callable))
59 self.mocker.result(signals[0])
60 self.proxy.register_to_credentials_error(MATCH(callable))
61 self.mocker.result(signals[1])
62 self.proxy.clear_credentials(reply_handler=MATCH(callable),
63 error_handler=MATCH(callable))
64 self.mocker.replay()
65 return self.management_tool.clear_credentials()
66
67 def test_store_credentials(self):
68 """Test that we store the credentials correctly."""
69 token = 'token'
70 signals = ['creds_stored','creds_error']
71 self.get_cred_proxy()
72 self.mocker.result(self.proxy)
73 self.proxy.register_to_credentials_stored(MATCH(callable))
74 self.mocker.result(signals[0])
75 self.proxy.register_to_credentials_error(MATCH(callable))
76 self.mocker.result(signals[1])
77 self.proxy.store_credentials(token, reply_handler=MATCH(callable),
78 error_handler=MATCH(callable))
79 self.mocker.replay()
80 return self.management_tool.store_credentials(token)
81
82 def test_register(self):
83 """Test that we correctly register."""
84 window_id = 10
85 window_id_dict = dict(window_id=str(window_id))
86 signals = ['creds_found', 'creds_denied', 'creds_error']
87 self.get_cred_proxy()
88 self.mocker.result(self.proxy)
89 self.proxy.register_to_credentials_found(MATCH(callable))
90 self.mocker.result(signals[0])
91 self.proxy.register_to_authorization_denied(MATCH(callable))
92 self.mocker.result(signals[1])
93 self.proxy.register_to_credentials_error(MATCH(callable))
94 self.mocker.result(signals[2])
95 self.proxy.register(window_id_dict, reply_handler=MATCH(callable),
96 error_handler=MATCH(callable))
97 self.mocker.replay()
98 return self.management_tool.register(window_id=window_id)
99
0100
=== added file 'ubuntuone/credentials.py'
--- ubuntuone/credentials.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/credentials.py 2011-05-03 09:17:06 +0000
@@ -0,0 +1,255 @@
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Author: Natalia B. Bidart <natalia.bidart@canonical.com>
5# Author: Manuel de la Pena<manuel@canonical.com>
6#
7# Copyright 2011 Canonical Ltd.
8#
9# This program is free software: you can redistribute it and/or modify it
10# under the terms of the GNU General Public License version 3, as published
11# by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful, but
14# WITHOUT ANY WARRANTY; without even the implied warranties of
15# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16# PURPOSE. See the GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program. If not, see <http://www.gnu.org/licenses/>.
20"""Common code for the credentials management."""
21
22import os
23
24from twisted.internet import defer
25
26from ubuntuone.logger import (basic_formatter, logging,
27 CustomRotatingFileHandler, LOGFOLDER)
28from ubuntuone.platform import get_creds_proxy
29
30LOG_LEVEL = logging.DEBUG
31path = os.path.join(LOGFOLDER, 'credentials.log')
32MAIN_HANDLER = CustomRotatingFileHandler(path)
33MAIN_HANDLER.setFormatter(basic_formatter)
34MAIN_HANDLER.setLevel(LOG_LEVEL)
35
36logger = logging.getLogger("ubuntuone.credentials")
37logger.setLevel(LOG_LEVEL)
38logger.addHandler(MAIN_HANDLER)
39
40
41class CredentialsError(Exception):
42 """A general exception when hadling credentilas."""
43
44
45class CredentialsManagementTool(object):
46 """Wrapper to CredentialsManagement.
47
48 The goal of this class is to abstract the caller from calling the DBus
49 service implemented in the class CredentialsManagement.
50
51 """
52
53 def __init__(self):
54 self._cleanup_signals = []
55
56 def cleanup(self, _):
57 """Disconnect all the DBus signals."""
58 for sig in self._cleanup_signals:
59 logger.debug('cleanup: removing signal match %r', sig)
60 sig.remove()
61
62 return _
63
64 @defer.inlineCallbacks
65 def find_credentials(self):
66 """Find credentials for Ubuntu One.
67
68 Return a deferred that, when fired, will return the credentials for
69 Ubuntu One for the current logged in user.
70
71 The credentials is a dictionary with both string keys and values. The
72 dictionary may be either empty if there are no credentials for the
73 user, or will hold five items as follow:
74
75 - "name"
76 - "token"
77 - "token_secret"
78 - "consumer_key"
79 - "consumer_secret"
80
81 """
82 d = defer.Deferred()
83 d.addBoth(self.cleanup)
84
85 proxy = get_creds_proxy()
86
87 sig = proxy.register_to_credentials_found(d.callback)
88 self._cleanup_signals.append(sig)
89
90 sig = proxy.register_to_credentials_not_found(lambda: d.callback({}))
91 self._cleanup_signals.append(sig)
92
93 sig = proxy.register_to_credentials_error(
94 lambda error_dict: d.errback(CredentialsError(error_dict)))
95 self._cleanup_signals.append(sig)
96
97 done = defer.Deferred()
98 proxy.find_credentials(reply_handler=lambda: done.callback(None),
99 error_handler=lambda *a: done.errback(a))
100
101 yield done
102
103 result = yield d
104 defer.returnValue(result)
105
106 @defer.inlineCallbacks
107 def clear_credentials(self):
108 """Clear credentials for Ubuntu One.
109
110 Return a deferred that, when fired, will return no result but will
111 indicate that the Ubuntu One credentials for the current user were
112 removed from the local keyring.
113
114 """
115 d = defer.Deferred()
116 d.addBoth(self.cleanup)
117
118 proxy = get_creds_proxy()
119 sig = proxy.register_to_credentials_cleared(lambda: d.callback(None))
120 self._cleanup_signals.append(sig)
121
122 sig = proxy.register_to_credentials_error(
123 lambda error_dict: d.errback(CredentialsError(error_dict)))
124 self._cleanup_signals.append(sig)
125
126 done = defer.Deferred()
127 proxy.clear_credentials(reply_handler=lambda: done.callback(None),
128 error_handler=lambda *a: done.errback(a))
129
130 yield done
131
132 yield d
133
134 @defer.inlineCallbacks
135 def store_credentials(self, token):
136 """Store credentials for Ubuntu One.
137
138 The parameter 'token' should be a dictionary that matches the
139 description of the result of 'find_credentials'.
140
141 Return a deferred that, when fired, will return no result but will
142 indicate that 'token' was stored in the local keyring as the new Ubuntu
143 One credentials for the current user.
144
145 """
146 d = defer.Deferred()
147 d.addBoth(self.cleanup)
148
149 proxy = get_creds_proxy()
150 sig = proxy.register_to_credentials_stored(lambda: d.callback(None))
151 self._cleanup_signals.append(sig)
152
153 sig = proxy.register_to_credentials_error(
154 lambda error_dict: d.errback(CredentialsError(error_dict)))
155 self._cleanup_signals.append(sig)
156
157 done = defer.Deferred()
158 proxy.store_credentials(token,
159 reply_handler=lambda: done.callback(None),
160 error_handler=lambda *a: done.errback(a))
161
162 yield done
163
164 yield d
165
166 @defer.inlineCallbacks
167 def register(self, window_id=0):
168 """Register to Ubuntu One.
169
170 Return a deferred that, when fired, will return the credentials for
171 Ubuntu One for the current logged in user.
172
173 If there are no credentials for the current user, a GTK UI will be
174 opened to invite the user to register to Ubuntu One. This UI provides
175 options to either register (main screen) or login (secondary screen).
176
177 You can pass an optional 'window_id' parameter that will be used by the
178 GTK UI to be set transient for it.
179
180 The returned credentials will be either a non-empty dictionary like the
181 one described in 'find_credentials', or None. The latter indicates that
182 there were no credentials for the user in the local keyring and that
183 the user refused to register to Ubuntu One.
184
185 """
186 d = defer.Deferred()
187 d.addBoth(self.cleanup)
188
189 proxy = get_creds_proxy()
190
191 sig = proxy.register_to_credentials_found(d.callback)
192 self._cleanup_signals.append(sig)
193
194 sig = proxy.register_to_authorization_denied(lambda: d.callback(None))
195 self._cleanup_signals.append(sig)
196
197 sig = proxy.register_to_credentials_error(
198 lambda error_dict: d.errback(CredentialsError(error_dict)))
199 self._cleanup_signals.append(sig)
200
201 done = defer.Deferred()
202 proxy.register({'window_id': str(window_id)},
203 reply_handler=lambda: done.callback(None),
204 error_handler=lambda *a: done.errback(a))
205
206 yield done
207
208 result = yield d
209 defer.returnValue(result)
210
211 @defer.inlineCallbacks
212 def login(self, window_id=0):
213 """Login to Ubuntu One.
214
215 Return a deferred that, when fired, will return the credentials for
216 Ubuntu One for the current logged in user.
217
218 If there are no credentials for the current user, a GTK UI will be
219 opened to invite the user to login to Ubuntu One. This UI provides
220 options to either login (main screen) or retrieve password (secondary
221 screen).
222
223 You can pass an optional 'window_id' parameter that will be used by the
224 GTK UI to be set transient for it.
225
226 The returned credentials will be either a non-empty dictionary like the
227 one described in 'find_credentials', or None. The latter indicates that
228 there were no credentials for the user in the local keyring and that
229 the user refused to login to Ubuntu One.
230
231 """
232 d = defer.Deferred()
233 d.addBoth(self.cleanup)
234
235 proxy = get_creds_proxy()
236
237 sig = proxy.register_to_credentials_found(d.callback)
238 self._cleanup_signals.append(sig)
239
240 sig = proxy.register_to_authorization_denied(lambda: d.callback(None))
241 self._cleanup_signals.append(sig)
242
243 sig = proxy.register_to_credentials_error(
244 lambda error_dict: d.errback(CredentialsError(error_dict)))
245 self._cleanup_signals.append(sig)
246
247 done = defer.Deferred()
248 proxy.login({'window_id': str(window_id)},
249 reply_handler=lambda: done.callback(None),
250 error_handler=lambda *a: done.errback(a))
251
252 yield done
253
254 result = yield d
255 defer.returnValue(result)
0256
=== modified file 'ubuntuone/platform/linux/__init__.py'
--- ubuntuone/platform/linux/__init__.py 2011-03-30 16:17:37 +0000
+++ ubuntuone/platform/linux/__init__.py 2011-05-03 09:17:06 +0000
@@ -51,7 +51,7 @@
51 get_udf_path,51 get_udf_path,
52 VMMetadataUpgraderMixIn52 VMMetadataUpgraderMixIn
53)53)
54from ubuntuone.platform.linux.credentials import CredentialsManagement54from ubuntuone.platform.linux.credentials import get_creds_proxy
55from ubuntuone.platform.linux.logger import setup_filesystem_logging, get_filesystem_logger55from ubuntuone.platform.linux.logger import setup_filesystem_logging, get_filesystem_logger
56from ubuntuone.platform.linux.filesystem_notifications import FilesystemMonitor56from ubuntuone.platform.linux.filesystem_notifications import FilesystemMonitor
57from ubuntuone.platform.linux.notification import Notification57from ubuntuone.platform.linux.notification import Notification
5858
=== modified file 'ubuntuone/platform/linux/credentials.py'
--- ubuntuone/platform/linux/credentials.py 2011-02-24 14:07:32 +0000
+++ ubuntuone/platform/linux/credentials.py 2011-05-03 09:17:06 +0000
@@ -15,7 +15,6 @@
15#15#
16# You should have received a copy of the GNU General Public License along16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Ubuntu One credentials management dbus service."""18"""Ubuntu One credentials management dbus service."""
2019
21import os20import os
@@ -24,7 +23,6 @@
24import gettext23import gettext
25import ubuntu_sso24import ubuntu_sso
2625
27from twisted.internet import defer
28from ubuntu_sso.credentials import HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY26from ubuntu_sso.credentials import HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY
2927
30from ubuntuone.logger import (basic_formatter, logging,28from ubuntuone.logger import (basic_formatter, logging,
@@ -238,237 +236,71 @@
238 reply_handler=reply_handler, error_handler=error_handler)236 reply_handler=reply_handler, error_handler=error_handler)
239237
240238
241class CredentialsError(Exception):239class CredentialsManagementProxy(object):
242 """A general exception when hadling credentilas."""240 """Proxy that allows to work with the dbus api.
243241
244242 This proxy has been added to hide the exact details of
245class CredentialsManagementTool(object):243 how the signals are connected. This allows the reuse of
246 """Wrapper to CredentialsManagement.244 the CredentialsManagementTool in diff platforms.
247
248 The goal of this class is to abstract the caller from calling the DBus
249 service implemented in the class CredentialsManagement.
250
251 """245 """
252246
253 def __init__(self):247 def __init__(self):
254 self._cleanup_signals = []248 """Create a new instance."""
255
256 def _get_creds_proxy(self):
257 """Get the CredentialsManagement dbus proxy."""
258 bus = dbus.SessionBus()249 bus = dbus.SessionBus()
259 try:250 try:
260 obj = bus.get_object(DBUS_BUS_NAME,251 obj = bus.get_object(DBUS_BUS_NAME,
261 DBUS_CREDENTIALS_PATH,252 DBUS_CREDENTIALS_PATH,
262 follow_name_owner_changes=True)253 follow_name_owner_changes=True)
263 proxy = dbus.Interface(obj, DBUS_CREDENTIALS_IFACE)254 self.proxy = dbus.Interface(obj, DBUS_CREDENTIALS_IFACE)
264 except:255 except:
265 logger.exception('get_creds_proxy:')256 logger.exception('get_creds_proxy:')
266 raise257 raise
267258
268 return proxy259 def find_credentials(self, *args, **kwargs):
269260 """Relay the find_credentials method."""
270 def cleanup(self, _):261 return self.proxy.find_credentials(*args, **kwargs)
271 """Disconnect all the DBus signals."""262
272 for sig in self._cleanup_signals:263 def clear_credentials(self, *args, **kwargs):
273 logger.debug('cleanup: removing signal match %r', sig)264 """Relay the clear_credentials method."""
274 sig.remove()265 return self.proxy.clear_credentials(*args, **kwargs)
275266
276 return _267 def store_credentials(self, *args, **kwargs):
277268 """Relay the store_credentials method."""
278 @defer.inlineCallbacks269 return self.proxy.store_credentials(*args, **kwargs)
279 def find_credentials(self):270
280 """Find credentials for Ubuntu One.271 def register(self, *args, **kwargs):
281272 """Relay the register method."""
282 Return a deferred that, when fired, will return the credentials for273 return self.proxy.register(*args, **kwargs)
283 Ubuntu One for the current logged in user.274
284275 def login(self, *args, **kwargs):
285 The credentials is a dictionary with both string keys and values. The276 """Relay the login method."""
286 dictionary may be either empty if there are no credentials for the277 return self.proxy.login(*args, **kwargs)
287 user, or will hold five items as follow:278
288279 def register_to_credentials_stored(self, callback):
289 - "name"280 """Register to the CredentialsStored dbus signal."""
290 - "token"281 return self.proxy.connect_to_signal('CredentialsStored', callback)
291 - "token_secret"282
292 - "consumer_key"283 def register_to_credentials_cleared(self, callback):
293 - "consumer_secret"284 """Register to the CredentialsCleared dbus signal."""
294285 return self.proxy.connect_to_signal('CredentialsCleared', callback)
295 """286
296 d = defer.Deferred()287 def register_to_credentials_found(self, callback):
297 d.addBoth(self.cleanup)288 """Register to the CredentialsFound dbus signal."""
298289 return self.proxy.connect_to_signal('CredentialsFound', callback)
299 proxy = self._get_creds_proxy()290
300291 def register_to_credentials_not_found(self, callback):
301 sig = proxy.connect_to_signal('CredentialsFound', d.callback)292 """Register to the CredentialsFound dbus signal."""
302 self._cleanup_signals.append(sig)293 return self.proxy.connect_to_signal('CredentialsNotFound', callback)
303294
304 sig = proxy.connect_to_signal('CredentialsNotFound',295 def register_to_authorization_denied(self, callback):
305 lambda: d.callback({}))296 """Register to the AuthorizationDenied dbus signal."""
306 self._cleanup_signals.append(sig)297 return self.proxy.connect_to_signal('AuthorizationDenied', callback)
307298
308 sig = proxy.connect_to_signal('CredentialsError',299 def register_to_credentials_error(self, callback):
309 lambda error_dict: d.errback(CredentialsError(error_dict)))300 """Register to the CredentialsError dbus signal."""
310 self._cleanup_signals.append(sig)301 return self.proxy.connect_to_signal('CredentialsError', callback)
311302
312 done = defer.Deferred()303
313 proxy.find_credentials(reply_handler=lambda: done.callback(None),304def get_creds_proxy():
314 error_handler=lambda *a: done.errback(a))305 """Get the CredentialsManagement dbus proxy."""
315306 return CredentialsManagementProxy()
316 yield done
317
318 result = yield d
319 defer.returnValue(result)
320
321 @defer.inlineCallbacks
322 def clear_credentials(self):
323 """Clear credentials for Ubuntu One.
324
325 Return a deferred that, when fired, will return no result but will
326 indicate that the Ubuntu One credentials for the current user were
327 removed from the local keyring.
328
329 """
330 d = defer.Deferred()
331 d.addBoth(self.cleanup)
332
333 proxy = self._get_creds_proxy()
334 sig = proxy.connect_to_signal('CredentialsCleared',
335 lambda: d.callback(None))
336 self._cleanup_signals.append(sig)
337
338 sig = proxy.connect_to_signal('CredentialsError',
339 lambda error_dict: d.errback(CredentialsError(error_dict)))
340 self._cleanup_signals.append(sig)
341
342 done = defer.Deferred()
343 proxy.clear_credentials(reply_handler=lambda: done.callback(None),
344 error_handler=lambda *a: done.errback(a))
345
346 yield done
347
348 yield d
349
350 @defer.inlineCallbacks
351 def store_credentials(self, token):
352 """Store credentials for Ubuntu One.
353
354 The parameter 'token' should be a dictionary that matches the
355 description of the result of 'find_credentials'.
356
357 Return a deferred that, when fired, will return no result but will
358 indicate that 'token' was stored in the local keyring as the new Ubuntu
359 One credentials for the current user.
360
361 """
362 d = defer.Deferred()
363 d.addBoth(self.cleanup)
364
365 proxy = self._get_creds_proxy()
366 sig = proxy.connect_to_signal('CredentialsStored',
367 lambda: d.callback(None))
368 self._cleanup_signals.append(sig)
369
370 sig = proxy.connect_to_signal('CredentialsError',
371 lambda error_dict: d.errback(CredentialsError(error_dict)))
372 self._cleanup_signals.append(sig)
373
374 done = defer.Deferred()
375 proxy.store_credentials(token,
376 reply_handler=lambda: done.callback(None),
377 error_handler=lambda *a: done.errback(a))
378
379 yield done
380
381 yield d
382
383 @defer.inlineCallbacks
384 def register(self, window_id=0):
385 """Register to Ubuntu One.
386
387 Return a deferred that, when fired, will return the credentials for
388 Ubuntu One for the current logged in user.
389
390 If there are no credentials for the current user, a GTK UI will be
391 opened to invite the user to register to Ubuntu One. This UI provides
392 options to either register (main screen) or login (secondary screen).
393
394 You can pass an optional 'window_id' parameter that will be used by the
395 GTK UI to be set transient for it.
396
397 The returned credentials will be either a non-empty dictionary like the
398 one described in 'find_credentials', or None. The latter indicates that
399 there were no credentials for the user in the local keyring and that
400 the user refused to register to Ubuntu One.
401
402 """
403 d = defer.Deferred()
404 d.addBoth(self.cleanup)
405
406 proxy = self._get_creds_proxy()
407
408 sig = proxy.connect_to_signal('CredentialsFound', d.callback)
409 self._cleanup_signals.append(sig)
410
411 sig = proxy.connect_to_signal('AuthorizationDenied',
412 lambda: d.callback(None))
413 self._cleanup_signals.append(sig)
414
415 sig = proxy.connect_to_signal('CredentialsError',
416 lambda error_dict: d.errback(CredentialsError(error_dict)))
417 self._cleanup_signals.append(sig)
418
419 done = defer.Deferred()
420 proxy.register({'window_id': str(window_id)},
421 reply_handler=lambda: done.callback(None),
422 error_handler=lambda *a: done.errback(a))
423
424 yield done
425
426 result = yield d
427 defer.returnValue(result)
428
429 @defer.inlineCallbacks
430 def login(self, window_id=0):
431 """Login to Ubuntu One.
432
433 Return a deferred that, when fired, will return the credentials for
434 Ubuntu One for the current logged in user.
435
436 If there are no credentials for the current user, a GTK UI will be
437 opened to invite the user to login to Ubuntu One. This UI provides
438 options to either login (main screen) or retrieve password (secondary
439 screen).
440
441 You can pass an optional 'window_id' parameter that will be used by the
442 GTK UI to be set transient for it.
443
444 The returned credentials will be either a non-empty dictionary like the
445 one described in 'find_credentials', or None. The latter indicates that
446 there were no credentials for the user in the local keyring and that
447 the user refused to login to Ubuntu One.
448
449 """
450 d = defer.Deferred()
451 d.addBoth(self.cleanup)
452
453 proxy = self._get_creds_proxy()
454
455 sig = proxy.connect_to_signal('CredentialsFound', d.callback)
456 self._cleanup_signals.append(sig)
457
458 sig = proxy.connect_to_signal('AuthorizationDenied',
459 lambda: d.callback(None))
460 self._cleanup_signals.append(sig)
461
462 sig = proxy.connect_to_signal('CredentialsError',
463 lambda error_dict: d.errback(CredentialsError(error_dict)))
464 self._cleanup_signals.append(sig)
465
466 done = defer.Deferred()
467 proxy.login({'window_id': str(window_id)},
468 reply_handler=lambda: done.callback(None),
469 error_handler=lambda *a: done.errback(a))
470
471 yield done
472
473 result = yield d
474 defer.returnValue(result)
475307
=== added file 'ubuntuone/platform/windows/credentials.py'
--- ubuntuone/platform/windows/credentials.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/platform/windows/credentials.py 2011-05-03 09:17:06 +0000
@@ -0,0 +1,131 @@
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Author: Manuel de la Pena<manuel@canonical.com>
5#
6# Copyright 2011 Canonical Ltd.
7#
8# This program is free software: you can redistribute it and/or modify it
9# under the terms of the GNU General Public License version 3, as published
10# by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranties of
14# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15# PURPOSE. See the GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program. If not, see <http://www.gnu.org/licenses/>.
19"""Ubuntu One credentials management IPC service."""
20
21import os
22
23import gettext
24
25from ubuntu_sso.main.windows import UbuntuSSOClient
26from ubuntu_sso.credentials import HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY
27from twisted.internet import defer
28
29from ubuntuone.logger import (basic_formatter, logging,
30 CustomRotatingFileHandler, LOGFOLDER)
31from ubuntuone.clientdefs import GETTEXT_PACKAGE
32
33
34Q_ = lambda string: gettext.dgettext(GETTEXT_PACKAGE, string)
35NO_OP = lambda *args, **kwargs: None
36
37LOG_LEVEL = logging.DEBUG
38path = os.path.join(LOGFOLDER, 'credentials.log')
39MAIN_HANDLER = CustomRotatingFileHandler(path)
40MAIN_HANDLER.setFormatter(basic_formatter)
41MAIN_HANDLER.setLevel(LOG_LEVEL)
42
43logger = logging.getLogger("ubuntuone.credentials")
44logger.setLevel(LOG_LEVEL)
45logger.addHandler(MAIN_HANDLER)
46
47APP_NAME = "Ubuntu One"
48TC_URL = "https://one.ubuntu.com/terms/"
49PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/"
50DESCRIPTION = Q_('Ubuntu One requires an Ubuntu Single Sign On (SSO) account. '
51 'This process will allow you to create a new account, '
52 'if you do not yet have one.')
53
54
55class CredentialsManagement(object):
56 """Object that manages Ubuntu One credentials."""
57
58 def __init__(self, proxy, *args, **kwargs):
59 super(CredentialsManagement, self).__init__(*args, **kwargs)
60 self.sso_proxy = proxy
61
62 def find_credentials(self, reply_handler=NO_OP, error_handler=NO_OP):
63 """Ask the Ubuntu One credentials."""
64 self.sso_proxy.find_credentials(APP_NAME, {},
65 reply_handler=reply_handler, error_handler=error_handler)
66
67
68 def clear_credentials(self, reply_handler=NO_OP, error_handler=NO_OP):
69 """Clear the Ubuntu One credentials."""
70 self.sso_proxy.clear_credentials(APP_NAME, {},
71 reply_handler=reply_handler, error_handler=error_handler)
72
73 def store_credentials(self, credentials,
74 reply_handler=NO_OP, error_handler=NO_OP):
75 """Store the token for Ubuntu One application."""
76 self.sso_proxy.store_credentials(APP_NAME, credentials,
77 reply_handler=reply_handler, error_handler=error_handler)
78
79 def register(self, args, reply_handler=NO_OP, error_handler=NO_OP):
80 """Get credentials if found else prompt to register to Ubuntu One."""
81 params = {HELP_TEXT_KEY: DESCRIPTION, TC_URL_KEY: TC_URL,
82 PING_URL_KEY: PING_URL}
83 params.update(args)
84 self.sso_proxy.register(APP_NAME, params,
85 reply_handler=reply_handler, error_handler=error_handler)
86
87 def login(self, args, reply_handler=NO_OP, error_handler=NO_OP):
88 """Get credentials if found else prompt to login to Ubuntu One."""
89 params = {HELP_TEXT_KEY: DESCRIPTION, TC_URL_KEY: TC_URL,
90 PING_URL_KEY: PING_URL}
91 params.update(args)
92 self.sso_proxy.login(APP_NAME, params,
93 reply_handler=reply_handler, error_handler=error_handler)
94
95 def register_to_credentials_stored(self, callback):
96 """Register to the CredentialsStored dbus signal."""
97 self.sso_proxy.on_credentials_stored_cb = callback
98 return self.sso_proxy.on_credentials_stored_cb
99
100 def register_to_credentials_cleared(self, callback):
101 """Register to the CredentialsCleared dbus signal."""
102 self.sso_proxy.on_credentials_cleared_cb = callback
103 return self.sso_proxy.on_credentials_cleared_cb
104
105 def register_to_credentials_found(self, callback):
106 """Register to the CredentialsFound dbus signal."""
107 self.sso_proxy.on_credentials_found_cb = callback
108 return self.sso_proxy.on_credentials_found_cb
109
110 def register_to_credentials_not_found(self, callback):
111 """Register to the CredentialsFound dbus signal."""
112 self.sso_proxy.on_credentials_not_found_cb = callback
113 return self.sso_proxy.on_credentials_not_found_cb
114
115 def register_to_authorization_denied(self, callback):
116 """Register to the AuthorizationDenied dbus signal."""
117 self.sso_proxy.on_authorization_denied_cb = callback
118 return self.sso_proxy.on_authorization_denied_cb
119
120 def register_to_credentials_error(self, callback):
121 """Register to the CredentialsError dbus signal."""
122 self.sso_proxy.on_credentials_error_cb = callback
123 return self.sso_proxy.on_credentials_error_cb
124
125
126@defer.inlineCallbacks
127def get_creds_proxy():
128 """Get the CredentialsManagement dbus proxy."""
129 client = UbuntuSSOClient()
130 client = yield client.connect()
131 defer.returnValue(CredentialsManagement(client.cred_management))

Subscribers

People subscribed via source and target branches