Merge lp:~leonardr/launchpadlib/bug-712808 into lp:launchpadlib

Proposed by Leonard Richardson
Status: Merged
Approved by: Graham Binns
Approved revision: 115
Merged at revision: 113
Proposed branch: lp:~leonardr/launchpadlib/bug-712808
Merge into: lp:launchpadlib
Diff against target: 131 lines (+42/-37)
3 files modified
src/launchpadlib/NEWS.txt (+7/-0)
src/launchpadlib/__init__.py (+1/-1)
src/launchpadlib/launchpad.py (+34/-36)
To merge this branch: bzr merge lp:~leonardr/launchpadlib/bug-712808
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+48830@code.launchpad.net

Description of the change

This branch fixes bug 712808 by changing launchpadlib's behavior when consumer_name is specified as a string. The previous behavior was to treat consumer_name as an OAuth consumer, but to try to do a desktop-wide integration. This is internally inconsistent--either the "consumer_name" should be treated as an application name and we should perform a desktop-wide integration, or we should try to do an application-specific integration. Since we've already decided to do desktop-wide integration in ordinary cases, I chose to treat a string consumer_name as the application name for a desktop-wide credential.

This code can't be tested normally, but it's easy to test manually, by running this code when you have no active credential on staging.launchpad.net:

Launchpad.get_token_and_login("my-app")

To post a comment you must log in.
lp:~leonardr/launchpadlib/bug-712808 updated
114. By Leonard Richardson

Moved the code to check the credential store into _authorize_token_and_login, so that it's used by all code paths.

Revision history for this message
Leonard Richardson (leonardr) wrote :

I noticed another problem: get_token_and_login() works, and it stores credentials in the keyring, but it doesn't _read_ credentials from the keyring the second time you run the code, because the code to look in the keyring was in login_with(). I moved that code to _authorize_token_and_login, which is called by all code paths, and now get_token_and_login() works just as well as login_with().

lp:~leonardr/launchpadlib/bug-712808 updated
115. By Leonard Richardson

Don't overwrite the credentials variable after going through so much trouble to create it.

Revision history for this message
Graham Binns (gmb) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/launchpadlib/NEWS.txt'
2--- src/launchpadlib/NEWS.txt 2011-01-18 21:57:09 +0000
3+++ src/launchpadlib/NEWS.txt 2011-02-07 20:13:43 +0000
4@@ -2,6 +2,13 @@
5 NEWS for launchpadlib
6 =====================
7
8+1.9.5 (2010-02-07)
9+==================
10+
11+- Fixed a bug that prevented the deprecated get_token_and_login code
12+ from working, and required that users of get_token_and_login get a
13+ new token on every usage.
14+
15 1.9.4 (2010-01-18)
16 ==================
17
18
19=== modified file 'src/launchpadlib/__init__.py'
20--- src/launchpadlib/__init__.py 2011-01-18 22:33:53 +0000
21+++ src/launchpadlib/__init__.py 2011-02-07 20:13:43 +0000
22@@ -14,4 +14,4 @@
23 # You should have received a copy of the GNU Lesser General Public License
24 # along with launchpadlib. If not, see <http://www.gnu.org/licenses/>.
25
26-__version__ = '1.9.4'
27+__version__ = '1.9.5'
28
29=== modified file 'src/launchpadlib/launchpad.py'
30--- src/launchpadlib/launchpad.py 2011-01-18 21:57:09 +0000
31+++ src/launchpadlib/launchpad.py 2011-02-07 20:13:43 +0000
32@@ -31,6 +31,7 @@
33 ScalarValue, # Re-import for client convenience
34 ServiceRoot,
35 )
36+from lazr.restfulclient.authorize.oauth import SystemWideConsumer
37 from lazr.restfulclient._browser import RestfulHttp
38 from launchpadlib.credentials import (
39 AccessToken,
40@@ -309,16 +310,18 @@
41 get_token_and_login() is removed, this code can be streamlined
42 and moved into its other call site, login_with().
43 """
44-
45 if isinstance(consumer_name, Consumer):
46- # Create the credentials with no Consumer, then set its .consumer
47- # property directly.
48- credentials = Credentials(None)
49- credentials.consumer = consumer_name
50+ consumer = consumer_name
51 else:
52- # Have the Credentials constructor create the Consumer
53- # automatically.
54- credentials = Credentials(consumer_name)
55+ # Create a system-wide consumer. lazr.restfulclient won't
56+ # do this automatically, but launchpadlib's default is to
57+ # do a desktop-wide integration.
58+ consumer = SystemWideConsumer(consumer_name)
59+
60+ # Create the credentials with no Consumer, then set its .consumer
61+ # property directly.
62+ credentials = Credentials(None)
63+ credentials.consumer = consumer
64 if authorization_engine is None:
65 authorization_engine = cls.authorization_engine_factory(
66 service_root, consumer_name, None, allow_access_levels)
67@@ -335,7 +338,24 @@
68 credential_store.credential_save_failed,
69 "credential_store")
70
71- credentials = authorization_engine(credentials, credential_store)
72+ # Try to get the credentials out of the credential store.
73+ cached_credentials = credential_store.load(
74+ authorization_engine.unique_consumer_id)
75+ if cached_credentials is None:
76+ # They're not there. Acquire new credentials using the
77+ # authorization engine.
78+ credentials = authorization_engine(credentials, credential_store)
79+ else:
80+ # We acquired credentials. But, the application name
81+ # wasn't stored along with the credentials, because in a
82+ # desktop integration scenario, a single set of
83+ # credentials may be shared by many applications. We need
84+ # to set the application name for this specific instance
85+ # of the credentials.
86+ credentials = cached_credentials
87+ credentials.consumer.application_name = (
88+ authorization_engine.application_name)
89+
90 return cls(credentials, authorization_engine, credential_store,
91 service_root, cache, timeout, proxy_info, version)
92
93@@ -513,33 +533,11 @@
94 "allow_access_levels", allow_access_levels,
95 authorization_engine.allow_access_levels)
96
97- credentials = credential_store.load(
98- authorization_engine.unique_consumer_id)
99-
100- if credentials is None:
101- # Credentials were not found in the local store. Go
102- # through the authorization process.
103- launchpad = cls._authorize_token_and_login(
104- authorization_engine.consumer, service_root,
105- cache_path, timeout, proxy_info, authorization_engine,
106- allow_access_levels, credential_store,
107- credential_save_failed, version)
108- else:
109- # The application name wasn't stored locally, because in a
110- # desktop integration scenario, a single set of
111- # credentials may be shared by many applications. We need
112- # to set the application name for this specific instance
113- # of the credentials.
114- credentials.consumer.application_name = (
115- authorization_engine.application_name)
116-
117- # Credentials were found in the local store. Create a
118- # Launchpad object.
119- launchpad = cls(
120- credentials, authorization_engine, credential_store,
121- service_root=service_root, cache=cache_path, timeout=timeout,
122- proxy_info=proxy_info, version=version)
123- return launchpad
124+ return cls._authorize_token_and_login(
125+ authorization_engine.consumer, service_root,
126+ cache_path, timeout, proxy_info, authorization_engine,
127+ allow_access_levels, credential_store,
128+ credential_save_failed, version)
129
130 @classmethod
131 def _warn_of_deprecated_login_method(cls, name):

Subscribers

People subscribed via source and target branches