Merge lp:~mandel/ubuntu-sso-client/implement_windows_main_1 into lp:ubuntu-sso-client
- implement_windows_main_1
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Manuel de la Peña |
Approved revision: | 696 |
Merged at revision: | 680 |
Proposed branch: | lp:~mandel/ubuntu-sso-client/implement_windows_main_1 |
Merge into: | lp:ubuntu-sso-client |
Prerequisite: | lp:~mandel/ubuntu-sso-client/implement_windows_networkstatus |
Diff against target: |
1267 lines (+741/-187) 9 files modified
run-tests (+1/-1) run-tests.bat (+1/-1) ubuntu_sso/main/__init__.py (+375/-0) ubuntu_sso/main/linux.py (+48/-166) ubuntu_sso/main/windows.py (+17/-0) ubuntu_sso/tests/main/__init__.py (+17/-0) ubuntu_sso/tests/main/test_common.py (+244/-0) ubuntu_sso/tests/main/test_linux.py (+21/-19) ubuntu_sso/tests/main/test_windows.py (+17/-0) |
To merge this branch: | bzr merge lp:~mandel/ubuntu-sso-client/implement_windows_main_1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alejandro J. Cura (community) | Approve | ||
Roberto Alsina (community) | Approve | ||
Review via email: mp+52707@code.launchpad.net |
Commit message
First step of implementing the code in main on windows.
Description of the change
First step of implementing the code in main on windows.
- 689. By Manuel de la Peña
-
Merged implement_
windows_ networkstatus into implement_ windows_ main_1. - 690. By Manuel de la Peña
-
Merged implement_
windows_ networkstatus into implement_ windows_ main_1. - 691. By Manuel de la Peña
-
Merged implement_
windows_ networkstatus into implement_ windows_ main_1. - 692. By Manuel de la Peña
-
Renamed test files so they are correctly ignored.
- 693. By Manuel de la Peña
-
Renamed test files so they are correctly ignored.
Alejandro J. Cura (alecu) wrote : | # |
When running the tests on natty:
alecu@breetai:
Running test suite for ubuntu_sso
Xlib: extension "RANDR" missing on display ":99".
Traceback (most recent call last):
File "/usr/bin/u1trial", line 246, in <module>
main()
File "/usr/bin/u1trial", line 243, in main
TestRunner(
File "/usr/bin/u1trial", line 181, in run
options.
File "/usr/bin/u1trial", line 160, in _collect_tests
module_suite = self._load_
File "/usr/bin/u1trial", line 88, in _load_unittest
module = __import__(modpath, None, None, [""])
File "/home/
from ubuntu_
File "/home/
import pythoncom
ImportError: No module named pythoncom
- 694. By Manuel de la Peña
-
Added the correct ignore to the runt-test script.
- 695. By Manuel de la Peña
-
Fixed style issues.
Alejandro J. Cura (alecu) wrote : | # |
Great branch!
A couple of minor nitpicks:
* a small typo: "Object object"
* and a weird name for a test method: CredentialsMana
Manuel de la Peña (mandel) wrote : | # |
Alecu,
Thanks for the comments, I'll fix those two thing you mentioned, better now than never :)
- 696. By Manuel de la Peña
-
Fixed test name and small typo.
Preview Diff
1 | === modified file 'run-tests' | |||
2 | --- run-tests 2011-02-24 02:46:19 +0000 | |||
3 | +++ run-tests 2011-03-17 08:43:34 +0000 | |||
4 | @@ -33,5 +33,5 @@ | |||
5 | 33 | } | 33 | } |
6 | 34 | 34 | ||
7 | 35 | echo "Running test suite for ""$MODULE" | 35 | echo "Running test suite for ""$MODULE" |
9 | 36 | `which xvfb-run` u1trial "$MODULE" -i "test_windows_networkstate.py" && style_check | 36 | `which xvfb-run` u1trial "$MODULE" -i "test_windows.py" && style_check |
10 | 37 | rm -rf _trial_temp | 37 | rm -rf _trial_temp |
11 | 38 | 38 | ||
12 | === modified file 'run-tests.bat' | |||
13 | --- run-tests.bat 2011-03-15 08:27:10 +0000 | |||
14 | +++ run-tests.bat 2011-03-17 08:43:34 +0000 | |||
15 | @@ -51,7 +51,7 @@ | |||
16 | 51 | :PYTHONPRESENT | 51 | :PYTHONPRESENT |
17 | 52 | ECHO Python found, executing the tests... | 52 | ECHO Python found, executing the tests... |
18 | 53 | :: execute the tests with a number of ignored linux only modules | 53 | :: execute the tests with a number of ignored linux only modules |
20 | 54 | "%PYTHONPATH%\python.exe" "%PYTHONPATH%\Scripts\u1trial" -c ubuntu_sso -i "test_gui.py, test_linux_keyring.py, test_linux_network_state.py" | 54 | "%PYTHONPATH%\python.exe" "%PYTHONPATH%\Scripts\u1trial" -c ubuntu_sso -i "test_gui.py, test_linux.py, test_txsecrets.py" |
21 | 55 | "%PYTHONPATH%\python.exe" "%PYTHONPATH%\Scripts\u1lint" ubuntu_sso | 55 | "%PYTHONPATH%\python.exe" "%PYTHONPATH%\Scripts\u1lint" ubuntu_sso |
22 | 56 | :: test for style if we can, if pep8 is not present, move to the end | 56 | :: test for style if we can, if pep8 is not present, move to the end |
23 | 57 | IF EXIST "%PYTHONPATH%Scripts\pep8.exe" | 57 | IF EXIST "%PYTHONPATH%Scripts\pep8.exe" |
24 | 58 | 58 | ||
25 | === added directory 'ubuntu_sso/main' | |||
26 | === added file 'ubuntu_sso/main/__init__.py' | |||
27 | --- ubuntu_sso/main/__init__.py 1970-01-01 00:00:00 +0000 | |||
28 | +++ ubuntu_sso/main/__init__.py 2011-03-17 08:43:34 +0000 | |||
29 | @@ -0,0 +1,375 @@ | |||
30 | 1 | # -*- coding: utf-8 -*- | ||
31 | 2 | # | ||
32 | 3 | # Author: Natalia Bidart <natalia.bidart@canonical.com> | ||
33 | 4 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
34 | 5 | # Author: Manuel de la Pena <manuel@canonical.com> | ||
35 | 6 | # | ||
36 | 7 | # Copyright 2011 Canonical Ltd. | ||
37 | 8 | # | ||
38 | 9 | # This program is free software: you can redistribute it and/or modify it | ||
39 | 10 | # under the terms of the GNU General Public License version 3, as published | ||
40 | 11 | # by the Free Software Foundation. | ||
41 | 12 | # | ||
42 | 13 | # This program is distributed in the hope that it will be useful, but | ||
43 | 14 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
44 | 15 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
45 | 16 | # PURPOSE. See the GNU General Public License for more details. | ||
46 | 17 | # | ||
47 | 18 | # You should have received a copy of the GNU General Public License along | ||
48 | 19 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
49 | 20 | """Main object implementations.""" | ||
50 | 21 | |||
51 | 22 | import os | ||
52 | 23 | import sys | ||
53 | 24 | import warnings | ||
54 | 25 | |||
55 | 26 | from ubuntu_sso import NO_OP | ||
56 | 27 | from ubuntu_sso.account import Account | ||
57 | 28 | from ubuntu_sso.credentials import (Credentials, HELP_TEXT_KEY, PING_URL_KEY, | ||
58 | 29 | TC_URL_KEY, UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY, | ||
59 | 30 | SUCCESS_CB_KEY, ERROR_CB_KEY, DENIAL_CB_KEY) | ||
60 | 31 | from ubuntu_sso.keyring import get_token_name, U1_APP_NAME, Keyring | ||
61 | 32 | from ubuntu_sso.logger import setup_logging | ||
62 | 33 | |||
63 | 34 | logger = setup_logging("ubuntu_sso.main") | ||
64 | 35 | U1_PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/" | ||
65 | 36 | |||
66 | 37 | |||
67 | 38 | class SSOLoginProcessor(Account): | ||
68 | 39 | """Login and register users using the Ubuntu Single Sign On service. | ||
69 | 40 | |||
70 | 41 | Alias classname to maintain backwards compatibility. DO NOT USE, use | ||
71 | 42 | ubuntu_sso.account.Account instead. | ||
72 | 43 | """ | ||
73 | 44 | |||
74 | 45 | def __init__(self, sso_service_class=None): | ||
75 | 46 | """Create a new SSO Account manager.""" | ||
76 | 47 | msg = 'Use ubuntu_sso.account.Account instead.' | ||
77 | 48 | warnings.warn(msg, DeprecationWarning) | ||
78 | 49 | super(SSOLoginProcessor, self).__init__(sso_service_class) | ||
79 | 50 | |||
80 | 51 | |||
81 | 52 | def except_to_errdict(e): | ||
82 | 53 | """Turn an exception into a dictionary to return thru DBus.""" | ||
83 | 54 | result = { | ||
84 | 55 | "errtype": e.__class__.__name__, | ||
85 | 56 | } | ||
86 | 57 | if len(e.args) == 0: | ||
87 | 58 | result["message"] = e.__class__.__doc__ | ||
88 | 59 | elif isinstance(e.args[0], dict): | ||
89 | 60 | result.update(e.args[0]) | ||
90 | 61 | elif isinstance(e.args[0], basestring): | ||
91 | 62 | result["message"] = e.args[0] | ||
92 | 63 | |||
93 | 64 | return result | ||
94 | 65 | |||
95 | 66 | |||
96 | 67 | class SSOLoginRoot(object): | ||
97 | 68 | """Login thru the Single Sign On service.""" | ||
98 | 69 | |||
99 | 70 | def __init__(self, sso_login_processor_class=Account, | ||
100 | 71 | sso_service_class=None): | ||
101 | 72 | """Initiate the Login object.""" | ||
102 | 73 | self.sso_login_processor_class = sso_login_processor_class | ||
103 | 74 | self.processor = self.sso_login_processor_class( | ||
104 | 75 | sso_service_class=sso_service_class) | ||
105 | 76 | |||
106 | 77 | def generate_captcha(self, app_name, filename, thread_execute, result_cb, | ||
107 | 78 | error_cb): | ||
108 | 79 | """Call the matching method in the processor.""" | ||
109 | 80 | def f(): | ||
110 | 81 | """Inner function that will be run in a thread.""" | ||
111 | 82 | return self.processor.generate_captcha(filename) | ||
112 | 83 | thread_execute(f, app_name, result_cb, error_cb) | ||
113 | 84 | |||
114 | 85 | def register_user(self, app_name, email, password, captcha_id, | ||
115 | 86 | captcha_solution, thread_execute, result_cb, error_cb): | ||
116 | 87 | """Call the matching method in the processor.""" | ||
117 | 88 | def f(): | ||
118 | 89 | """Inner function that will be run in a thread.""" | ||
119 | 90 | return self.processor.register_user(email, password, | ||
120 | 91 | captcha_id, captcha_solution) | ||
121 | 92 | thread_execute(f, app_name, result_cb, error_cb) | ||
122 | 93 | |||
123 | 94 | def login(self, app_name, email, password, thread_execute, result_cb, | ||
124 | 95 | error_cb, not_validated_cb): | ||
125 | 96 | """Call the matching method in the processor.""" | ||
126 | 97 | def f(): | ||
127 | 98 | """Inner function that will be run in a thread.""" | ||
128 | 99 | token_name = get_token_name(app_name) | ||
129 | 100 | logger.debug('login: token_name %r, email %r, password <hidden>.', | ||
130 | 101 | token_name, email) | ||
131 | 102 | credentials = self.processor.login(email, password, token_name) | ||
132 | 103 | logger.debug('login returned not None credentials? %r.', | ||
133 | 104 | credentials is not None) | ||
134 | 105 | return credentials | ||
135 | 106 | |||
136 | 107 | def success_cb(app_name, credentials): | ||
137 | 108 | """Login finished successfull.""" | ||
138 | 109 | is_validated = self.processor.is_validated(credentials) | ||
139 | 110 | logger.debug('user is validated? %r.', is_validated) | ||
140 | 111 | if is_validated: | ||
141 | 112 | # pylint: disable=E1101 | ||
142 | 113 | d = Keyring().set_credentials(app_name, credentials) | ||
143 | 114 | d.addCallback(lambda _: result_cb(app_name, email)) | ||
144 | 115 | d.addErrback(lambda failure: \ | ||
145 | 116 | error_cb(app_name, | ||
146 | 117 | except_to_errdict(failure.value))) | ||
147 | 118 | else: | ||
148 | 119 | not_validated_cb(app_name, email) | ||
149 | 120 | thread_execute(f, app_name, success_cb, error_cb) | ||
150 | 121 | |||
151 | 122 | def validate_email(self, app_name, email, password, email_token, | ||
152 | 123 | thread_execute, result_cb, error_cb): | ||
153 | 124 | """Call the matching method in the processor.""" | ||
154 | 125 | |||
155 | 126 | def f(): | ||
156 | 127 | """Inner function that will be run in a thread.""" | ||
157 | 128 | token_name = get_token_name(app_name) | ||
158 | 129 | credentials = self.processor.validate_email(email, password, | ||
159 | 130 | email_token, token_name) | ||
160 | 131 | return credentials | ||
161 | 132 | |||
162 | 133 | def success_cb(app_name, credentials): | ||
163 | 134 | """Validation finished successfully.""" | ||
164 | 135 | # pylint: disable=E1101 | ||
165 | 136 | d = Keyring().set_credentials(app_name, credentials) | ||
166 | 137 | d.addCallback(lambda _: result_cb(app_name, email)) | ||
167 | 138 | failure_cb = lambda f: error_cb(app_name, f.value) | ||
168 | 139 | d.addErrback(failure_cb) | ||
169 | 140 | |||
170 | 141 | thread_execute(f, app_name, success_cb, error_cb) | ||
171 | 142 | |||
172 | 143 | def request_password_reset_token(self, app_name, email, thread_execute, | ||
173 | 144 | result_cb, error_cb): | ||
174 | 145 | """Call the matching method in the processor.""" | ||
175 | 146 | def f(): | ||
176 | 147 | """Inner function that will be run in a thread.""" | ||
177 | 148 | return self.processor.request_password_reset_token(email) | ||
178 | 149 | thread_execute(f, app_name, result_cb, error_cb) | ||
179 | 150 | |||
180 | 151 | def set_new_password(self, app_name, email, token, new_password, | ||
181 | 152 | thread_execute, result_cb, error_cb): | ||
182 | 153 | """Call the matching method in the processor.""" | ||
183 | 154 | def f(): | ||
184 | 155 | """Inner function that will be run in a thread.""" | ||
185 | 156 | return self.processor.set_new_password(email, token, | ||
186 | 157 | new_password) | ||
187 | 158 | thread_execute(f, app_name, result_cb, error_cb) | ||
188 | 159 | |||
189 | 160 | |||
190 | 161 | class SSOCredentialsRoot(object): | ||
191 | 162 | """Object that gets credentials, and login/registers if needed.""" | ||
192 | 163 | |||
193 | 164 | def __init__(self): | ||
194 | 165 | self.ping_url = os.environ.get('USSOC_PING_URL', U1_PING_URL) | ||
195 | 166 | |||
196 | 167 | def find_credentials(self, app_name, callback=NO_OP, errback=NO_OP): | ||
197 | 168 | """Get the credentials from the keyring or {} if not there.""" | ||
198 | 169 | |||
199 | 170 | def log_result(result): | ||
200 | 171 | """Log the result and continue.""" | ||
201 | 172 | logger.info('find_credentials: app_name "%s", result is {}? %s', | ||
202 | 173 | app_name, result == {}) | ||
203 | 174 | return result | ||
204 | 175 | |||
205 | 176 | d = Credentials(app_name=app_name).find_credentials() | ||
206 | 177 | # pylint: disable=E1101 | ||
207 | 178 | d.addCallback(log_result) | ||
208 | 179 | d.addCallbacks(callback, errback) | ||
209 | 180 | |||
210 | 181 | def login_or_register_to_get_credentials(self, app_name, | ||
211 | 182 | terms_and_conditions_url, | ||
212 | 183 | help_text, window_id, | ||
213 | 184 | success_cb, error_cb, denial_cb): | ||
214 | 185 | """Get credentials if found else prompt GUI to login or register. | ||
215 | 186 | |||
216 | 187 | 'app_name' will be displayed in the GUI. | ||
217 | 188 | 'terms_and_conditions_url' will be the URL pointing to T&C. | ||
218 | 189 | 'help_text' is an explanatory text for the end-users, will be shown | ||
219 | 190 | below the headers. | ||
220 | 191 | 'window_id' is the id of the window which will be set as a parent of | ||
221 | 192 | the GUI. If 0, no parent will be set. | ||
222 | 193 | |||
223 | 194 | """ | ||
224 | 195 | ping_url = self.ping_url if app_name == U1_APP_NAME else None | ||
225 | 196 | obj = Credentials(app_name=app_name, ping_url=ping_url, | ||
226 | 197 | tc_url=terms_and_conditions_url, | ||
227 | 198 | help_text=help_text, window_id=window_id, | ||
228 | 199 | success_cb=success_cb, error_cb=error_cb, | ||
229 | 200 | denial_cb=denial_cb) | ||
230 | 201 | obj.register() | ||
231 | 202 | |||
232 | 203 | def login_to_get_credentials(self, app_name, help_text, window_id, | ||
233 | 204 | success_cb, error_cb, denial_cb): | ||
234 | 205 | """Get credentials if found else prompt GUI just to login | ||
235 | 206 | |||
236 | 207 | 'app_name' will be displayed in the GUI. | ||
237 | 208 | 'help_text' is an explanatory text for the end-users, will be shown | ||
238 | 209 | before the login fields. | ||
239 | 210 | 'window_id' is the id of the window which will be set as a parent of | ||
240 | 211 | the GUI. If 0, no parent will be set. | ||
241 | 212 | |||
242 | 213 | """ | ||
243 | 214 | ping_url = self.ping_url if app_name == U1_APP_NAME else None | ||
244 | 215 | obj = Credentials(app_name=app_name, ping_url=ping_url, tc_url=None, | ||
245 | 216 | help_text=help_text, window_id=window_id, | ||
246 | 217 | success_cb=success_cb, error_cb=error_cb, | ||
247 | 218 | denial_cb=denial_cb) | ||
248 | 219 | obj.login() | ||
249 | 220 | |||
250 | 221 | def clear_token(self, app_name, callback=NO_OP, errback=NO_OP): | ||
251 | 222 | """Clear the token for an application from the keyring. | ||
252 | 223 | |||
253 | 224 | 'app_name' is the name of the application. | ||
254 | 225 | """ | ||
255 | 226 | d = Credentials(app_name=app_name).clear_credentials() | ||
256 | 227 | # pylint: disable=E1101 | ||
257 | 228 | d.addCallbacks(lambda _: callback(), errback) | ||
258 | 229 | |||
259 | 230 | |||
260 | 231 | class CredentialsManagementRoot(object): | ||
261 | 232 | """Object that manages credentials. | ||
262 | 233 | |||
263 | 234 | Every exposed method in this class requires one mandatory argument: | ||
264 | 235 | |||
265 | 236 | - 'app_name': the name of the application. Will be displayed in the | ||
266 | 237 | GUI header, plus it will be used to find/build/clear tokens. | ||
267 | 238 | |||
268 | 239 | And accepts another parameter named 'args', which is a dictionary that | ||
269 | 240 | can contain the following: | ||
270 | 241 | |||
271 | 242 | - 'help_text': an explanatory text for the end-users, will be | ||
272 | 243 | shown below the header. This is an optional free text field. | ||
273 | 244 | |||
274 | 245 | - 'ping_url': the url to open after successful token retrieval. If | ||
275 | 246 | defined, the email will be attached to the url and will be pinged | ||
276 | 247 | with a OAuth-signed request. | ||
277 | 248 | |||
278 | 249 | - 'tc_url': the link to the Terms and Conditions page. If defined, | ||
279 | 250 | the checkbox to agree to the terms will link to it. | ||
280 | 251 | |||
281 | 252 | - 'window_id': the id of the window which will be set as a parent | ||
282 | 253 | of the GUI. If not defined, no parent will be set. | ||
283 | 254 | |||
284 | 255 | """ | ||
285 | 256 | |||
286 | 257 | def __init__(self, found_cb, error_cb, denied_cb, *args, **kwargs): | ||
287 | 258 | """Create a new instance. | ||
288 | 259 | |||
289 | 260 | - 'found_cb' is a callback that will be executed when the credentials | ||
290 | 261 | were found. | ||
291 | 262 | |||
292 | 263 | - 'error_cb' is a callback that will be executed when there was an | ||
293 | 264 | error getting the credentials. | ||
294 | 265 | |||
295 | 266 | - 'denied_cb' is a callback that will be executed when the user denied | ||
296 | 267 | the use of the crendetials. | ||
297 | 268 | |||
298 | 269 | """ | ||
299 | 270 | super(CredentialsManagementRoot, self).__init__(*args, **kwargs) | ||
300 | 271 | self.found_cb = found_cb | ||
301 | 272 | self.error_cb = error_cb | ||
302 | 273 | self.denied_cb = denied_cb | ||
303 | 274 | |||
304 | 275 | valid_keys = (HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY, | ||
305 | 276 | UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY) | ||
306 | 277 | |||
307 | 278 | def _parse_args(self, args): | ||
308 | 279 | """Retrieve values from the generic param 'args'.""" | ||
309 | 280 | result = dict(i for i in args.iteritems() if i[0] in self.valid_keys) | ||
310 | 281 | result[WINDOW_ID_KEY] = int(args.get(WINDOW_ID_KEY, 0)) | ||
311 | 282 | result[SUCCESS_CB_KEY] = self.found_cb | ||
312 | 283 | result[ERROR_CB_KEY] = self.error_cb | ||
313 | 284 | result[DENIAL_CB_KEY] = self.denied_cb | ||
314 | 285 | return result | ||
315 | 286 | |||
316 | 287 | def find_credentials(self, app_name, args, success_cb, error_cb): | ||
317 | 288 | """Look for the credentials for an application. | ||
318 | 289 | |||
319 | 290 | - 'app_name': the name of the application which credentials are | ||
320 | 291 | going to be removed. | ||
321 | 292 | |||
322 | 293 | - 'args' is a dictionary, currently not used. | ||
323 | 294 | |||
324 | 295 | - 'success_cb' is a callback that will be execute if the operation was | ||
325 | 296 | a success. | ||
326 | 297 | |||
327 | 298 | - 'error_cb' is a callback that will be executed if the operation had | ||
328 | 299 | an error. | ||
329 | 300 | |||
330 | 301 | """ | ||
331 | 302 | |||
332 | 303 | obj = Credentials(app_name) | ||
333 | 304 | d = obj.find_credentials() | ||
334 | 305 | # pylint: disable=E1101 | ||
335 | 306 | d.addCallback(success_cb) | ||
336 | 307 | d.addErrback(error_cb, app_name) | ||
337 | 308 | |||
338 | 309 | def clear_credentials(self, app_name, args, success_cb, error_cb): | ||
339 | 310 | """Clear the credentials for an application. | ||
340 | 311 | |||
341 | 312 | - 'app_name': the name of the application which credentials are | ||
342 | 313 | going to be removed. | ||
343 | 314 | |||
344 | 315 | - 'args' is a dictionary, currently not used. | ||
345 | 316 | |||
346 | 317 | - 'success_cb' is a callback that will be execute if the operation was | ||
347 | 318 | a success. | ||
348 | 319 | |||
349 | 320 | - 'error_cb' is a callback that will be executed if the operation had | ||
350 | 321 | an error. | ||
351 | 322 | |||
352 | 323 | """ | ||
353 | 324 | |||
354 | 325 | obj = Credentials(app_name) | ||
355 | 326 | d = obj.clear_credentials() | ||
356 | 327 | # pylint: disable=E1101 | ||
357 | 328 | d.addCallback(success_cb) | ||
358 | 329 | d.addErrback(error_cb, app_name) | ||
359 | 330 | |||
360 | 331 | def store_credentials(self, app_name, args, success_cb, error_cb): | ||
361 | 332 | """Store the token for an application. | ||
362 | 333 | |||
363 | 334 | - 'app_name': the name of the application which credentials are | ||
364 | 335 | going to be stored. | ||
365 | 336 | |||
366 | 337 | - 'args' is the dictionary holding the credentials. Needs to provide | ||
367 | 338 | the following mandatory keys: 'token', 'token_key', 'consumer_key', | ||
368 | 339 | 'consumer_secret'. | ||
369 | 340 | |||
370 | 341 | - 'success_cb' is a callback that will be execute if the operation was | ||
371 | 342 | a success. | ||
372 | 343 | |||
373 | 344 | - 'error_cb' is a callback that will be executed if the operation had | ||
374 | 345 | an error. | ||
375 | 346 | """ | ||
376 | 347 | |||
377 | 348 | obj = Credentials(app_name) | ||
378 | 349 | d = obj.store_credentials(args) | ||
379 | 350 | # pylint: disable=E1101 | ||
380 | 351 | d.addCallback(success_cb) | ||
381 | 352 | d.addErrback(error_cb, app_name) | ||
382 | 353 | |||
383 | 354 | def register(self, app_name, args): | ||
384 | 355 | """Get credentials if found else prompt GUI to register.""" | ||
385 | 356 | obj = Credentials(app_name, **self._parse_args(args)) | ||
386 | 357 | obj.register() | ||
387 | 358 | |||
388 | 359 | def login(self, app_name, args): | ||
389 | 360 | """Get credentials if found else prompt GUI to login.""" | ||
390 | 361 | obj = Credentials(app_name, **self._parse_args(args)) | ||
391 | 362 | obj.login() | ||
392 | 363 | |||
393 | 364 | # pylint: disable=C0103 | ||
394 | 365 | SSOLogin = None | ||
395 | 366 | SSOCredentials = None | ||
396 | 367 | CredentialsManagement = None | ||
397 | 368 | |||
398 | 369 | if sys.platform == 'win32': | ||
399 | 370 | pass | ||
400 | 371 | else: | ||
401 | 372 | from ubuntu_sso.main import linux | ||
402 | 373 | SSOLogin = linux.SSOLogin | ||
403 | 374 | SSOCredentials = linux.SSOCredentials | ||
404 | 375 | CredentialsManagement = linux.CredentialsManagement | ||
405 | 0 | 376 | ||
406 | === renamed file 'ubuntu_sso/main.py' => 'ubuntu_sso/main/linux.py' | |||
407 | --- ubuntu_sso/main.py 2011-01-28 13:45:09 +0000 | |||
408 | +++ ubuntu_sso/main/linux.py 2011-03-17 08:43:34 +0000 | |||
409 | @@ -27,21 +27,17 @@ | |||
410 | 27 | 27 | ||
411 | 28 | """ | 28 | """ |
412 | 29 | 29 | ||
413 | 30 | import os | ||
414 | 31 | import threading | 30 | import threading |
415 | 32 | import warnings | ||
416 | 33 | 31 | ||
417 | 34 | import dbus.service | 32 | import dbus.service |
418 | 35 | 33 | ||
419 | 36 | from ubuntu_sso import (DBUS_ACCOUNT_PATH, DBUS_IFACE_USER_NAME, | 34 | from ubuntu_sso import (DBUS_ACCOUNT_PATH, DBUS_IFACE_USER_NAME, |
420 | 37 | DBUS_IFACE_CRED_NAME, DBUS_CREDENTIALS_IFACE, NO_OP) | 35 | DBUS_IFACE_CRED_NAME, DBUS_CREDENTIALS_IFACE, NO_OP) |
421 | 38 | from ubuntu_sso.account import Account | 36 | from ubuntu_sso.account import Account |
427 | 39 | from ubuntu_sso.credentials import (Credentials, HELP_TEXT_KEY, PING_URL_KEY, | 37 | from ubuntu_sso.credentials import ERROR_KEY, ERROR_DETAIL_KEY |
423 | 40 | TC_URL_KEY, UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY, | ||
424 | 41 | SUCCESS_CB_KEY, ERROR_CB_KEY, DENIAL_CB_KEY, | ||
425 | 42 | ERROR_KEY, ERROR_DETAIL_KEY) | ||
426 | 43 | from ubuntu_sso.keyring import get_token_name, U1_APP_NAME, Keyring | ||
428 | 44 | from ubuntu_sso.logger import setup_logging | 38 | from ubuntu_sso.logger import setup_logging |
429 | 39 | from ubuntu_sso.main import (CredentialsManagementRoot, SSOLoginRoot, | ||
430 | 40 | SSOCredentialsRoot, except_to_errdict) | ||
431 | 45 | 41 | ||
432 | 46 | 42 | ||
433 | 47 | # Disable the invalid name warning, as we have a lot of DBus style names | 43 | # Disable the invalid name warning, as we have a lot of DBus style names |
434 | @@ -49,39 +45,9 @@ | |||
435 | 49 | 45 | ||
436 | 50 | 46 | ||
437 | 51 | logger = setup_logging("ubuntu_sso.main") | 47 | logger = setup_logging("ubuntu_sso.main") |
438 | 52 | U1_PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/" | ||
439 | 53 | TIMEOUT_INTERVAL = 10000 # 10 seconds | 48 | TIMEOUT_INTERVAL = 10000 # 10 seconds |
440 | 54 | 49 | ||
441 | 55 | 50 | ||
442 | 56 | class SSOLoginProcessor(Account): | ||
443 | 57 | """Login and register users using the Ubuntu Single Sign On service. | ||
444 | 58 | |||
445 | 59 | Alias classname to maintain backwards compatibility. DO NOT USE, use | ||
446 | 60 | ubuntu_sso.account.Account instead. | ||
447 | 61 | """ | ||
448 | 62 | |||
449 | 63 | def __init__(self, sso_service_class=None): | ||
450 | 64 | """Create a new SSO Account manager.""" | ||
451 | 65 | msg = 'Use ubuntu_sso.account.Account instead.' | ||
452 | 66 | warnings.warn(msg, DeprecationWarning) | ||
453 | 67 | super(SSOLoginProcessor, self).__init__(sso_service_class) | ||
454 | 68 | |||
455 | 69 | |||
456 | 70 | def except_to_errdict(e): | ||
457 | 71 | """Turn an exception into a dictionary to return thru DBus.""" | ||
458 | 72 | result = { | ||
459 | 73 | "errtype": e.__class__.__name__, | ||
460 | 74 | } | ||
461 | 75 | if len(e.args) == 0: | ||
462 | 76 | result["message"] = e.__class__.__doc__ | ||
463 | 77 | elif isinstance(e.args[0], dict): | ||
464 | 78 | result.update(e.args[0]) | ||
465 | 79 | elif isinstance(e.args[0], basestring): | ||
466 | 80 | result["message"] = e.args[0] | ||
467 | 81 | |||
468 | 82 | return result | ||
469 | 83 | |||
470 | 84 | |||
471 | 85 | def blocking(f, app_name, result_cb, error_cb): | 51 | def blocking(f, app_name, result_cb, error_cb): |
472 | 86 | """Run f in a thread; return or throw an exception thru the callbacks.""" | 52 | """Run f in a thread; return or throw an exception thru the callbacks.""" |
473 | 87 | def _in_thread(): | 53 | def _in_thread(): |
474 | @@ -107,9 +73,7 @@ | |||
475 | 107 | """Initiate the Login object.""" | 73 | """Initiate the Login object.""" |
476 | 108 | dbus.service.Object.__init__(self, object_path=object_path, | 74 | dbus.service.Object.__init__(self, object_path=object_path, |
477 | 109 | bus_name=bus_name) | 75 | bus_name=bus_name) |
481 | 110 | self.sso_login_processor_class = sso_login_processor_class | 76 | self.root = SSOLoginRoot(sso_login_processor_class, sso_service_class) |
479 | 111 | self.processor = self.sso_login_processor_class( | ||
480 | 112 | sso_service_class=sso_service_class) | ||
482 | 113 | 77 | ||
483 | 114 | # generate_capcha signals | 78 | # generate_capcha signals |
484 | 115 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") | 79 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") |
485 | @@ -128,11 +92,9 @@ | |||
486 | 128 | in_signature='ss') | 92 | in_signature='ss') |
487 | 129 | def generate_captcha(self, app_name, filename): | 93 | def generate_captcha(self, app_name, filename): |
488 | 130 | """Call the matching method in the processor.""" | 94 | """Call the matching method in the processor.""" |
494 | 131 | def f(): | 95 | self.root.generate_captcha(app_name, filename, blocking, |
495 | 132 | """Inner function that will be run in a thread.""" | 96 | self.CaptchaGenerated, |
496 | 133 | return self.processor.generate_captcha(filename) | 97 | self.CaptchaGenerationError) |
492 | 134 | blocking(f, app_name, self.CaptchaGenerated, | ||
493 | 135 | self.CaptchaGenerationError) | ||
497 | 136 | 98 | ||
498 | 137 | # register_user signals | 99 | # register_user signals |
499 | 138 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") | 100 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") |
500 | @@ -152,11 +114,10 @@ | |||
501 | 152 | def register_user(self, app_name, email, password, | 114 | def register_user(self, app_name, email, password, |
502 | 153 | captcha_id, captcha_solution): | 115 | captcha_id, captcha_solution): |
503 | 154 | """Call the matching method in the processor.""" | 116 | """Call the matching method in the processor.""" |
509 | 155 | def f(): | 117 | self.root.register_user(app_name, email, password, captcha_id, |
510 | 156 | """Inner function that will be run in a thread.""" | 118 | captcha_solution, blocking, |
511 | 157 | return self.processor.register_user(email, password, | 119 | self.UserRegistered, |
512 | 158 | captcha_id, captcha_solution) | 120 | self.UserRegistrationError) |
508 | 159 | blocking(f, app_name, self.UserRegistered, self.UserRegistrationError) | ||
513 | 160 | 121 | ||
514 | 161 | # login signals | 122 | # login signals |
515 | 162 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") | 123 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") |
516 | @@ -181,30 +142,8 @@ | |||
517 | 181 | in_signature='sss') | 142 | in_signature='sss') |
518 | 182 | def login(self, app_name, email, password): | 143 | def login(self, app_name, email, password): |
519 | 183 | """Call the matching method in the processor.""" | 144 | """Call the matching method in the processor.""" |
544 | 184 | def f(): | 145 | self.root.login(app_name, email, password, blocking, self.LoggedIn, |
545 | 185 | """Inner function that will be run in a thread.""" | 146 | self.LoginError, self.UserNotValidated) |
522 | 186 | token_name = get_token_name(app_name) | ||
523 | 187 | logger.debug('login: token_name %r, email %r, password <hidden>.', | ||
524 | 188 | token_name, email) | ||
525 | 189 | credentials = self.processor.login(email, password, token_name) | ||
526 | 190 | logger.debug('login returned not None credentials? %r.', | ||
527 | 191 | credentials is not None) | ||
528 | 192 | return credentials | ||
529 | 193 | |||
530 | 194 | def success_cb(app_name, credentials): | ||
531 | 195 | """Login finished successfull.""" | ||
532 | 196 | is_validated = self.processor.is_validated(credentials) | ||
533 | 197 | logger.debug('user is validated? %r.', is_validated) | ||
534 | 198 | if is_validated: | ||
535 | 199 | # pylint: disable=E1101 | ||
536 | 200 | d = Keyring().set_credentials(app_name, credentials) | ||
537 | 201 | d.addCallback(lambda _: self.LoggedIn(app_name, email)) | ||
538 | 202 | d.addErrback(lambda failure: \ | ||
539 | 203 | self.LoginError(app_name, | ||
540 | 204 | except_to_errdict(failure.value))) | ||
541 | 205 | else: | ||
542 | 206 | self.UserNotValidated(app_name, email) | ||
543 | 207 | blocking(f, app_name, success_cb, self.LoginError) | ||
546 | 208 | 147 | ||
547 | 209 | # validate_email signals | 148 | # validate_email signals |
548 | 210 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") | 149 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") |
549 | @@ -223,23 +162,9 @@ | |||
550 | 223 | in_signature='ssss') | 162 | in_signature='ssss') |
551 | 224 | def validate_email(self, app_name, email, password, email_token): | 163 | def validate_email(self, app_name, email, password, email_token): |
552 | 225 | """Call the matching method in the processor.""" | 164 | """Call the matching method in the processor.""" |
570 | 226 | 165 | self.root.validate_email(app_name, email, password, email_token, | |
571 | 227 | def f(): | 166 | blocking, self.EmailValidated, |
572 | 228 | """Inner function that will be run in a thread.""" | 167 | self.EmailValidationError) |
556 | 229 | token_name = get_token_name(app_name) | ||
557 | 230 | credentials = self.processor.validate_email(email, password, | ||
558 | 231 | email_token, token_name) | ||
559 | 232 | return credentials | ||
560 | 233 | |||
561 | 234 | def success_cb(app_name, credentials): | ||
562 | 235 | """Validation finished successfully.""" | ||
563 | 236 | # pylint: disable=E1101 | ||
564 | 237 | d = Keyring().set_credentials(app_name, credentials) | ||
565 | 238 | d.addCallback(lambda _: self.EmailValidated(app_name, email)) | ||
566 | 239 | failure_cb = lambda f: self.EmailValidationError(app_name, f.value) | ||
567 | 240 | d.addErrback(failure_cb) | ||
568 | 241 | |||
569 | 242 | blocking(f, app_name, success_cb, self.EmailValidationError) | ||
573 | 243 | 168 | ||
574 | 244 | # request_password_reset_token signals | 169 | # request_password_reset_token signals |
575 | 245 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") | 170 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") |
576 | @@ -258,11 +183,9 @@ | |||
577 | 258 | in_signature='ss') | 183 | in_signature='ss') |
578 | 259 | def request_password_reset_token(self, app_name, email): | 184 | def request_password_reset_token(self, app_name, email): |
579 | 260 | """Call the matching method in the processor.""" | 185 | """Call the matching method in the processor.""" |
585 | 261 | def f(): | 186 | self.root.request_password_reset_token(app_name, email, blocking, |
586 | 262 | """Inner function that will be run in a thread.""" | 187 | self.PasswordResetTokenSent, |
587 | 263 | return self.processor.request_password_reset_token(email) | 188 | self.PasswordResetError) |
583 | 264 | blocking(f, app_name, self.PasswordResetTokenSent, | ||
584 | 265 | self.PasswordResetError) | ||
588 | 266 | 189 | ||
589 | 267 | # set_new_password signals | 190 | # set_new_password signals |
590 | 268 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") | 191 | @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss") |
591 | @@ -281,11 +204,9 @@ | |||
592 | 281 | in_signature='ssss') | 204 | in_signature='ssss') |
593 | 282 | def set_new_password(self, app_name, email, token, new_password): | 205 | def set_new_password(self, app_name, email, token, new_password): |
594 | 283 | """Call the matching method in the processor.""" | 206 | """Call the matching method in the processor.""" |
600 | 284 | def f(): | 207 | self.root.set_new_password(app_name, email, token, new_password, |
601 | 285 | """Inner function that will be run in a thread.""" | 208 | blocking, self.PasswordChanged, |
602 | 286 | return self.processor.set_new_password(email, token, | 209 | self.PasswordChangeError) |
598 | 287 | new_password) | ||
599 | 288 | blocking(f, app_name, self.PasswordChanged, self.PasswordChangeError) | ||
603 | 289 | 210 | ||
604 | 290 | 211 | ||
605 | 291 | class SSOCredentials(dbus.service.Object): | 212 | class SSOCredentials(dbus.service.Object): |
606 | @@ -296,7 +217,7 @@ | |||
607 | 296 | 217 | ||
608 | 297 | def __init__(self, *args, **kwargs): | 218 | def __init__(self, *args, **kwargs): |
609 | 298 | dbus.service.Object.__init__(self, *args, **kwargs) | 219 | dbus.service.Object.__init__(self, *args, **kwargs) |
611 | 299 | self.ping_url = os.environ.get('USSOC_PING_URL', U1_PING_URL) | 220 | self.root = SSOCredentialsRoot() |
612 | 300 | 221 | ||
613 | 301 | def _process_error(self, app_name, error_dict): | 222 | def _process_error(self, app_name, error_dict): |
614 | 302 | """Process the 'error_dict' and emit CredentialsError.""" | 223 | """Process the 'error_dict' and emit CredentialsError.""" |
615 | @@ -327,17 +248,7 @@ | |||
616 | 327 | async_callbacks=("callback", "errback")) | 248 | async_callbacks=("callback", "errback")) |
617 | 328 | def find_credentials(self, app_name, callback=NO_OP, errback=NO_OP): | 249 | def find_credentials(self, app_name, callback=NO_OP, errback=NO_OP): |
618 | 329 | """Get the credentials from the keyring or {} if not there.""" | 250 | """Get the credentials from the keyring or {} if not there.""" |
630 | 330 | 251 | self.root.find_credentials(app_name, callback, errback) | |
620 | 331 | def log_result(result): | ||
621 | 332 | """Log the result and continue.""" | ||
622 | 333 | logger.info('find_credentials: app_name "%s", result is {}? %s', | ||
623 | 334 | app_name, result == {}) | ||
624 | 335 | return result | ||
625 | 336 | |||
626 | 337 | d = Credentials(app_name=app_name).find_credentials() | ||
627 | 338 | # pylint: disable=E1101 | ||
628 | 339 | d.addCallback(log_result) | ||
629 | 340 | d.addCallbacks(callback, errback) | ||
631 | 341 | 252 | ||
632 | 342 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, | 253 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, |
633 | 343 | in_signature="sssx", out_signature="") | 254 | in_signature="sssx", out_signature="") |
634 | @@ -354,14 +265,12 @@ | |||
635 | 354 | the GUI. If 0, no parent will be set. | 265 | the GUI. If 0, no parent will be set. |
636 | 355 | 266 | ||
637 | 356 | """ | 267 | """ |
646 | 357 | ping_url = self.ping_url if app_name == U1_APP_NAME else None | 268 | self.root.login_or_register_to_get_credentials(app_name, |
647 | 358 | obj = Credentials(app_name=app_name, ping_url=ping_url, | 269 | terms_and_conditions_url, |
648 | 359 | tc_url=terms_and_conditions_url, | 270 | help_text, window_id, |
649 | 360 | help_text=help_text, window_id=window_id, | 271 | self.CredentialsFound, |
650 | 361 | success_cb=self.CredentialsFound, | 272 | self._process_error, |
651 | 362 | error_cb=self._process_error, | 273 | self.AuthorizationDenied) |
644 | 363 | denial_cb=self.AuthorizationDenied) | ||
645 | 364 | obj.register() | ||
652 | 365 | 274 | ||
653 | 366 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, | 275 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, |
654 | 367 | in_signature="ssx", out_signature="") | 276 | in_signature="ssx", out_signature="") |
655 | @@ -375,13 +284,10 @@ | |||
656 | 375 | the GUI. If 0, no parent will be set. | 284 | the GUI. If 0, no parent will be set. |
657 | 376 | 285 | ||
658 | 377 | """ | 286 | """ |
666 | 378 | ping_url = self.ping_url if app_name == U1_APP_NAME else None | 287 | self.root.login_to_get_credentials(app_name, help_text, window_id, |
667 | 379 | obj = Credentials(app_name=app_name, ping_url=ping_url, tc_url=None, | 288 | self.CredentialsFound, |
668 | 380 | help_text=help_text, window_id=window_id, | 289 | self._process_error, |
669 | 381 | success_cb=self.CredentialsFound, | 290 | self.AuthorizationDenied) |
663 | 382 | error_cb=self._process_error, | ||
664 | 383 | denial_cb=self.AuthorizationDenied) | ||
665 | 384 | obj.login() | ||
670 | 385 | 291 | ||
671 | 386 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, | 292 | @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME, |
672 | 387 | in_signature='s', out_signature='', | 293 | in_signature='s', out_signature='', |
673 | @@ -391,9 +297,7 @@ | |||
674 | 391 | 297 | ||
675 | 392 | 'app_name' is the name of the application. | 298 | 'app_name' is the name of the application. |
676 | 393 | """ | 299 | """ |
680 | 394 | d = Credentials(app_name=app_name).clear_credentials() | 300 | self.root.clear_token(app_name, callback, errback) |
678 | 395 | # pylint: disable=E1101 | ||
679 | 396 | d.addCallbacks(lambda _: callback(), errback) | ||
681 | 397 | 301 | ||
682 | 398 | 302 | ||
683 | 399 | class CredentialsManagement(dbus.service.Object): | 303 | class CredentialsManagement(dbus.service.Object): |
684 | @@ -427,22 +331,13 @@ | |||
685 | 427 | self._ref_count = 0 | 331 | self._ref_count = 0 |
686 | 428 | self.timeout_func = timeout_func | 332 | self.timeout_func = timeout_func |
687 | 429 | self.shutdown_func = shutdown_func | 333 | self.shutdown_func = shutdown_func |
688 | 334 | self.root = CredentialsManagementRoot(self.CredentialsFound, | ||
689 | 335 | self.CredentialsError, | ||
690 | 336 | self.AuthorizationDenied) | ||
691 | 430 | 337 | ||
692 | 431 | # Operator not preceded by a space (fails with dbus decorators) | 338 | # Operator not preceded by a space (fails with dbus decorators) |
693 | 432 | # pylint: disable=C0322 | 339 | # pylint: disable=C0322 |
694 | 433 | 340 | ||
695 | 434 | valid_keys = (HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY, | ||
696 | 435 | UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY) | ||
697 | 436 | |||
698 | 437 | def _parse_args(self, args): | ||
699 | 438 | """Retrieve values from the generic param 'args'.""" | ||
700 | 439 | result = dict(i for i in args.iteritems() if i[0] in self.valid_keys) | ||
701 | 440 | result[WINDOW_ID_KEY] = int(args.get(WINDOW_ID_KEY, 0)) | ||
702 | 441 | result[SUCCESS_CB_KEY] = self.CredentialsFound | ||
703 | 442 | result[ERROR_CB_KEY] = self.CredentialsError | ||
704 | 443 | result[DENIAL_CB_KEY] = self.AuthorizationDenied | ||
705 | 444 | return result | ||
706 | 445 | |||
707 | 446 | def _process_failure(self, failure, app_name): | 341 | def _process_failure(self, failure, app_name): |
708 | 447 | """Process the 'failure' and emit CredentialsError.""" | 342 | """Process the 'failure' and emit CredentialsError.""" |
709 | 448 | self.CredentialsError(app_name, except_to_errdict(failure.value)) | 343 | self.CredentialsError(app_name, except_to_errdict(failure.value)) |
710 | @@ -539,11 +434,8 @@ | |||
711 | 539 | else: | 434 | else: |
712 | 540 | self.CredentialsNotFound(app_name) | 435 | self.CredentialsNotFound(app_name) |
713 | 541 | 436 | ||
719 | 542 | obj = Credentials(app_name) | 437 | self.root.find_credentials(app_name, args, success_cb, |
720 | 543 | d = obj.find_credentials() | 438 | self._process_failure) |
716 | 544 | # pylint: disable=E1101 | ||
717 | 545 | d.addCallback(success_cb) | ||
718 | 546 | d.addErrback(self._process_failure, app_name) | ||
721 | 547 | 439 | ||
722 | 548 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, | 440 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, |
723 | 549 | in_signature='sa{ss}', out_signature='') | 441 | in_signature='sa{ss}', out_signature='') |
724 | @@ -557,12 +449,9 @@ | |||
725 | 557 | 449 | ||
726 | 558 | """ | 450 | """ |
727 | 559 | self.ref_count += 1 | 451 | self.ref_count += 1 |
734 | 560 | 452 | self.root.clear_credentials(app_name, args, | |
735 | 561 | obj = Credentials(app_name) | 453 | lambda _: self.CredentialsCleared(app_name), |
736 | 562 | d = obj.clear_credentials() | 454 | self._process_failure) |
731 | 563 | # pylint: disable=E1101 | ||
732 | 564 | d.addCallback(lambda _: self.CredentialsCleared(app_name)) | ||
733 | 565 | d.addErrback(self._process_failure, app_name) | ||
737 | 566 | 455 | ||
738 | 567 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, | 456 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, |
739 | 568 | in_signature='sa{ss}', out_signature='') | 457 | in_signature='sa{ss}', out_signature='') |
740 | @@ -578,27 +467,20 @@ | |||
741 | 578 | 467 | ||
742 | 579 | """ | 468 | """ |
743 | 580 | self.ref_count += 1 | 469 | self.ref_count += 1 |
750 | 581 | 470 | self.root.store_credentials(app_name, args, | |
751 | 582 | obj = Credentials(app_name) | 471 | lambda _: self.CredentialsStored(app_name), |
752 | 583 | d = obj.store_credentials(args) | 472 | self._process_failure) |
747 | 584 | # pylint: disable=E1101 | ||
748 | 585 | d.addCallback(lambda _: self.CredentialsStored(app_name)) | ||
749 | 586 | d.addErrback(self._process_failure, app_name) | ||
753 | 587 | 473 | ||
754 | 588 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, | 474 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, |
755 | 589 | in_signature='sa{ss}', out_signature='') | 475 | in_signature='sa{ss}', out_signature='') |
756 | 590 | def register(self, app_name, args): | 476 | def register(self, app_name, args): |
757 | 591 | """Get credentials if found else prompt GUI to register.""" | 477 | """Get credentials if found else prompt GUI to register.""" |
758 | 592 | self.ref_count += 1 | 478 | self.ref_count += 1 |
762 | 593 | 479 | self.root.register(app_name, args) | |
760 | 594 | obj = Credentials(app_name, **self._parse_args(args)) | ||
761 | 595 | obj.register() | ||
763 | 596 | 480 | ||
764 | 597 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, | 481 | @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE, |
765 | 598 | in_signature='sa{ss}', out_signature='') | 482 | in_signature='sa{ss}', out_signature='') |
766 | 599 | def login(self, app_name, args): | 483 | def login(self, app_name, args): |
767 | 600 | """Get credentials if found else prompt GUI to login.""" | 484 | """Get credentials if found else prompt GUI to login.""" |
768 | 601 | self.ref_count += 1 | 485 | self.ref_count += 1 |
772 | 602 | 486 | self.root.login(app_name, args) | |
770 | 603 | obj = Credentials(app_name, **self._parse_args(args)) | ||
771 | 604 | obj.login() | ||
773 | 605 | 487 | ||
774 | === added file 'ubuntu_sso/main/windows.py' | |||
775 | --- ubuntu_sso/main/windows.py 1970-01-01 00:00:00 +0000 | |||
776 | +++ ubuntu_sso/main/windows.py 2011-03-17 08:43:34 +0000 | |||
777 | @@ -0,0 +1,17 @@ | |||
778 | 1 | # -*- coding: utf-8 -*- | ||
779 | 2 | # Author: Manuel de la Pena <manuel@canonical.com> | ||
780 | 3 | # | ||
781 | 4 | # Copyright 2011 Canonical Ltd. | ||
782 | 5 | # | ||
783 | 6 | # This program is free software: you can redistribute it and/or modify it | ||
784 | 7 | # under the terms of the GNU General Public License version 3, as published | ||
785 | 8 | # by the Free Software Foundation. | ||
786 | 9 | # | ||
787 | 10 | # This program is distributed in the hope that it will be useful, but | ||
788 | 11 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
789 | 12 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
790 | 13 | # PURPOSE. See the GNU General Public License for more details. | ||
791 | 14 | # | ||
792 | 15 | # You should have received a copy of the GNU General Public License along | ||
793 | 16 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
794 | 17 | """Main implementation on windows.""" | ||
795 | 0 | 18 | ||
796 | === renamed file 'ubuntu_sso/tests/keyring/test_linux_keyring.py' => 'ubuntu_sso/tests/keyring/test_linux.py' | |||
797 | === renamed file 'ubuntu_sso/tests/keyring/test_windows_keyring.py' => 'ubuntu_sso/tests/keyring/test_windows.py' | |||
798 | === added directory 'ubuntu_sso/tests/main' | |||
799 | === added file 'ubuntu_sso/tests/main/__init__.py' | |||
800 | --- ubuntu_sso/tests/main/__init__.py 1970-01-01 00:00:00 +0000 | |||
801 | +++ ubuntu_sso/tests/main/__init__.py 2011-03-17 08:43:34 +0000 | |||
802 | @@ -0,0 +1,17 @@ | |||
803 | 1 | # -*- coding: utf-8 -*- | ||
804 | 2 | # Author: Manuel de la Pena <manuel@canonical.com> | ||
805 | 3 | # | ||
806 | 4 | # Copyright 2011 Canonical Ltd. | ||
807 | 5 | # | ||
808 | 6 | # This program is free software: you can redistribute it and/or modify it | ||
809 | 7 | # under the terms of the GNU General Public License version 3, as published | ||
810 | 8 | # by the Free Software Foundation. | ||
811 | 9 | # | ||
812 | 10 | # This program is distributed in the hope that it will be useful, but | ||
813 | 11 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
814 | 12 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
815 | 13 | # PURPOSE. See the GNU General Public License for more details. | ||
816 | 14 | # | ||
817 | 15 | # You should have received a copy of the GNU General Public License along | ||
818 | 16 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
819 | 17 | """Test the different main implementations.""" | ||
820 | 0 | 18 | ||
821 | === added file 'ubuntu_sso/tests/main/test_common.py' | |||
822 | --- ubuntu_sso/tests/main/test_common.py 1970-01-01 00:00:00 +0000 | |||
823 | +++ ubuntu_sso/tests/main/test_common.py 2011-03-17 08:43:34 +0000 | |||
824 | @@ -0,0 +1,244 @@ | |||
825 | 1 | # -*- coding: utf-8 -*- | ||
826 | 2 | # | ||
827 | 3 | # test_main - tests for ubuntu_sso.main | ||
828 | 4 | # | ||
829 | 5 | # Author: Natalia Bidart <natalia.bidart@canonical.com> | ||
830 | 6 | # Author: Alejandro J. Cura <alecu@canonical.com> | ||
831 | 7 | # Author: Manuel de la Pena <manuel@canonical.com> | ||
832 | 8 | # | ||
833 | 9 | # Copyright 2009-2010 Canonical Ltd. | ||
834 | 10 | # | ||
835 | 11 | # This program is free software: you can redistribute it and/or modify it | ||
836 | 12 | # under the terms of the GNU General Public License version 3, as published | ||
837 | 13 | # by the Free Software Foundation. | ||
838 | 14 | # | ||
839 | 15 | # This program is distributed in the hope that it will be useful, but | ||
840 | 16 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
841 | 17 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
842 | 18 | # PURPOSE. See the GNU General Public License for more details. | ||
843 | 19 | # | ||
844 | 20 | # You should have received a copy of the GNU General Public License along | ||
845 | 21 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
846 | 22 | """Tests share by diff platforms.""" | ||
847 | 23 | |||
848 | 24 | import os | ||
849 | 25 | |||
850 | 26 | from unittest import TestCase | ||
851 | 27 | from mocker import MockerTestCase, MATCH | ||
852 | 28 | from ubuntu_sso.main import ( | ||
853 | 29 | CredentialsManagement, | ||
854 | 30 | SSOCredentialsRoot, | ||
855 | 31 | SSOCredentials, | ||
856 | 32 | SSOLogin, | ||
857 | 33 | U1_PING_URL) | ||
858 | 34 | |||
859 | 35 | |||
860 | 36 | class EnvironOverridesTestCase(TestCase): | ||
861 | 37 | """Some URLs can be set from the environment for testing/QA purposes.""" | ||
862 | 38 | |||
863 | 39 | def test_override_ping_url(self): | ||
864 | 40 | """The ping url can be set from the environ via USSOC_PING_URL.""" | ||
865 | 41 | fake_url = 'this is not really a URL' | ||
866 | 42 | old_url = os.environ.get('USSOC_PING_URL') | ||
867 | 43 | os.environ['USSOC_PING_URL'] = fake_url | ||
868 | 44 | try: | ||
869 | 45 | creds = SSOCredentialsRoot() | ||
870 | 46 | self.assertEqual(creds.ping_url, fake_url) | ||
871 | 47 | finally: | ||
872 | 48 | if old_url: | ||
873 | 49 | os.environ['USSOC_PING_URL'] = old_url | ||
874 | 50 | else: | ||
875 | 51 | del os.environ['USSOC_PING_URL'] | ||
876 | 52 | |||
877 | 53 | def test_no_override_ping_url(self): | ||
878 | 54 | """If the environ is unset, the default ping url is used.""" | ||
879 | 55 | creds = SSOCredentialsRoot() | ||
880 | 56 | self.assertEqual(creds.ping_url, U1_PING_URL) | ||
881 | 57 | |||
882 | 58 | |||
883 | 59 | class SSOLoginMockedTestCase(MockerTestCase): | ||
884 | 60 | """Test that the call are relied correctly.""" | ||
885 | 61 | |||
886 | 62 | def setUp(self): | ||
887 | 63 | """Setup tests.""" | ||
888 | 64 | super(SSOLoginMockedTestCase, self).setUp() | ||
889 | 65 | self.root = self.mocker.mock() | ||
890 | 66 | mockbusname = self.mocker.mock() | ||
891 | 67 | mockbus = self.mocker.mock() | ||
892 | 68 | mockbusname.get_bus() | ||
893 | 69 | self.mocker.result(mockbus) | ||
894 | 70 | self.login = SSOLogin(mockbus) | ||
895 | 71 | self.login.root = self.root | ||
896 | 72 | self.mocker.reset() | ||
897 | 73 | |||
898 | 74 | def test_generate_captcha(self): | ||
899 | 75 | """Test that the call is relayed.""" | ||
900 | 76 | app_name = 'app' | ||
901 | 77 | filename = 'file' | ||
902 | 78 | self.root.generate_captcha(app_name, filename, MATCH(callable), | ||
903 | 79 | MATCH(callable), MATCH(callable)) | ||
904 | 80 | self.mocker.replay() | ||
905 | 81 | self.login.generate_captcha(app_name, filename) | ||
906 | 82 | |||
907 | 83 | def test_register_user(self): | ||
908 | 84 | """Test that the call is relayed.""" | ||
909 | 85 | app_name = 'app' | ||
910 | 86 | email = 'email' | ||
911 | 87 | password = 'pwd' | ||
912 | 88 | captcha_id = 'id' | ||
913 | 89 | captcha_solution = 'hello' | ||
914 | 90 | self.root.register_user(app_name, email, password, captcha_id, | ||
915 | 91 | captcha_solution, MATCH(callable), | ||
916 | 92 | MATCH(callable), MATCH(callable)) | ||
917 | 93 | self.mocker.replay() | ||
918 | 94 | self.login.register_user(app_name, email, password, captcha_id, | ||
919 | 95 | captcha_solution) | ||
920 | 96 | |||
921 | 97 | def test_login(self): | ||
922 | 98 | """Test that the call is relayed.""" | ||
923 | 99 | app_name = 'app' | ||
924 | 100 | email = 'email' | ||
925 | 101 | password = 'password' | ||
926 | 102 | self.root.login(app_name, email, password, MATCH(callable), | ||
927 | 103 | MATCH(callable), MATCH(callable), | ||
928 | 104 | MATCH(callable)) | ||
929 | 105 | self.mocker.mock() | ||
930 | 106 | self.mocker.replay() | ||
931 | 107 | self.login.login(app_name, email, password) | ||
932 | 108 | |||
933 | 109 | def test_validate_email(self): | ||
934 | 110 | """Test that the call is relayed.""" | ||
935 | 111 | app_name = 'app' | ||
936 | 112 | email = 'email' | ||
937 | 113 | password = 'passwrd' | ||
938 | 114 | email_token = 'token' | ||
939 | 115 | self.root.validate_email(app_name, email, password, email_token, | ||
940 | 116 | MATCH(callable), MATCH(callable), | ||
941 | 117 | MATCH(callable)) | ||
942 | 118 | self.mocker.replay() | ||
943 | 119 | self.login.validate_email(app_name, email, password, email_token) | ||
944 | 120 | |||
945 | 121 | def test_request_password_reset_tolen(self): | ||
946 | 122 | """Test that the call is relayed.""" | ||
947 | 123 | app_name = 'app' | ||
948 | 124 | email = 'email' | ||
949 | 125 | self.root.request_password_reset_token(app_name, email, | ||
950 | 126 | MATCH(callable), | ||
951 | 127 | MATCH(callable), | ||
952 | 128 | MATCH(callable)) | ||
953 | 129 | self.mocker.replay() | ||
954 | 130 | self.login.request_password_reset_token(app_name, email) | ||
955 | 131 | |||
956 | 132 | def test_set_new_password(self): | ||
957 | 133 | """Test that the call is relayed.""" | ||
958 | 134 | app_name = 'app' | ||
959 | 135 | email = 'email' | ||
960 | 136 | token = 'token' | ||
961 | 137 | new_password = 'new' | ||
962 | 138 | self.root.set_new_password(app_name, email, token, new_password, | ||
963 | 139 | MATCH(callable), MATCH(callable), | ||
964 | 140 | MATCH(callable)) | ||
965 | 141 | self.mocker.replay() | ||
966 | 142 | self.login.set_new_password(app_name, email, token, new_password) | ||
967 | 143 | |||
968 | 144 | |||
969 | 145 | class SSOCredentialsMockedTestCase(MockerTestCase): | ||
970 | 146 | """Test that the call are relied correctly.""" | ||
971 | 147 | |||
972 | 148 | def setUp(self): | ||
973 | 149 | """Setup tests.""" | ||
974 | 150 | super(SSOCredentialsMockedTestCase, self).setUp() | ||
975 | 151 | self.root = self.mocker.mock() | ||
976 | 152 | mockbusname = self.mocker.mock() | ||
977 | 153 | mockbus = self.mocker.mock() | ||
978 | 154 | mockbusname.get_bus() | ||
979 | 155 | self.mocker.result(mockbus) | ||
980 | 156 | self.cred = SSOCredentials(mockbus) | ||
981 | 157 | self.cred.root = self.root | ||
982 | 158 | self.mocker.reset() | ||
983 | 159 | |||
984 | 160 | def test_find_credentials(self): | ||
985 | 161 | """Test that the call is relayed.""" | ||
986 | 162 | app_name = 'app' | ||
987 | 163 | result_cb = error_cb = lambda: None | ||
988 | 164 | self.root.find_credentials(app_name, result_cb, error_cb) | ||
989 | 165 | self.mocker.mock() | ||
990 | 166 | self.mocker.replay() | ||
991 | 167 | self.cred.find_credentials(app_name, result_cb, error_cb) | ||
992 | 168 | |||
993 | 169 | def test_login_or_register_to_get_credentials(self): | ||
994 | 170 | """Test that the call is relayed.""" | ||
995 | 171 | app_name = 'app' | ||
996 | 172 | terms = 'terms' | ||
997 | 173 | help_text = 'help' | ||
998 | 174 | window_id = 'id' | ||
999 | 175 | self.root.login_or_register_to_get_credentials(app_name, terms, | ||
1000 | 176 | help_text, window_id, | ||
1001 | 177 | MATCH(callable), | ||
1002 | 178 | MATCH(callable), | ||
1003 | 179 | MATCH(callable)) | ||
1004 | 180 | self.mocker.replay() | ||
1005 | 181 | self.cred.login_or_register_to_get_credentials(app_name, terms, | ||
1006 | 182 | help_text, window_id) | ||
1007 | 183 | |||
1008 | 184 | def test_clear_token(self): | ||
1009 | 185 | """Test that the call is relayed.""" | ||
1010 | 186 | app_name = 'app' | ||
1011 | 187 | result_cb = error_cb = lambda: None | ||
1012 | 188 | self.root.clear_token(app_name, result_cb, error_cb) | ||
1013 | 189 | self.mocker.replay() | ||
1014 | 190 | self.cred.clear_token(app_name, result_cb, error_cb) | ||
1015 | 191 | |||
1016 | 192 | |||
1017 | 193 | class CredentialsManagementMockedTestCase(MockerTestCase): | ||
1018 | 194 | """Test that the call are relied correctly.""" | ||
1019 | 195 | |||
1020 | 196 | def setUp(self): | ||
1021 | 197 | """Setup tests.""" | ||
1022 | 198 | super(CredentialsManagementMockedTestCase, self).setUp() | ||
1023 | 199 | self.root = self.mocker.mock() | ||
1024 | 200 | self.cred = CredentialsManagement(None, None) | ||
1025 | 201 | self.cred.root = self.root | ||
1026 | 202 | |||
1027 | 203 | def test_find_credentials(self): | ||
1028 | 204 | """Test that the call is relayed.""" | ||
1029 | 205 | app_name = 'app' | ||
1030 | 206 | args = 'args' | ||
1031 | 207 | self.root.find_credentials(app_name, args, MATCH(callable), | ||
1032 | 208 | MATCH(callable)) | ||
1033 | 209 | self.mocker.replay() | ||
1034 | 210 | self.cred.find_credentials(app_name, args) | ||
1035 | 211 | |||
1036 | 212 | def test_clear_credentials(self): | ||
1037 | 213 | """Test that the call is relayed.""" | ||
1038 | 214 | app_name = 'app' | ||
1039 | 215 | args = 'args' | ||
1040 | 216 | self.root.clear_credentials(app_name, args, MATCH(callable), | ||
1041 | 217 | MATCH(callable)) | ||
1042 | 218 | self.mocker.replay() | ||
1043 | 219 | self.cred.clear_credentials(app_name, args) | ||
1044 | 220 | |||
1045 | 221 | def test_store_credentials(self): | ||
1046 | 222 | """Test that the call is relayed.""" | ||
1047 | 223 | app_name = 'app' | ||
1048 | 224 | args = 'args' | ||
1049 | 225 | self.root.store_credentials(app_name, args, MATCH(callable), | ||
1050 | 226 | MATCH(callable)) | ||
1051 | 227 | self.mocker.replay() | ||
1052 | 228 | self.cred.store_credentials(app_name, args) | ||
1053 | 229 | |||
1054 | 230 | def test_register(self): | ||
1055 | 231 | """Test that the call is relayed.""" | ||
1056 | 232 | app_name = 'app' | ||
1057 | 233 | args = 'args' | ||
1058 | 234 | self.root.register(app_name, args) | ||
1059 | 235 | self.mocker.replay() | ||
1060 | 236 | self.cred.register(app_name, args) | ||
1061 | 237 | |||
1062 | 238 | def test_login(self): | ||
1063 | 239 | """Test that the call is relayed.""" | ||
1064 | 240 | app_name = 'app' | ||
1065 | 241 | args = 'args' | ||
1066 | 242 | self.root.login(app_name, args) | ||
1067 | 243 | self.mocker.replay() | ||
1068 | 244 | self.cred.login(app_name, args) | ||
1069 | 0 | 245 | ||
1070 | === renamed file 'ubuntu_sso/tests/test_main.py' => 'ubuntu_sso/tests/main/test_linux.py' | |||
1071 | --- ubuntu_sso/tests/test_main.py 2011-01-28 13:45:09 +0000 | |||
1072 | +++ ubuntu_sso/tests/main/test_linux.py 2011-03-17 08:43:34 +0000 | |||
1073 | @@ -31,12 +31,13 @@ | |||
1074 | 31 | 31 | ||
1075 | 32 | import ubuntu_sso.keyring | 32 | import ubuntu_sso.keyring |
1076 | 33 | import ubuntu_sso.main | 33 | import ubuntu_sso.main |
1077 | 34 | import ubuntu_sso.main.linux | ||
1078 | 34 | 35 | ||
1079 | 35 | from ubuntu_sso import DBUS_CREDENTIALS_IFACE | 36 | from ubuntu_sso import DBUS_CREDENTIALS_IFACE |
1080 | 36 | from ubuntu_sso.keyring import U1_APP_NAME | 37 | from ubuntu_sso.keyring import U1_APP_NAME |
1083 | 37 | from ubuntu_sso.main import (U1_PING_URL, TIMEOUT_INTERVAL, | 38 | from ubuntu_sso.main import (U1_PING_URL, except_to_errdict, |
1082 | 38 | blocking, except_to_errdict, | ||
1084 | 39 | CredentialsManagement, SSOCredentials, SSOLogin) | 39 | CredentialsManagement, SSOCredentials, SSOLogin) |
1085 | 40 | from ubuntu_sso.main.linux import TIMEOUT_INTERVAL, blocking | ||
1086 | 40 | from ubuntu_sso.main import (HELP_TEXT_KEY, PING_URL_KEY, | 41 | from ubuntu_sso.main import (HELP_TEXT_KEY, PING_URL_KEY, |
1087 | 41 | TC_URL_KEY, UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY, | 42 | TC_URL_KEY, UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY, |
1088 | 42 | SUCCESS_CB_KEY, ERROR_CB_KEY, DENIAL_CB_KEY) | 43 | SUCCESS_CB_KEY, ERROR_CB_KEY, DENIAL_CB_KEY) |
1089 | @@ -120,7 +121,7 @@ | |||
1090 | 120 | expected_result = "expected result" | 121 | expected_result = "expected result" |
1091 | 121 | self.create_mock_processor().generate_captcha(filename) | 122 | self.create_mock_processor().generate_captcha(filename) |
1092 | 122 | self.mocker.result(expected_result) | 123 | self.mocker.result(expected_result) |
1094 | 123 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 124 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1095 | 124 | self.mocker.replay() | 125 | self.mocker.replay() |
1096 | 125 | 126 | ||
1097 | 126 | def verify(app_name, result): | 127 | def verify(app_name, result): |
1098 | @@ -143,7 +144,7 @@ | |||
1099 | 143 | expected_result = "expected result" | 144 | expected_result = "expected result" |
1100 | 144 | self.create_mock_processor().generate_captcha(filename) | 145 | self.create_mock_processor().generate_captcha(filename) |
1101 | 145 | self.mocker.result(expected_result) | 146 | self.mocker.result(expected_result) |
1103 | 146 | self.patch(ubuntu_sso.main, "blocking", fake_err_blocking) | 147 | self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking) |
1104 | 147 | self.mocker.replay() | 148 | self.mocker.replay() |
1105 | 148 | 149 | ||
1106 | 149 | def verify(app_name, errdict): | 150 | def verify(app_name, errdict): |
1107 | @@ -166,7 +167,7 @@ | |||
1108 | 166 | self.create_mock_processor().register_user(EMAIL, PASSWORD, CAPTCHA_ID, | 167 | self.create_mock_processor().register_user(EMAIL, PASSWORD, CAPTCHA_ID, |
1109 | 167 | CAPTCHA_SOLUTION) | 168 | CAPTCHA_SOLUTION) |
1110 | 168 | self.mocker.result(expected_result) | 169 | self.mocker.result(expected_result) |
1112 | 169 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 170 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1113 | 170 | self.mocker.replay() | 171 | self.mocker.replay() |
1114 | 171 | 172 | ||
1115 | 172 | def verify(app_name, result): | 173 | def verify(app_name, result): |
1116 | @@ -190,7 +191,7 @@ | |||
1117 | 190 | self.create_mock_processor().register_user(EMAIL, PASSWORD, CAPTCHA_ID, | 191 | self.create_mock_processor().register_user(EMAIL, PASSWORD, CAPTCHA_ID, |
1118 | 191 | CAPTCHA_SOLUTION) | 192 | CAPTCHA_SOLUTION) |
1119 | 192 | self.mocker.result(expected_result) | 193 | self.mocker.result(expected_result) |
1121 | 193 | self.patch(ubuntu_sso.main, "blocking", fake_err_blocking) | 194 | self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking) |
1122 | 194 | self.mocker.replay() | 195 | self.mocker.replay() |
1123 | 195 | 196 | ||
1124 | 196 | def verify(app_name, errdict): | 197 | def verify(app_name, errdict): |
1125 | @@ -215,7 +216,7 @@ | |||
1126 | 215 | self.mocker.result(TOKEN) | 216 | self.mocker.result(TOKEN) |
1127 | 216 | processor.is_validated(TOKEN) | 217 | processor.is_validated(TOKEN) |
1128 | 217 | self.mocker.result(True) | 218 | self.mocker.result(True) |
1130 | 218 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 219 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1131 | 219 | self.mocker.replay() | 220 | self.mocker.replay() |
1132 | 220 | 221 | ||
1133 | 221 | def verify(app_name, result): | 222 | def verify(app_name, result): |
1134 | @@ -241,7 +242,7 @@ | |||
1135 | 241 | self.mocker.result(TOKEN) | 242 | self.mocker.result(TOKEN) |
1136 | 242 | processor.is_validated(TOKEN) | 243 | processor.is_validated(TOKEN) |
1137 | 243 | self.mocker.result(False) | 244 | self.mocker.result(False) |
1139 | 244 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 245 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1140 | 245 | self.mocker.replay() | 246 | self.mocker.replay() |
1141 | 246 | 247 | ||
1142 | 247 | def verify(app_name, email): | 248 | def verify(app_name, email): |
1143 | @@ -263,7 +264,7 @@ | |||
1144 | 263 | """The login method fails as expected when get_token_name fails.""" | 264 | """The login method fails as expected when get_token_name fails.""" |
1145 | 264 | d = Deferred() | 265 | d = Deferred() |
1146 | 265 | self.create_mock_processor() | 266 | self.create_mock_processor() |
1148 | 266 | self.patch(ubuntu_sso.main, "blocking", fake_err_blocking) | 267 | self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking) |
1149 | 267 | 268 | ||
1150 | 268 | def fake_gtn(*args): | 269 | def fake_gtn(*args): |
1151 | 269 | """A fake get_token_name that fails.""" | 270 | """A fake get_token_name that fails.""" |
1152 | @@ -296,7 +297,7 @@ | |||
1153 | 296 | processor.is_validated(TOKEN) | 297 | processor.is_validated(TOKEN) |
1154 | 297 | self.mocker.result(True) | 298 | self.mocker.result(True) |
1155 | 298 | 299 | ||
1157 | 299 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 300 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1158 | 300 | 301 | ||
1159 | 301 | def fake_set_creds(*args): | 302 | def fake_set_creds(*args): |
1160 | 302 | """A fake Keyring.set_credentials that fails.""" | 303 | """A fake Keyring.set_credentials that fails.""" |
1161 | @@ -327,7 +328,7 @@ | |||
1162 | 327 | self.create_mock_processor().validate_email(EMAIL, PASSWORD, | 328 | self.create_mock_processor().validate_email(EMAIL, PASSWORD, |
1163 | 328 | EMAIL_TOKEN, TOKEN_NAME) | 329 | EMAIL_TOKEN, TOKEN_NAME) |
1164 | 329 | self.mocker.result(TOKEN) | 330 | self.mocker.result(TOKEN) |
1166 | 330 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 331 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1167 | 331 | self.mocker.replay() | 332 | self.mocker.replay() |
1168 | 332 | 333 | ||
1169 | 333 | def verify(app_name, result): | 334 | def verify(app_name, result): |
1170 | @@ -348,7 +349,7 @@ | |||
1171 | 348 | """Test that the validate_email method fails as expected.""" | 349 | """Test that the validate_email method fails as expected.""" |
1172 | 349 | d = Deferred() | 350 | d = Deferred() |
1173 | 350 | self.create_mock_processor() | 351 | self.create_mock_processor() |
1175 | 351 | self.patch(ubuntu_sso.main, "blocking", fake_err_blocking) | 352 | self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking) |
1176 | 352 | 353 | ||
1177 | 353 | def fake_gtn(*args): | 354 | def fake_gtn(*args): |
1178 | 354 | """A fake get_token_name that fails.""" | 355 | """A fake get_token_name that fails.""" |
1179 | @@ -376,7 +377,7 @@ | |||
1180 | 376 | d = Deferred() | 377 | d = Deferred() |
1181 | 377 | processor = self.create_mock_processor() | 378 | processor = self.create_mock_processor() |
1182 | 378 | processor.request_password_reset_token(EMAIL) | 379 | processor.request_password_reset_token(EMAIL) |
1184 | 379 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 380 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1185 | 380 | self.mocker.result(EMAIL) | 381 | self.mocker.result(EMAIL) |
1186 | 381 | self.mocker.replay() | 382 | self.mocker.replay() |
1187 | 382 | 383 | ||
1188 | @@ -399,7 +400,7 @@ | |||
1189 | 399 | 400 | ||
1190 | 400 | self.create_mock_processor().request_password_reset_token(EMAIL) | 401 | self.create_mock_processor().request_password_reset_token(EMAIL) |
1191 | 401 | self.mocker.result(EMAIL) | 402 | self.mocker.result(EMAIL) |
1193 | 402 | self.patch(ubuntu_sso.main, "blocking", fake_err_blocking) | 403 | self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking) |
1194 | 403 | self.mocker.replay() | 404 | self.mocker.replay() |
1195 | 404 | 405 | ||
1196 | 405 | def verify(app_name, errdict): | 406 | def verify(app_name, errdict): |
1197 | @@ -421,7 +422,7 @@ | |||
1198 | 421 | self.create_mock_processor().set_new_password(EMAIL, EMAIL_TOKEN, | 422 | self.create_mock_processor().set_new_password(EMAIL, EMAIL_TOKEN, |
1199 | 422 | PASSWORD) | 423 | PASSWORD) |
1200 | 423 | self.mocker.result(EMAIL) | 424 | self.mocker.result(EMAIL) |
1202 | 424 | self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking) | 425 | self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking) |
1203 | 425 | self.mocker.replay() | 426 | self.mocker.replay() |
1204 | 426 | 427 | ||
1205 | 427 | def verify(app_name, result): | 428 | def verify(app_name, result): |
1206 | @@ -445,7 +446,7 @@ | |||
1207 | 445 | self.create_mock_processor().set_new_password(EMAIL, EMAIL_TOKEN, | 446 | self.create_mock_processor().set_new_password(EMAIL, EMAIL_TOKEN, |
1208 | 446 | PASSWORD) | 447 | PASSWORD) |
1209 | 447 | self.mocker.result(expected_result) | 448 | self.mocker.result(expected_result) |
1211 | 448 | self.patch(ubuntu_sso.main, "blocking", fake_err_blocking) | 449 | self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking) |
1212 | 449 | self.mocker.replay() | 450 | self.mocker.replay() |
1213 | 450 | 451 | ||
1214 | 451 | def verify(app_name, errdict): | 452 | def verify(app_name, errdict): |
1215 | @@ -687,7 +688,7 @@ | |||
1216 | 687 | os.environ['USSOC_PING_URL'] = fake_url | 688 | os.environ['USSOC_PING_URL'] = fake_url |
1217 | 688 | try: | 689 | try: |
1218 | 689 | creds = SSOCredentials(None) | 690 | creds = SSOCredentials(None) |
1220 | 690 | self.assertEqual(creds.ping_url, fake_url) | 691 | self.assertEqual(creds.root.ping_url, fake_url) |
1221 | 691 | finally: | 692 | finally: |
1222 | 692 | if old_url: | 693 | if old_url: |
1223 | 693 | os.environ['USSOC_PING_URL'] = old_url | 694 | os.environ['USSOC_PING_URL'] = old_url |
1224 | @@ -697,7 +698,7 @@ | |||
1225 | 697 | def test_no_override_ping_url(self): | 698 | def test_no_override_ping_url(self): |
1226 | 698 | """If the environ is unset, the default ping url is used.""" | 699 | """If the environ is unset, the default ping url is used.""" |
1227 | 699 | creds = SSOCredentials(None) | 700 | creds = SSOCredentials(None) |
1229 | 700 | self.assertEqual(creds.ping_url, U1_PING_URL) | 701 | self.assertEqual(creds.root.ping_url, U1_PING_URL) |
1230 | 701 | 702 | ||
1231 | 702 | 703 | ||
1232 | 703 | class CredentialsManagementTestCase(TestCase): | 704 | class CredentialsManagementTestCase(TestCase): |
1233 | @@ -746,7 +747,8 @@ | |||
1234 | 746 | 747 | ||
1235 | 747 | def test_is_dbus_object(self): | 748 | def test_is_dbus_object(self): |
1236 | 748 | """CredentialsManagement is a Dbus object.""" | 749 | """CredentialsManagement is a Dbus object.""" |
1238 | 749 | self.assertIsInstance(self.client, ubuntu_sso.main.dbus.service.Object) | 750 | self.assertIsInstance(self.client, |
1239 | 751 | ubuntu_sso.main.linux.dbus.service.Object) | ||
1240 | 750 | 752 | ||
1241 | 751 | 753 | ||
1242 | 752 | class FakeCredentials(object): | 754 | class FakeCredentials(object): |
1243 | 753 | 755 | ||
1244 | === added file 'ubuntu_sso/tests/main/test_windows.py' | |||
1245 | --- ubuntu_sso/tests/main/test_windows.py 1970-01-01 00:00:00 +0000 | |||
1246 | +++ ubuntu_sso/tests/main/test_windows.py 2011-03-17 08:43:34 +0000 | |||
1247 | @@ -0,0 +1,17 @@ | |||
1248 | 1 | # -*- coding: utf-8 -*- | ||
1249 | 2 | # Author: Manuel de la Pena <manuel@canonical.com> | ||
1250 | 3 | # | ||
1251 | 4 | # Copyright 2011 Canonical Ltd. | ||
1252 | 5 | # | ||
1253 | 6 | # This program is free software: you can redistribute it and/or modify it | ||
1254 | 7 | # under the terms of the GNU General Public License version 3, as published | ||
1255 | 8 | # by the Free Software Foundation. | ||
1256 | 9 | # | ||
1257 | 10 | # This program is distributed in the hope that it will be useful, but | ||
1258 | 11 | # WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1259 | 12 | # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1260 | 13 | # PURPOSE. See the GNU General Public License for more details. | ||
1261 | 14 | # | ||
1262 | 15 | # You should have received a copy of the GNU General Public License along | ||
1263 | 16 | # with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1264 | 17 | """Windows tests.""" | ||
1265 | 0 | 18 | ||
1266 | === renamed file 'ubuntu_sso/tests/networkstate/test_linux_networkstate.py' => 'ubuntu_sso/tests/networkstate/test_linux.py' | |||
1267 | === renamed file 'ubuntu_sso/tests/networkstate/test_windows_networkstate.py' => 'ubuntu_sso/tests/networkstate/test_windows.py' |
+1 on windows