Merge lp:~mvo/software-center/login-cleanup into lp:software-center
- login-cleanup
- Merge into trunk
Proposed by
Michael Vogt
Status: | Merged |
---|---|
Merged at revision: | 3181 |
Proposed branch: | lp:~mvo/software-center/login-cleanup |
Merge into: | lp:software-center |
Prerequisite: | lp:~mvo/software-center/merge-prev-purchases-lp969273 |
Diff against target: |
898 lines (+147/-506) 13 files modified
software-center (+0/-5) softwarecenter/backend/launchpad.py (+0/-341) softwarecenter/backend/login.py (+34/-1) softwarecenter/backend/login_impl/login_fake.py (+85/-0) softwarecenter/backend/login_impl/login_sso.py (+3/-84) softwarecenter/backend/oneconfhandler/core.py (+2/-2) softwarecenter/backend/ubuntusso.py (+6/-6) softwarecenter/ui/gtk3/app.py (+2/-20) softwarecenter/ui/gtk3/review_gui_helper.py (+2/-2) softwarecenter/ui/gtk3/widgets/recommendations.py (+2/-2) tests/disabled_test_launchpad.py (+0/-36) tests/gtk3/test_catview.py (+1/-1) tests/test_login_backend.py (+10/-6) |
To merge this branch: | bzr merge lp:~mvo/software-center/login-cleanup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gary Lasker (community) | Approve | ||
Review via email: mp+124420@code.launchpad.net |
Commit message
Description of the change
Cleanup around the login backend code to make the naming better and to move the actual implementation of the login backend into softwarecenter.
Plus it removes a unused launchpad interfaces for private ppas that never got used nor does it work correctly.
To post a comment you must log in.
- 3190. By Michael Vogt
-
fix tests
- 3191. By Michael Vogt
-
merged from merge-prev-
purchases- lp969273
Revision history for this message
Michael Vogt (mvo) wrote : | # |
- 3192. By Michael Vogt
-
pep8 fixes
Revision history for this message
Gary Lasker (gary-lasker) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'software-center' |
2 | --- software-center 2012-09-06 10:19:43 +0000 |
3 | +++ software-center 2012-09-14 14:02:22 +0000 |
4 | @@ -62,11 +62,6 @@ |
5 | parser.add_option("--display-navlog", action="store_true", |
6 | help="display a navigation history log (useful for debugging)", |
7 | default=False) |
8 | - # FIXME: REMOVE THIS option once launchpad integration is enabled |
9 | - # by default |
10 | - parser.add_option("--enable-lp", action="store_true", |
11 | - help="enable launchpad integration (for development use)", |
12 | - default=False) |
13 | parser.add_option("--disable-buy", action="store_true", |
14 | help="disable support to buy software", |
15 | default=False) |
16 | |
17 | === removed file 'softwarecenter/backend/launchpad.py' |
18 | --- softwarecenter/backend/launchpad.py 2012-08-07 13:15:08 +0000 |
19 | +++ softwarecenter/backend/launchpad.py 1970-01-01 00:00:00 +0000 |
20 | @@ -1,341 +0,0 @@ |
21 | -#!/usr/bin/python |
22 | -# -*- coding: utf-8 -*- |
23 | - |
24 | -# Copyright (C) 2009 Canonical |
25 | -# |
26 | -# Authors: |
27 | -# Michael Vogt |
28 | -# |
29 | -# This program is free software; you can redistribute it and/or modify it under |
30 | -# the terms of the GNU General Public License as published by the Free Software |
31 | -# Foundation; version 3. |
32 | -# |
33 | -# This program is distributed in the hope that it will be useful, but WITHOUT |
34 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
35 | -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
36 | -# details. |
37 | -# |
38 | -# You should have received a copy of the GNU General Public License along with |
39 | -# this program; if not, write to the Free Software Foundation, Inc., |
40 | -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
41 | - |
42 | -import os |
43 | -from gi.repository import GObject |
44 | -import time |
45 | -import threading |
46 | - |
47 | -import logging |
48 | -from softwarecenter.distro import get_distro |
49 | - |
50 | -from launchpadlib.launchpad import Launchpad |
51 | -from launchpadlib.credentials import RequestTokenAuthorizationEngine |
52 | -from launchpadlib.uris import LPNET_SERVICE_ROOT |
53 | -from softwarecenter.paths import SOFTWARE_CENTER_CACHE_DIR |
54 | - |
55 | -# py3 compat |
56 | -try: |
57 | - from queue import Queue |
58 | - Queue # pyflakes |
59 | -except ImportError: |
60 | - from Queue import Queue |
61 | - |
62 | -from login import LoginBackend |
63 | - |
64 | -# LP to use |
65 | -SERVICE_ROOT = LPNET_SERVICE_ROOT |
66 | - |
67 | -# internal |
68 | - |
69 | -# the various states that the login can be in |
70 | -LOGIN_STATE_UNKNOWN = "unkown" |
71 | -LOGIN_STATE_ASK_USER_AND_PASS = "ask-user-and-pass" |
72 | -LOGIN_STATE_HAS_USER_AND_PASS = "has-user-pass" |
73 | -LOGIN_STATE_SUCCESS = "success" |
74 | -LOGIN_STATE_SUCCESS_PENDING = "success-pending" |
75 | -LOGIN_STATE_AUTH_FAILURE = "auth-fail" |
76 | -LOGIN_STATE_USER_CANCEL = "user-cancel" |
77 | - |
78 | - |
79 | -class UserCancelException(Exception): |
80 | - """ user pressed cancel """ |
81 | - pass |
82 | - |
83 | - |
84 | -class LaunchpadlibWorker(threading.Thread): |
85 | - """The launchpadlib worker thread - it does not touch the UI |
86 | - and only communicates via the following: |
87 | - |
88 | - "login_state" - the current LOGIN_STATE_* value |
89 | - |
90 | - To input reviews call "queue_review()" |
91 | - When no longer needed, call "shutdown()" |
92 | - """ |
93 | - |
94 | - def __init__(self): |
95 | - # init parent |
96 | - threading.Thread.__init__(self) |
97 | - # the current login state, this is used accross multiple threads |
98 | - self.login_state = LOGIN_STATE_UNKNOWN |
99 | - # the username/pw to use |
100 | - self.login_username = "" |
101 | - self.login_password = "" |
102 | - self._launchpad = None |
103 | - self._pending_requests = Queue() |
104 | - self._shutdown = False |
105 | - self._logger = logging.getLogger("softwarecenter.backend") |
106 | - |
107 | - def run(self): |
108 | - """ |
109 | - Main thread run interface, logs into launchpad |
110 | - """ |
111 | - self._logger.debug("lp worker thread run") |
112 | - # login |
113 | - self._lp_login() |
114 | - # loop |
115 | - self._wait_for_commands() |
116 | - |
117 | - def shutdown(self): |
118 | - """Request shutdown""" |
119 | - self._shutdown = True |
120 | - |
121 | - def queue_request(self, func, args, result_callback): |
122 | - # FIXME: add support to pass strings instead of callable |
123 | - self._pending_requests.put((func, args, result_callback)) |
124 | - |
125 | - def _wait_for_commands(self): |
126 | - """internal helper that waits for commands""" |
127 | - while True: |
128 | - while not self._pending_requests.empty(): |
129 | - self._logger.debug("found pending request") |
130 | - (func, args, result_callback) = self._pending_requests.get() |
131 | - # run func async |
132 | - res = func(*args) |
133 | - # provide result to the callback |
134 | - result_callback(res) |
135 | - self._pending_requests.task_done() |
136 | - # wait a bit |
137 | - time.sleep(0.1) |
138 | - if (self._shutdown and |
139 | - self._pending_requests.empty()): |
140 | - return |
141 | - |
142 | - def _lp_login(self, access_level=['READ_PRIVATE']): |
143 | - """ internal LP login code """ |
144 | - self._logger.debug("lp_login") |
145 | - # use cachedir |
146 | - cachedir = SOFTWARE_CENTER_CACHE_DIR |
147 | - if not os.path.exists(cachedir): |
148 | - os.makedirs(cachedir) |
149 | - # login into LP with GUI |
150 | - try: |
151 | - self._launchpad = Launchpad.login_with( |
152 | - 'software-center', SERVICE_ROOT, cachedir, |
153 | - allow_access_levels=access_level, |
154 | - authorizer_class=AuthorizeRequestTokenFromThread) |
155 | - self.display_name = self._launchpad.me.display_name |
156 | - except Exception as e: |
157 | - if type(e) == UserCancelException: |
158 | - return |
159 | - self._logger.exception("Launchpad.login_with()") |
160 | - # remove token on failure, it may be e.g. expired |
161 | - # FIXME: store the token in a different place and to avoid |
162 | - # having to use _get_paths() |
163 | - (service_root, launchpadlib_dir, cache_path, |
164 | - service_root_dir) = Launchpad._get_paths(SERVICE_ROOT, cachedir) |
165 | - credentials_path = os.path.join(service_root_dir, 'credentials') |
166 | - consumer_credentials_path = os.path.join(credentials_path, |
167 | - 'software-center') |
168 | - # --- |
169 | - if os.path.exists(consumer_credentials_path): |
170 | - os.remove(consumer_credentials_path) |
171 | - self._lp_login(access_level) |
172 | - return |
173 | - self.login_state = LOGIN_STATE_SUCCESS |
174 | - self._logger.debug("/done %s" % self._launchpad) |
175 | - |
176 | - |
177 | -class AuthorizeRequestTokenFromThread(RequestTokenAuthorizationEngine): |
178 | - """ Internal helper that updates the login_state of |
179 | - the modul global lp_worker_thread object |
180 | - """ |
181 | - def __init__(self, *args, **kwargs): |
182 | - super(AuthorizeRequestTokenFromThread, self).__init__(*args, **kwargs) |
183 | - self._logger = logging.getLogger("softwarecenter.backend") |
184 | - |
185 | - # we need this to give the engine a place to store the state |
186 | - # for the UI |
187 | - def __new__(cls, *args, **kwargs): |
188 | - o = object.__new__(cls) |
189 | - # keep the state here (the lp_worker_thead global to this module) |
190 | - o.lp_worker = lp_worker_thread |
191 | - return o |
192 | - |
193 | - def input_username(self, cached_username, suggested_message): |
194 | - self._logger.debug("input_username: %s" % self.lp_worker.login_state) |
195 | - # otherwise go into ASK state |
196 | - if not self.lp_worker.login_state in (LOGIN_STATE_ASK_USER_AND_PASS, |
197 | - LOGIN_STATE_AUTH_FAILURE, |
198 | - LOGIN_STATE_USER_CANCEL): |
199 | - self.lp_worker.login_state = LOGIN_STATE_ASK_USER_AND_PASS |
200 | - # check if user canceled and if so just return "" |
201 | - if self.lp_worker.login_state == LOGIN_STATE_USER_CANCEL: |
202 | - raise UserCancelException |
203 | - # wait for username to become available |
204 | - while not self.lp_worker.login_state in (LOGIN_STATE_HAS_USER_AND_PASS, |
205 | - LOGIN_STATE_USER_CANCEL): |
206 | - time.sleep(0.2) |
207 | - # note: returning None here make lplib open a registration page |
208 | - # in the browser |
209 | - return self.lp_worker.login_username |
210 | - |
211 | - def input_password(self, suggested_message): |
212 | - self._logger.debug("Input password size %s" % |
213 | - len(self.lp_worker.login_password)) |
214 | - return self.lp_worker.login_password |
215 | - |
216 | - def input_access_level(self, available_levels, suggested_message, |
217 | - only_one_option=None): |
218 | - """Collect the desired level of access from the end-user.""" |
219 | - self._logger.debug("input_access_level") |
220 | - return "WRITE_PUBLIC" |
221 | - |
222 | - def startup(self, suggested_messages): |
223 | - self._logger.debug("startup") |
224 | - |
225 | - def authentication_failure(self, suggested_message): |
226 | - """The user entered invalid credentials.""" |
227 | - self._logger.debug("auth failure") |
228 | - # ignore auth failures if the user canceled |
229 | - if self.lp_worker.login_state == LOGIN_STATE_USER_CANCEL: |
230 | - return |
231 | - self.lp_worker.login_state = LOGIN_STATE_AUTH_FAILURE |
232 | - |
233 | - def success(self, suggested_message): |
234 | - """The token was successfully authorized.""" |
235 | - self._logger.debug("success") |
236 | - self.lp_worker.login_state = LOGIN_STATE_SUCCESS_PENDING |
237 | - |
238 | - |
239 | -class GLaunchpad(LoginBackend): |
240 | - """ A launchpad connection that uses GObject signals |
241 | - for communication and async tasks |
242 | - """ |
243 | - |
244 | - NEW_ACCOUNT_URL = "https://login.launchpad.net/+standalone-login" |
245 | - FORGOT_PASSWORD_URL = "https://login.launchpad.net/+standalone-login" |
246 | - |
247 | - def __init__(self): |
248 | - LoginBackend.__init__(self) |
249 | - self.distro = get_distro() |
250 | - self.oauth_token = None |
251 | - |
252 | - def connect_to_server(self): |
253 | - """ Connects to launchpad and emits one of: |
254 | - - need-username-password (use enter_username_password() then) |
255 | - - login-successful |
256 | - - login-failed |
257 | - """ |
258 | - GObject.timeout_add(200, self._wait_for_login) |
259 | - lp_worker_thread.start() |
260 | - |
261 | - def shutdown(self): |
262 | - """ shutdown the server connection thread """ |
263 | - lp_worker_thread.shutdown() |
264 | - |
265 | - def enter_username_password(self, user, password): |
266 | - """ |
267 | - provider username and password, ususally used when the |
268 | - need-username-password signal was send |
269 | - """ |
270 | - lp_worker_thread.login_username = user |
271 | - lp_worker_thread.login_password = password |
272 | - lp_worker_thread.login_state = LOGIN_STATE_HAS_USER_AND_PASS |
273 | - |
274 | - def login(self, username=None, password=None): |
275 | - if username and password: |
276 | - self.enter_username_password(username, password) |
277 | - else: |
278 | - self.connect_to_server() |
279 | - |
280 | - def cancel_login(self): |
281 | - lp_worker_thread.login_state = LOGIN_STATE_USER_CANCEL |
282 | - |
283 | - def get_subscribed_archives(self): |
284 | - """ return list of sources.list entries """ |
285 | - urls = lp_worker_thread._launchpad.me.getArchiveSubscriptionURLs() |
286 | - return self._format_archive_subscription_urls_as_deb_lines(urls) |
287 | - |
288 | - def _format_archive_subscription_urls_as_deb_lines(self, urls): |
289 | - deb_lines = ["deb %s %s main" % (url, self.distro.get_codename()) |
290 | - for url in urls] |
291 | - return deb_lines |
292 | - |
293 | - def get_subscribed_archives_async(self, callback): |
294 | - """ get the available subscribed archives and run 'callback' when |
295 | - they become availalbe |
296 | - """ |
297 | - def _result_cb(urls): |
298 | - # format as deb lines |
299 | - callback(self._format_archive_subscription_urls_as_deb_lines(urls)) |
300 | - #func = "me.getArchiveSubscriptionURLs" |
301 | - func = lp_worker_thread._launchpad.me.getArchiveSubscriptionURLs |
302 | - lp_worker_thread.queue_request(func, (), _result_cb) |
303 | - |
304 | - def _wait_for_login(self): |
305 | - state = lp_worker_thread.login_state |
306 | - if state == LOGIN_STATE_AUTH_FAILURE: |
307 | - self.emit("login-failed") |
308 | - elif state == LOGIN_STATE_ASK_USER_AND_PASS: |
309 | - self.emit("need-username-password") |
310 | - elif state == LOGIN_STATE_SUCCESS: |
311 | - self.emit("login-successful", self.oauth_token) |
312 | - return False |
313 | - elif state == LOGIN_STATE_USER_CANCEL: |
314 | - return False |
315 | - return True |
316 | - |
317 | -# IMPORTANT: create one (module) global LP worker thread here |
318 | -lp_worker_thread = LaunchpadlibWorker() |
319 | -# daemon threads make it crash on cancel |
320 | -lp_worker_thread.daemon = True |
321 | - |
322 | - |
323 | -# test code |
324 | -def _login_success(lp): |
325 | - print ("success %s" % lp) |
326 | - print(lp.get_subscribed_archives()) |
327 | - print(lp.get_subscribed_archives_async(_result_callback)) |
328 | - |
329 | - |
330 | -def _login_failed(lp): |
331 | - print ("fail %s" % lp) |
332 | - |
333 | - |
334 | -def _result_callback(result_list): |
335 | - print("_result_callback %s" % result_list) |
336 | - |
337 | - |
338 | -def _login_need_user_and_password(lp): |
339 | - import sys |
340 | - sys.stdout.write("user: ") |
341 | - sys.stdout.flush() |
342 | - user = sys.stdin.readline().strip() |
343 | - sys.stdout.write("pass: ") |
344 | - sys.stdout.flush() |
345 | - password = sys.stdin.readline().strip() |
346 | - lp.enter_username_password(user, password) |
347 | - |
348 | - |
349 | -if __name__ == "__main__": |
350 | - logging.basicConfig(level=logging.DEBUG) |
351 | - lp = GLaunchpad() |
352 | - lp.connect("login-successful", _login_success) |
353 | - lp.connect("login-failed", _login_failed) |
354 | - lp.connect("need-username-password", _login_need_user_and_password) |
355 | - lp.connect_to_server() |
356 | - |
357 | - # wait |
358 | - try: |
359 | - GObject.MainLoop().run() |
360 | - except KeyboardInterrupt: |
361 | - lp_worker_thread.shutdown() |
362 | |
363 | === modified file 'softwarecenter/backend/login.py' |
364 | --- softwarecenter/backend/login.py 2012-09-14 14:02:22 +0000 |
365 | +++ softwarecenter/backend/login.py 2012-09-14 14:02:22 +0000 |
366 | @@ -21,6 +21,11 @@ |
367 | |
368 | from gi.repository import GObject |
369 | |
370 | +import logging |
371 | +import os |
372 | + |
373 | +LOG = logging.getLogger(__name__) |
374 | + |
375 | |
376 | class LoginBackend(GObject.GObject): |
377 | |
378 | @@ -46,7 +51,7 @@ |
379 | ), |
380 | } |
381 | |
382 | - def login(self, username=None, password=None): |
383 | + def login(self): |
384 | raise NotImplemented |
385 | |
386 | def login_or_register(self): |
387 | @@ -57,3 +62,31 @@ |
388 | |
389 | def cancel_login(self): |
390 | self.emit("login-canceled") |
391 | + |
392 | + |
393 | +def get_login_backend(window_id, appname, help_text): |
394 | + """ |
395 | + factory that returns an sso loader singelton |
396 | + """ |
397 | + if "SOFTWARE_CENTER_FAKE_REVIEW_API" in os.environ: |
398 | + from softwarecenter.backend.login_impl.login_fake import ( |
399 | + LoginBackendDbusSSOFake) |
400 | + sso_class = LoginBackendDbusSSOFake(window_id, appname, help_text) |
401 | + LOG.warn('Using fake login SSO functionality. Only meant for ' |
402 | + 'testing purposes') |
403 | + else: |
404 | + from softwarecenter.backend.login_impl.login_sso import ( |
405 | + LoginBackendDbusSSO) |
406 | + sso_class = LoginBackendDbusSSO(window_id, appname, help_text) |
407 | + return sso_class |
408 | + |
409 | + |
410 | +if __name__ == "__main__": |
411 | + logging.basicConfig(level=logging.DEBUG) |
412 | + |
413 | + from softwarecenter.enums import SOFTWARE_CENTER_NAME_KEYRING |
414 | + login = get_login_backend(0, SOFTWARE_CENTER_NAME_KEYRING, "login-text") |
415 | + login.login() |
416 | + |
417 | + from gi.repository import Gtk |
418 | + Gtk.main() |
419 | |
420 | === added directory 'softwarecenter/backend/login_impl' |
421 | === added file 'softwarecenter/backend/login_impl/__init__.py' |
422 | === added file 'softwarecenter/backend/login_impl/login_fake.py' |
423 | --- softwarecenter/backend/login_impl/login_fake.py 1970-01-01 00:00:00 +0000 |
424 | +++ softwarecenter/backend/login_impl/login_fake.py 2012-09-14 14:02:22 +0000 |
425 | @@ -0,0 +1,85 @@ |
426 | +#!/usr/bin/python |
427 | +# -*- coding: utf-8 -*- |
428 | + |
429 | +# Copyright (C) 2012 Canonical |
430 | +# |
431 | +# Authors: |
432 | +# Michael Vogt |
433 | +# |
434 | +# This program is free software; you can redistribute it and/or modify it under |
435 | +# the terms of the GNU General Public License as published by the Free Software |
436 | +# Foundation; version 3. |
437 | +# |
438 | +# This program is distributed in the hope that it will be useful, but WITHOUT |
439 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
440 | +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
441 | +# details. |
442 | +# |
443 | +# You should have received a copy of the GNU General Public License along with |
444 | +# this program; if not, write to the Free Software Foundation, Inc., |
445 | +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
446 | + |
447 | +import dbus |
448 | +import logging |
449 | +import random |
450 | +import string |
451 | + |
452 | +from softwarecenter.backend.fake_review_settings import ( |
453 | + FakeReviewSettings, |
454 | + network_delay, |
455 | + ) |
456 | +from softwarecenter.backend.login import LoginBackend |
457 | + |
458 | +LOG = logging.getLogger(__name__) |
459 | + |
460 | + |
461 | +class LoginBackendDbusSSOFake(LoginBackend): |
462 | + |
463 | + def __init__(self, window_id, appname, help_text): |
464 | + super(LoginBackendDbusSSOFake, self).__init__() |
465 | + self.appname = appname |
466 | + self.help_text = help_text |
467 | + self._window_id = window_id |
468 | + self._fake_settings = FakeReviewSettings() |
469 | + |
470 | + @network_delay |
471 | + def login(self): |
472 | + response = self._fake_settings.get_setting('login_response') |
473 | + |
474 | + if response == "successful": |
475 | + self.emit("login-successful", self._return_credentials()) |
476 | + elif response == "failed": |
477 | + self.emit("login-failed") |
478 | + elif response == "denied": |
479 | + self.cancel_login() |
480 | + |
481 | + return |
482 | + |
483 | + def login_or_register(self): |
484 | + #fake functionality for this is no different to fake login() |
485 | + self.login() |
486 | + return |
487 | + |
488 | + def _random_unicode_string(self, length): |
489 | + retval = '' |
490 | + for i in range(0, length): |
491 | + retval = retval + random.choice(string.letters + string.digits) |
492 | + return retval.decode('utf-8') |
493 | + |
494 | + def _return_credentials(self): |
495 | + c = dbus.Dictionary( |
496 | + { |
497 | + dbus.String(u'consumer_secret'): dbus.String( |
498 | + self._random_unicode_string(30)), |
499 | + dbus.String(u'token'): dbus.String( |
500 | + self._random_unicode_string(50)), |
501 | + dbus.String(u'consumer_key'): dbus.String( |
502 | + self._random_unicode_string(7)), |
503 | + dbus.String(u'name'): dbus.String('Ubuntu Software Center @ ' + |
504 | + self._random_unicode_string(6)), |
505 | + dbus.String(u'token_secret'): dbus.String( |
506 | + self._random_unicode_string(50)) |
507 | + }, |
508 | + signature=dbus.Signature('ss') |
509 | + ) |
510 | + return c |
511 | |
512 | === renamed file 'softwarecenter/backend/login_sso.py' => 'softwarecenter/backend/login_impl/login_sso.py' |
513 | --- softwarecenter/backend/login_sso.py 2012-09-14 14:02:22 +0000 |
514 | +++ softwarecenter/backend/login_impl/login_sso.py 2012-09-14 14:02:22 +0000 |
515 | @@ -21,24 +21,18 @@ |
516 | |
517 | import dbus |
518 | import logging |
519 | -import random |
520 | -import string |
521 | -import os |
522 | |
523 | from dbus.mainloop.glib import DBusGMainLoop |
524 | DBusGMainLoop(set_as_default=True) |
525 | |
526 | -from softwarecenter.utils import utf8 |
527 | -from login import LoginBackend |
528 | - |
529 | from ubuntu_sso import ( |
530 | DBUS_BUS_NAME, |
531 | DBUS_CREDENTIALS_IFACE, |
532 | DBUS_CREDENTIALS_PATH, |
533 | ) |
534 | |
535 | -# mostly for testing |
536 | -from fake_review_settings import FakeReviewSettings, network_delay |
537 | +from softwarecenter.backend.login import LoginBackend |
538 | +from softwarecenter.utils import utf8 |
539 | |
540 | LOG = logging.getLogger(__name__) |
541 | |
542 | @@ -80,7 +74,7 @@ |
543 | self._credentials = None |
544 | self.proxy.find_credentials(self.appname, self._get_params()) |
545 | |
546 | - def login(self, username=None, password=None): |
547 | + def login(self): |
548 | LOG.debug("login()") |
549 | self._credentials = None |
550 | self.proxy.login(self.appname, self._get_params()) |
551 | @@ -121,78 +115,3 @@ |
552 | return |
553 | self.cancel_login() |
554 | self.emit("login-canceled") |
555 | - |
556 | - |
557 | -class LoginBackendDbusSSOFake(LoginBackend): |
558 | - |
559 | - def __init__(self, window_id, appname, help_text): |
560 | - super(LoginBackendDbusSSOFake, self).__init__() |
561 | - self.appname = appname |
562 | - self.help_text = help_text |
563 | - self._window_id = window_id |
564 | - self._fake_settings = FakeReviewSettings() |
565 | - |
566 | - @network_delay |
567 | - def login(self, username=None, password=None): |
568 | - response = self._fake_settings.get_setting('login_response') |
569 | - |
570 | - if response == "successful": |
571 | - self.emit("login-successful", self._return_credentials()) |
572 | - elif response == "failed": |
573 | - self.emit("login-failed") |
574 | - elif response == "denied": |
575 | - self.cancel_login() |
576 | - |
577 | - return |
578 | - |
579 | - def login_or_register(self): |
580 | - #fake functionality for this is no different to fake login() |
581 | - self.login() |
582 | - return |
583 | - |
584 | - def _random_unicode_string(self, length): |
585 | - retval = '' |
586 | - for i in range(0, length): |
587 | - retval = retval + random.choice(string.letters + string.digits) |
588 | - return retval.decode('utf-8') |
589 | - |
590 | - def _return_credentials(self): |
591 | - c = dbus.Dictionary( |
592 | - { |
593 | - dbus.String(u'consumer_secret'): dbus.String( |
594 | - self._random_unicode_string(30)), |
595 | - dbus.String(u'token'): dbus.String( |
596 | - self._random_unicode_string(50)), |
597 | - dbus.String(u'consumer_key'): dbus.String( |
598 | - self._random_unicode_string(7)), |
599 | - dbus.String(u'name'): dbus.String('Ubuntu Software Center @ ' + |
600 | - self._random_unicode_string(6)), |
601 | - dbus.String(u'token_secret'): dbus.String( |
602 | - self._random_unicode_string(50)) |
603 | - }, |
604 | - signature=dbus.Signature('ss') |
605 | - ) |
606 | - return c |
607 | - |
608 | - |
609 | -def get_sso_backend(window_id, appname, help_text): |
610 | - """ |
611 | - factory that returns an sso loader singelton |
612 | - """ |
613 | - if "SOFTWARE_CENTER_FAKE_REVIEW_API" in os.environ: |
614 | - sso_class = LoginBackendDbusSSOFake(window_id, appname, help_text) |
615 | - LOG.warn('Using fake login SSO functionality. Only meant for ' |
616 | - 'testing purposes') |
617 | - else: |
618 | - sso_class = LoginBackendDbusSSO(window_id, appname, help_text) |
619 | - return sso_class |
620 | - |
621 | -if __name__ == "__main__": |
622 | - logging.basicConfig(level=logging.DEBUG) |
623 | - |
624 | - from softwarecenter.enums import SOFTWARE_CENTER_NAME_KEYRING |
625 | - login = get_sso_backend(0, SOFTWARE_CENTER_NAME_KEYRING, "login-text") |
626 | - login.login() |
627 | - |
628 | - from gi.repository import Gtk |
629 | - Gtk.main() |
630 | |
631 | === modified file 'softwarecenter/backend/oneconfhandler/core.py' |
632 | --- softwarecenter/backend/oneconfhandler/core.py 2012-03-19 21:01:41 +0000 |
633 | +++ softwarecenter/backend/oneconfhandler/core.py 2012-09-14 14:02:22 +0000 |
634 | @@ -20,7 +20,7 @@ |
635 | from oneconf.dbusconnect import DbusConnect |
636 | from oneconf.enums import MIN_TIME_WITHOUT_ACTIVITY |
637 | |
638 | -from softwarecenter.backend.login_sso import get_sso_backend |
639 | +from softwarecenter.backend.login import get_login_backend |
640 | from softwarecenter.backend.ubuntusso import get_ubuntu_sso_backend |
641 | from softwarecenter.enums import SOFTWARE_CENTER_NAME_KEYRING |
642 | |
643 | @@ -167,7 +167,7 @@ |
644 | "their inventories online to compare the software " |
645 | "installed on each\nNo-one else will be able to see " |
646 | "what you have installed.") |
647 | - self.sso = get_sso_backend( |
648 | + self.sso = get_login_backend( |
649 | 0, SOFTWARE_CENTER_NAME_KEYRING, help_text) |
650 | self.sso.connect("login-successful", self._maybe_login_successful) |
651 | self.sso.connect("login-canceled", self._login_canceled) |
652 | |
653 | === modified file 'softwarecenter/backend/ubuntusso.py' |
654 | --- softwarecenter/backend/ubuntusso.py 2012-09-14 14:02:22 +0000 |
655 | +++ softwarecenter/backend/ubuntusso.py 2012-09-14 14:02:22 +0000 |
656 | @@ -36,7 +36,7 @@ |
657 | from fake_review_settings import FakeReviewSettings, network_delay |
658 | from spawn_helper import SpawnHelper |
659 | from softwarecenter.config import get_config |
660 | -from softwarecenter.backend.login_sso import get_sso_backend |
661 | +from softwarecenter.backend.login import get_login_backend |
662 | |
663 | from softwarecenter.backend.piston.ubuntusso_pristine import ( |
664 | UbuntuSsoAPI as PristineUbuntuSsoAPI, |
665 | @@ -123,8 +123,8 @@ |
666 | def clear_token(self): |
667 | clear_token_from_ubuntu_sso_sync(SOFTWARE_CENTER_NAME_KEYRING) |
668 | |
669 | - def _get_sso_backend_and_connect(self): |
670 | - sso = get_sso_backend( |
671 | + def _get_login_backend_and_connect(self): |
672 | + sso = get_login_backend( |
673 | self.xid, |
674 | SOFTWARE_CENTER_NAME_KEYRING, |
675 | _(SOFTWARE_CENTER_SSO_DESCRIPTION)) |
676 | @@ -135,14 +135,14 @@ |
677 | |
678 | def find_oauth_token_sync(self): |
679 | self.oauth = None |
680 | - sso = self. _get_sso_backend_and_connect() |
681 | + sso = self. _get_login_backend_and_connect() |
682 | sso.find_credentials() |
683 | self.loop.run() |
684 | return self.oauth |
685 | |
686 | def get_oauth_token_sync(self): |
687 | self.oauth = None |
688 | - sso = self. _get_sso_backend_and_connect() |
689 | + sso = self. _get_login_backend_and_connect() |
690 | sso.login_or_register() |
691 | self.loop.run() |
692 | return self.oauth |
693 | @@ -252,7 +252,7 @@ |
694 | logging.basicConfig(level=logging.DEBUG) |
695 | softwarecenter.paths.datadir = "./data" |
696 | |
697 | - backend = get_sso_backend("", "appname", "help_text") |
698 | + backend = get_login_backend("", "appname", "help_text") |
699 | backend.connect("login-successful", _dbus_maybe_login_successful) |
700 | backend.login_or_register() |
701 | Gtk.main() |
702 | |
703 | === modified file 'softwarecenter/ui/gtk3/app.py' |
704 | --- softwarecenter/ui/gtk3/app.py 2012-09-14 14:02:22 +0000 |
705 | +++ softwarecenter/ui/gtk3/app.py 2012-09-14 14:02:22 +0000 |
706 | @@ -121,7 +121,7 @@ |
707 | |
708 | from softwarecenter.config import get_config |
709 | from softwarecenter.backend import get_install_backend |
710 | -from softwarecenter.backend.login_sso import get_sso_backend |
711 | +from softwarecenter.backend.login import get_login_backend |
712 | from softwarecenter.backend.recagent import RecommenderAgent |
713 | |
714 | from softwarecenter.backend.channel import AllInstalledChannel |
715 | @@ -625,9 +625,6 @@ |
716 | if Gtk.main_level() == 0: |
717 | LOG.info("closing before the regular main loop was run") |
718 | sys.exit(0) |
719 | - # this is the case when it regularly runs |
720 | - if hasattr(self, "glaunchpad"): |
721 | - self.glaunchpad.shutdown() |
722 | self.save_state() |
723 | self.destroy() |
724 | |
725 | @@ -737,13 +734,6 @@ |
726 | if self.menuitem_go_forward.get_sensitive(): |
727 | self.menuitem_go_forward.activate() |
728 | |
729 | - def _on_lp_login(self, lp, token): |
730 | - self._lp_login_successful = True |
731 | - private_archives = self.glaunchpad.get_subscribed_archives() |
732 | - channel_manager = self.view_switcher.get_model().channel_manager |
733 | - channel_manager.feed_in_private_sources_list_entries( |
734 | - private_archives) |
735 | - |
736 | def _on_style_updated(self, widget, init_css_callback, *args): |
737 | init_css_callback(widget, *args) |
738 | |
739 | @@ -819,14 +809,6 @@ |
740 | # return False to ensure that a possible GObject.timeout_add ends |
741 | return False |
742 | |
743 | - def on_menuitem_launchpad_private_ppas_activate(self, menuitem): |
744 | - from backend.launchpad import GLaunchpad |
745 | - self.glaunchpad = GLaunchpad() |
746 | - self.glaunchpad.connect("login-successful", self._on_lp_login) |
747 | - from view.logindialog import LoginDialog |
748 | - d = LoginDialog(self.glaunchpad, self.datadir, parent=self.window_main) |
749 | - d.login() |
750 | - |
751 | def _on_reinstall_purchased_login(self, sso, oauth_result): |
752 | self._sso_login_successful = True |
753 | # appmanager needs to know about the oauth token for the reinstall |
754 | @@ -870,7 +852,7 @@ |
755 | #window = self.window_main.get_window() |
756 | #xid = self.get_window().xid |
757 | xid = 0 |
758 | - self.sso = get_sso_backend(xid, appname, help_text) |
759 | + self.sso = get_login_backend(xid, appname, help_text) |
760 | self.sso.connect( |
761 | "login-successful", self._on_reinstall_purchased_login) |
762 | self.sso.login() |
763 | |
764 | === modified file 'softwarecenter/ui/gtk3/review_gui_helper.py' |
765 | --- softwarecenter/ui/gtk3/review_gui_helper.py 2012-08-07 10:19:55 +0000 |
766 | +++ softwarecenter/ui/gtk3/review_gui_helper.py 2012-09-14 14:02:22 +0000 |
767 | @@ -51,7 +51,7 @@ |
768 | from softwarecenter.enums import Icons, SOFTWARE_CENTER_NAME_KEYRING |
769 | from softwarecenter.config import get_config |
770 | from softwarecenter.distro import get_distro, get_current_arch |
771 | -from softwarecenter.backend.login_sso import get_sso_backend |
772 | +from softwarecenter.backend.login import get_login_backend |
773 | from softwarecenter.backend.reviews import Review |
774 | from softwarecenter.db.database import Application |
775 | from softwarecenter.gwibber_helper import GwibberHelper, GwibberHelperMock |
776 | @@ -449,7 +449,7 @@ |
777 | login_window_xid = self._get_parent_xid_for_login_window() |
778 | help_text = _("To review software or to report abuse you need to " |
779 | "sign in to a Ubuntu Single Sign-On account.") |
780 | - self.sso = get_sso_backend(login_window_xid, |
781 | + self.sso = get_login_backend(login_window_xid, |
782 | SOFTWARE_CENTER_NAME_KEYRING, help_text) |
783 | self.sso.connect("login-successful", self._maybe_login_successful) |
784 | self.sso.connect("login-canceled", self._login_canceled) |
785 | |
786 | === modified file 'softwarecenter/ui/gtk3/widgets/recommendations.py' |
787 | --- softwarecenter/ui/gtk3/widgets/recommendations.py 2012-09-11 14:44:17 +0000 |
788 | +++ softwarecenter/ui/gtk3/widgets/recommendations.py 2012-09-14 14:02:22 +0000 |
789 | @@ -30,7 +30,7 @@ |
790 | AppRecommendationsCategory) |
791 | from softwarecenter.backend import get_install_backend |
792 | from softwarecenter.backend.recagent import RecommenderAgent |
793 | -from softwarecenter.backend.login_sso import get_sso_backend |
794 | +from softwarecenter.backend.login import get_login_backend |
795 | from softwarecenter.backend.ubuntusso import get_ubuntu_sso_backend |
796 | from softwarecenter.enums import ( |
797 | LOBBY_RECOMMENDATIONS_CAROUSEL_LIMIT, |
798 | @@ -316,7 +316,7 @@ |
799 | # we simply reuse the opt-in text from the panel since we |
800 | # are well past string freeze |
801 | self.spinner_notebook.show_spinner() |
802 | - self.sso = get_sso_backend(get_parent_xid(self), |
803 | + self.sso = get_login_backend(get_parent_xid(self), |
804 | SOFTWARE_CENTER_NAME_KEYRING, |
805 | self.RECOMMENDATIONS_OPT_IN_TEXT) |
806 | self.sso.connect("login-successful", self._maybe_login_successful) |
807 | |
808 | === removed file 'tests/disabled_test_launchpad.py' |
809 | --- tests/disabled_test_launchpad.py 2012-08-14 15:10:19 +0000 |
810 | +++ tests/disabled_test_launchpad.py 1970-01-01 00:00:00 +0000 |
811 | @@ -1,36 +0,0 @@ |
812 | -import unittest |
813 | - |
814 | -from tests.utils import ( |
815 | - do_events, |
816 | - setup_test_env, |
817 | -) |
818 | -setup_test_env() |
819 | -from softwarecenter.backend.launchpad import GLaunchpad |
820 | - |
821 | - |
822 | -class TestUbuntuSSO(unittest.TestCase): |
823 | - |
824 | - def _cb_login_successful(self, lp, token): |
825 | - self._login_successful = True |
826 | - |
827 | - def test_launchpad_login(self): |
828 | - lp = GLaunchpad() |
829 | - lp.connect("login-successful", self._cb_login_successful) |
830 | - # monkey patch |
831 | - lp.login = lambda u,p: True |
832 | - lp.login("user", "password") |
833 | - lp.emit("login-successful", None) |
834 | - do_events() |
835 | - self.assertTrue(self._login_successful) |
836 | - |
837 | - def _monkey_get_subscribed_archives(self): |
838 | - return ["deb http://foo:pw@launchpad.net/ main"] |
839 | - |
840 | - def test_launchpad_get_subscribed_archives(self): |
841 | - lp = GLaunchpad() |
842 | - lp.get_subscribed_archives = self._monkey_get_subscribed_archives |
843 | - archives = lp.get_subscribed_archives() |
844 | - self.assertEqual(archives, ["deb http://foo:pw@launchpad.net/ main"]) |
845 | - |
846 | -if __name__ == "__main__": |
847 | - unittest.main() |
848 | |
849 | === modified file 'tests/gtk3/test_catview.py' |
850 | --- tests/gtk3/test_catview.py 2012-09-11 14:33:50 +0000 |
851 | +++ tests/gtk3/test_catview.py 2012-09-14 14:02:22 +0000 |
852 | @@ -116,7 +116,7 @@ |
853 | |
854 | # we need to use a custom setUp method for the recommendations test cases |
855 | # so that everything gets configured properly |
856 | - @patch('softwarecenter.ui.gtk3.widgets.recommendations.get_sso_backend') |
857 | + @patch('softwarecenter.ui.gtk3.widgets.recommendations.get_login_backend') |
858 | @patch('softwarecenter.ui.gtk3.widgets.recommendations.RecommenderAgent' |
859 | '.is_opted_in') |
860 | # patch out the agent query method to avoid making the actual server call |
861 | |
862 | === modified file 'tests/test_login_backend.py' |
863 | --- tests/test_login_backend.py 2012-05-30 18:39:55 +0000 |
864 | +++ tests/test_login_backend.py 2012-09-14 14:02:22 +0000 |
865 | @@ -5,9 +5,13 @@ |
866 | setup_test_env, |
867 | ) |
868 | setup_test_env() |
869 | -from softwarecenter.backend.login_sso import (get_sso_backend, |
870 | - LoginBackendDbusSSO, |
871 | - LoginBackendDbusSSOFake) |
872 | +from softwarecenter.backend.login import get_login_backend |
873 | +from softwarecenter.backend.login_impl.login_sso import ( |
874 | + LoginBackendDbusSSO) |
875 | +from softwarecenter.backend.login_impl.login_fake import ( |
876 | + LoginBackendDbusSSOFake, |
877 | + ) |
878 | + |
879 | |
880 | class TestLoginBackend(unittest.TestCase): |
881 | """ tests the login backend stuff """ |
882 | @@ -21,13 +25,13 @@ |
883 | set([x for x in dir(login_real) if not x.startswith("_")]), |
884 | set([x for x in dir(login_fake) if not x.startswith("_")])) |
885 | |
886 | - def test_get_sso_backend(self): |
887 | + def test_get_login_backend(self): |
888 | # test that we get the real one |
889 | - self.assertEqual(type(get_sso_backend(None, None, None)), |
890 | + self.assertEqual(type(get_login_backend(None, None, None)), |
891 | LoginBackendDbusSSO) |
892 | # test that we get the fake one |
893 | os.environ["SOFTWARE_CENTER_FAKE_REVIEW_API"] = "1" |
894 | - self.assertEqual(type(get_sso_backend(None, None, None)), |
895 | + self.assertEqual(type(get_login_backend(None, None, None)), |
896 | LoginBackendDbusSSOFake) |
897 | # clean the environment |
898 | del os.environ["SOFTWARE_CENTER_FAKE_REVIEW_API"] |
Should just be rename/reshuffle but still a careful look will be good.