Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(560)

Unified Diff: utils/pub/oauth2.dart

Issue 11348268: Don't require users to copy-paste authorization codes when authorizing pub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | utils/pub/utils.dart » ('j') | utils/pub/utils.dart » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/pub/oauth2.dart
diff --git a/utils/pub/oauth2.dart b/utils/pub/oauth2.dart
index 60213a9341efe505e7536950af9047b7e10509b1..8e9e25655568938679c7acb26712cd3fbc874e99 100644
--- a/utils/pub/oauth2.dart
+++ b/utils/pub/oauth2.dart
@@ -78,40 +78,10 @@ Future withClient(SystemCache cache, Future fn(Client client)) {
/// Gets a new OAuth2 client. If saved credentials are available, those are
/// used; otherwise, the user is prompted to authorize the pub client.
Future<Client> _getClient(SystemCache cache) {
- var httpClient = new CurlClient();
-
return _loadCredentials(cache).chain((credentials) {
- if (credentials != null) {
- return new Future.immediate(new Client(
- _identifier, _secret, credentials, httpClient: httpClient));
- }
-
- // Allow the tests to inject their own token endpoint URL.
- var tokenEndpoint = Platform.environment['_PUB_TEST_TOKEN_ENDPOINT'];
- if (tokenEndpoint != null) {
- tokenEndpoint = new Uri.fromString(tokenEndpoint);
- } else {
- tokenEndpoint = _tokenEndpoint;
- }
-
- var grant = new AuthorizationCodeGrant(
- _identifier,
- _secret,
- _authorizationEndpoint,
- tokenEndpoint,
- httpClient: httpClient);
-
- // TODO(nweiz): spin up a server on localhost and redirect the user there so
- // they don't have to copy/paste the authorization code. See issue 6951.
- var authUrl = grant.getAuthorizationUrl(
- new Uri.fromString('urn:ietf:wg:oauth:2.0:oob'), scopes: _scopes);
-
- stdout.writeString(
- 'Pub needs your authorization to upload packages on your behalf.\n'
- 'Go to $authUrl\n'
- 'Then click "Allow access" and paste the code below:\n'
- '> ');
- return readLine().chain(grant.handleAuthorizationCode);
+ if (credentials == null) return _authorize();
+ return new Future.immediate(new Client(
Bob Nystrom 2012/11/28 19:35:41 Can't wait until Future unifies chain/transform...
nweiz 2012/11/28 19:42:14 Indeed.
+ _identifier, _secret, credentials, httpClient: new CurlClient()));
}).chain((client) {
return _saveCredentials(cache, client.credentials).transform((_) => client);
});
@@ -155,3 +125,54 @@ Future _saveCredentials(SystemCache cache, Credentials credentials) {
/// The path to the file in which the user's OAuth2 credentials are stored.
String _credentialsFile(SystemCache cache) =>
join(cache.rootDir, 'credentials.json');
+
+/// Gets the user to authorize pub as a client of pub.dartlang.org via oauth2.
+/// Returns a Future that will complete to a fully-authorized [Client].
+Future<Client> _authorize() {
+ // Allow the tests to inject their own token endpoint URL.
+ var tokenEndpoint = Platform.environment['_PUB_TEST_TOKEN_ENDPOINT'];
+ if (tokenEndpoint != null) {
+ tokenEndpoint = new Uri.fromString(tokenEndpoint);
+ } else {
+ tokenEndpoint = _tokenEndpoint;
+ }
+
+ var grant = new AuthorizationCodeGrant(
+ _identifier,
+ _secret,
+ _authorizationEndpoint,
+ tokenEndpoint,
+ httpClient: new CurlClient());
+
+ // Spin up a one-shot HTTP server to receive the authorization code from the
+ // Google OAuth2 server via redirect. This server will close itself as soon as
+ // the code is received.
+ var completer = new Completer();
+ var server = new HttpServer();
+ server.addRequestHandler((request) => request.path == "/", (request, response) {
Bob Nystrom 2012/11/28 19:35:41 Long line.
nweiz 2012/11/28 19:42:14 Done.
+ chainToCompleter(new Future.immediate(null).chain((_) {
+ print('Authorization received, processing...');
+ var queryString = request.queryString;
+ if (queryString == null) queryString = '';
+ response.statusCode = 302;
+ response.headers.set('location', 'http://pub.dartlang.org/authorized');
+ response.outputStream.close();
+ server.close();
+ return grant.handleAuthorizationResponse(queryToMap(queryString));
+ }), completer);
+ });
+ server.listen('127.0.0.1', 0);
+
+ var authUrl = grant.getAuthorizationUrl(
+ new Uri.fromString('http://localhost:${server.port}'), scopes: _scopes);
+
+ print('Pub needs your authorization to upload packages on your behalf.\n'
+ 'Go to $authUrl\n'
Bob Nystrom 2012/11/28 19:35:41 "In a web browser, go to"?
nweiz 2012/11/28 19:42:14 Done.
+ 'Then click "Allow access".\n\n'
+ 'Waiting for your authorization...');
+
+ return completer.future.transform((client) {
+ print('Successfully authorized.\n');
+ return client;
+ });
+}
« no previous file with comments | « no previous file | utils/pub/utils.dart » ('j') | utils/pub/utils.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698