Merge lp:~leonardr/launchpadlib/improve-workflow into lp:launchpadlib
Status: | Merged |
---|---|
Approved by: | Martin Pool |
Approved revision: | 97 |
Merged at revision: | 93 |
Proposed branch: | lp:~leonardr/launchpadlib/improve-workflow |
Merge into: | lp:launchpadlib |
Diff against target: |
268 lines (+68/-32) 4 files modified
src/launchpadlib/NEWS.txt (+9/-0) src/launchpadlib/credentials.py (+36/-13) src/launchpadlib/launchpad.py (+12/-8) src/launchpadlib/tests/test_launchpad.py (+11/-11) |
To merge this branch: | bzr merge lp:~leonardr/launchpadlib/improve-workflow |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Pool (community) | Approve | ||
Review via email: mp+29849@code.launchpad.net |
Description of the change
This branch improves the console-based workflow for exchanging a request token for an access token.
Here's the old workflow:
1. Tab into your browser app.
2. Authorize (or don't) the launchpadlib app.
3. Tab into the console.
4. Hit Enter.
My original plan was to eliminate all but step 2. If I could somehow do this, the current launchpadlib workflow would be more or less the same as the proposed expensive workflow involving a custom desktop application and a brand new OAuth access level.
Unfortunately, a combination of problems with the webbrowser module/Firefox/the standard Ubuntu window manager foiled my plan to eliminate step 1, and Javascript security issues foiled my plan to eliminate step 3.
But, I was able to eliminate step 4, with a minor change to Launchpad (https:/
Since it's now possible to distinguish "I don't want you to have access to my Launchpad account" from "I haven't made a decision about giving you access", I took the opportunity to improve launchpadlib's behavior when access is denied. Previously launchpadlib just raised an unhelpful HTTPError. Now it ensures that login_with() and the like return None instead of a Launchpad object. When you call login_with(), you can check the return value and know that if it's None, the user made a decision not to give you access--you can sys.exit() or complain or whatever.
Bonus: since the console-based workflow no longer reads from stdin, it should be now possible to use it from a GUI application.
Since this branch only works on a version of Launchpad that has my branch installed, I won't be releasing a version of launchpadlib that includes this branch until my Launchpad branch is fully deployed.
Nice cover letter.
> Since it's now possible to distinguish "I don't want you to have access to my Launchpad account" from "I haven't made a decision about giving you access", I took the opportunity to improve launchpadlib's behavior when access is denied. Previously launchpadlib just raised an unhelpful HTTPError. Now it ensures that login_with() and the like return None instead of a Launchpad object. When you call login_with(), you can check the return value and know that if it's None, the user made a decision not to give you access--you can sys.exit() or complain or whatever.
This of course needs to go into the docs and I would say ideally to get a brief post on the blog (even just a pointer to this mp.)
I think you should raise a specific exception if the user denies access, rather than returning None:
1- If the app ignores the return code, we don't want it to just blithely continue and then cause knock-on errors. The default should be for the app to stop.
2- Returning None for errors is just bad.
3- It gives you a space to eventually possibly pass back a sensible message. (I mean I doubt the user wants to explain why, but perhaps you can also in the future say "this app is banned" or "you're creating too many tokens" etc.) I would say you should probably put the error body in to the exception, even if at the moment it's not super helpful.
+ print " (%s)" % self.authorizat ion_url
+ print "should be opening in your browser. Use your browser to"
+ print "to authorize this program to access Launchpad on your behalf."
It would be nice to not directly print but rather pass this to a callback function so guis can hook it. It could be a followon but perhaps you could just hoist it out while you're here.
- launchpad. credentials. save_to_ path(consumer_ credentials_ path) consumer_ credentials_ path, stat.S_IREAD | stat.S_IWRITE) credentials. save_to_ path(consumer_ credentials_ path) credentials_ path, stat.S_IREAD | stat.S_IWRITE)
- os.chmod(
+ if launchpad is not None:
+ launchpad.
+ os.chmod(
+ consumer_
It's always much more secure to create the path secure (by passing a third parameter to os.open) than to chmod it later: the app may be interrupted, someone may grab it in the race window, etc.
Otherwise looks good.