OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library oauth2; | 5 library oauth2; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'dart:uri'; | 8 import 'dart:uri'; |
9 | 9 |
10 // TODO(nweiz): Make this a "package:" URL, or something nicer than this. | 10 // TODO(nweiz): Make this a "package:" URL, or something nicer than this. |
11 import '../../pkg/oauth2/lib/oauth2.dart'; | 11 import '../../pkg/oauth2/lib/oauth2.dart'; |
12 import 'io.dart'; | 12 import 'io.dart'; |
13 import 'log.dart' as log; | |
13 import 'system_cache.dart'; | 14 import 'system_cache.dart'; |
14 import 'utils.dart'; | 15 import 'utils.dart'; |
15 | 16 |
16 export '../../pkg/oauth2/lib/oauth2.dart'; | 17 export '../../pkg/oauth2/lib/oauth2.dart'; |
17 | 18 |
18 /// The pub client's OAuth2 identifier. | 19 /// The pub client's OAuth2 identifier. |
19 final _identifier = '818368855108-8grd2eg9tj9f38os6f1urbcvsq399u8n.apps.' | 20 final _identifier = '818368855108-8grd2eg9tj9f38os6f1urbcvsq399u8n.apps.' |
20 'googleusercontent.com'; | 21 'googleusercontent.com'; |
21 | 22 |
22 /// The pub client's OAuth2 secret. This isn't actually meant to be kept a | 23 /// The pub client's OAuth2 secret. This isn't actually meant to be kept a |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 _identifier, _secret, credentials, httpClient: curlClient)); | 84 _identifier, _secret, credentials, httpClient: curlClient)); |
84 }).chain((client) { | 85 }).chain((client) { |
85 return _saveCredentials(cache, client.credentials).transform((_) => client); | 86 return _saveCredentials(cache, client.credentials).transform((_) => client); |
86 }); | 87 }); |
87 } | 88 } |
88 | 89 |
89 /// Loads the user's OAuth2 credentials from the in-memory cache or the | 90 /// Loads the user's OAuth2 credentials from the in-memory cache or the |
90 /// filesystem if possible. If the credentials can't be loaded for any reason, | 91 /// filesystem if possible. If the credentials can't be loaded for any reason, |
91 /// the returned [Future] will complete to null. | 92 /// the returned [Future] will complete to null. |
92 Future<Credentials> _loadCredentials(SystemCache cache) { | 93 Future<Credentials> _loadCredentials(SystemCache cache) { |
94 var path = _credentialsFile(cache); | |
95 log.fine('Loading OAuth2 credentials from $path.'); | |
nweiz
2012/12/05 23:56:54
"from $path" is redundant, and also false if _cred
Bob Nystrom
2012/12/06 01:33:26
Done.
| |
93 if (_credentials != null) return new Future.immediate(_credentials); | 96 if (_credentials != null) return new Future.immediate(_credentials); |
94 return fileExists(_credentialsFile(cache)).chain((credentialsExist) { | 97 return fileExists(path).chain((credentialsExist) { |
95 if (!credentialsExist) return new Future.immediate(null); | 98 if (!credentialsExist) { |
99 log.fine('No credentials found at $path.'); | |
nweiz
2012/12/05 23:56:54
I wouldn't include most of these fine log statemen
Bob Nystrom
2012/12/06 01:33:26
Done.
| |
100 return new Future.immediate(null); | |
101 } | |
96 | 102 |
103 log.fine('Found credentials at $path.'); | |
97 return readTextFile(_credentialsFile(cache)).transform((credentialsJson) { | 104 return readTextFile(_credentialsFile(cache)).transform((credentialsJson) { |
105 log.fine('Read credentials file.'); | |
98 var credentials = new Credentials.fromJson(credentialsJson); | 106 var credentials = new Credentials.fromJson(credentialsJson); |
99 if (credentials.isExpired && !credentials.canRefresh) { | 107 if (credentials.isExpired && !credentials.canRefresh) { |
100 printError("Pub's authorization to upload packages has expired and " | 108 log.error("Pub's authorization to upload packages has expired and " |
101 "can't be automatically refreshed."); | 109 "can't be automatically refreshed."); |
102 return null; // null means re-authorize | 110 return null; // null means re-authorize |
103 } | 111 } |
104 | 112 |
105 return credentials; | 113 return credentials; |
106 }); | 114 }); |
107 }).transformException((e) { | 115 }).transformException((e) { |
108 printError('Warning: could not load the saved OAuth2 credentials:' | 116 log.error('Warning: could not load the saved OAuth2 credentials: $e\n' |
109 ' $e\n' | |
110 'Obtaining new credentials...'); | 117 'Obtaining new credentials...'); |
111 return null; // null means re-authorize | 118 return null; // null means re-authorize |
112 }); | 119 }); |
113 } | 120 } |
114 | 121 |
115 /// Save the user's OAuth2 credentials to the in-memory cache and the | 122 /// Save the user's OAuth2 credentials to the in-memory cache and the |
116 /// filesystem. | 123 /// filesystem. |
117 Future _saveCredentials(SystemCache cache, Credentials credentials) { | 124 Future _saveCredentials(SystemCache cache, Credentials credentials) { |
118 _credentials = credentials; | 125 _credentials = credentials; |
119 var credentialsFile = _credentialsFile(cache); | 126 var path = _credentialsFile(cache); |
120 return ensureDir(dirname(credentialsFile)).chain((_) => | 127 log.fine('Saving OAuth2 credentials to $path.'); |
nweiz
2012/12/05 23:56:54
"to $path" is redundant.
Bob Nystrom
2012/12/06 01:33:26
Done.
| |
121 writeTextFile(credentialsFile, credentials.toJson())); | 128 return ensureDir(dirname(path)).chain((_) => |
129 writeTextFile(path, credentials.toJson())); | |
122 } | 130 } |
123 | 131 |
124 /// The path to the file in which the user's OAuth2 credentials are stored. | 132 /// The path to the file in which the user's OAuth2 credentials are stored. |
125 String _credentialsFile(SystemCache cache) => | 133 String _credentialsFile(SystemCache cache) => |
126 join(cache.rootDir, 'credentials.json'); | 134 join(cache.rootDir, 'credentials.json'); |
127 | 135 |
128 /// Gets the user to authorize pub as a client of pub.dartlang.org via oauth2. | 136 /// Gets the user to authorize pub as a client of pub.dartlang.org via oauth2. |
129 /// Returns a Future that will complete to a fully-authorized [Client]. | 137 /// Returns a Future that will complete to a fully-authorized [Client]. |
130 Future<Client> _authorize() { | 138 Future<Client> _authorize() { |
131 // Allow the tests to inject their own token endpoint URL. | 139 // Allow the tests to inject their own token endpoint URL. |
(...skipping 12 matching lines...) Expand all Loading... | |
144 httpClient: curlClient); | 152 httpClient: curlClient); |
145 | 153 |
146 // Spin up a one-shot HTTP server to receive the authorization code from the | 154 // Spin up a one-shot HTTP server to receive the authorization code from the |
147 // Google OAuth2 server via redirect. This server will close itself as soon as | 155 // Google OAuth2 server via redirect. This server will close itself as soon as |
148 // the code is received. | 156 // the code is received. |
149 var completer = new Completer(); | 157 var completer = new Completer(); |
150 var server = new HttpServer(); | 158 var server = new HttpServer(); |
151 server.addRequestHandler((request) => request.path == "/", | 159 server.addRequestHandler((request) => request.path == "/", |
152 (request, response) { | 160 (request, response) { |
153 chainToCompleter(new Future.immediate(null).chain((_) { | 161 chainToCompleter(new Future.immediate(null).chain((_) { |
154 print('Authorization received, processing...'); | 162 log.message('Authorization received, processing...'); |
155 var queryString = request.queryString; | 163 var queryString = request.queryString; |
156 if (queryString == null) queryString = ''; | 164 if (queryString == null) queryString = ''; |
157 response.statusCode = 302; | 165 response.statusCode = 302; |
158 response.headers.set('location', 'http://pub.dartlang.org/authorized'); | 166 response.headers.set('location', 'http://pub.dartlang.org/authorized'); |
159 return Futures.wait([ | 167 return Futures.wait([ |
160 closeHttpResponse(request, response), | 168 closeHttpResponse(request, response), |
161 grant.handleAuthorizationResponse(queryToMap(queryString)) | 169 grant.handleAuthorizationResponse(queryToMap(queryString)) |
162 ]); | 170 ]); |
163 }).transform((results) { | 171 }).transform((results) { |
164 server.close(); | 172 server.close(); |
165 return results[1]; | 173 return results[1]; |
166 }), completer); | 174 }), completer); |
167 }); | 175 }); |
168 server.listen('127.0.0.1', 0); | 176 server.listen('127.0.0.1', 0); |
169 | 177 |
170 var authUrl = grant.getAuthorizationUrl( | 178 var authUrl = grant.getAuthorizationUrl( |
171 new Uri.fromString('http://localhost:${server.port}'), scopes: _scopes); | 179 new Uri.fromString('http://localhost:${server.port}'), scopes: _scopes); |
172 | 180 |
173 print('Pub needs your authorization to upload packages on your behalf.\n' | 181 log.message( |
nweiz
2012/12/05 23:56:54
Unlike print(), passing multiline strings to log.m
Bob Nystrom
2012/12/06 01:33:26
It's equivalent in normal verbosity, I think. In v
nweiz
2012/12/06 19:40:02
There are other places where multiple lines get pr
Bob Nystrom
2012/12/07 21:13:44
Per our discussion, this way is the new hotness si
| |
174 'In a web browser, go to $authUrl\n' | 182 'Pub needs your authorization to upload packages on your behalf.\n' |
175 'Then click "Allow access".\n\n' | 183 'In a web browser, go to $authUrl\n' |
176 'Waiting for your authorization...'); | 184 'Then click "Allow access".\n\n' |
185 'Waiting for your authorization...'); | |
177 | 186 |
178 return completer.future.transform((client) { | 187 return completer.future.transform((client) { |
179 print('Successfully authorized.\n'); | 188 log.message('Successfully authorized.\n'); |
180 return client; | 189 return client; |
181 }); | 190 }); |
182 } | 191 } |
OLD | NEW |