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

Side by Side Diff: lib/src/credentials.dart

Issue 1304363004: Code review changes (Closed) Base URL: git@github.com:dart-lang/oauth2.git@master
Patch Set: Created 5 years, 3 months 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 unified diff | Download patch
« no previous file with comments | « lib/src/client.dart ('k') | lib/src/handle_access_token_response.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.credentials; 5 library oauth2.credentials;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection';
8 import 'dart:convert'; 9 import 'dart:convert';
9 10
10 import 'package:http/http.dart' as http; 11 import 'package:http/http.dart' as http;
11 12
12 import 'handle_access_token_response.dart'; 13 import 'handle_access_token_response.dart';
14 import 'utils.dart';
13 15
14 /// Credentials that prove that a client is allowed to access a resource on the 16 /// Credentials that prove that a client is allowed to access a resource on the
15 /// resource owner's behalf. 17 /// resource owner's behalf.
16 /// 18 ///
17 /// These credentials are long-lasting and can be safely persisted across 19 /// These credentials are long-lasting and can be safely persisted across
18 /// multiple runs of the program. 20 /// multiple runs of the program.
19 /// 21 ///
20 /// Many authorization servers will attach an expiration date to a set of 22 /// Many authorization servers will attach an expiration date to a set of
21 /// credentials, along with a token that can be used to refresh the credentials 23 /// credentials, along with a token that can be used to refresh the credentials
22 /// once they've expired. The [Client] will automatically refresh its 24 /// once they've expired. The [Client] will automatically refresh its
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 /// Whether it's possible to refresh these credentials. 67 /// Whether it's possible to refresh these credentials.
66 bool get canRefresh => refreshToken != null && tokenEndpoint != null; 68 bool get canRefresh => refreshToken != null && tokenEndpoint != null;
67 69
68 /// Creates a new set of credentials. 70 /// Creates a new set of credentials.
69 /// 71 ///
70 /// This class is usually not constructed directly; rather, it's accessed via 72 /// This class is usually not constructed directly; rather, it's accessed via
71 /// [Client.credentials] after a [Client] is created by 73 /// [Client.credentials] after a [Client] is created by
72 /// [AuthorizationCodeGrant]. Alternately, it may be loaded from a serialized 74 /// [AuthorizationCodeGrant]. Alternately, it may be loaded from a serialized
73 /// form via [Credentials.fromJson]. 75 /// form via [Credentials.fromJson].
74 Credentials( 76 Credentials(
75 this.accessToken, 77 this.accessToken,
76 [this.refreshToken, 78 {this.refreshToken,
77 this.tokenEndpoint, 79 this.tokenEndpoint,
78 this.scopes, 80 Iterable<String> scopes,
79 this.expiration]); 81 this.expiration})
82 : scopes = new UnmodifiableListView(
83 // Explicitly type-annotate the list literal to work around
84 // sdk#24202.
85 scopes == null ? <String>[] : scopes.toList());
80 86
81 /// Loads a set of credentials from a JSON-serialized form. 87 /// Loads a set of credentials from a JSON-serialized form.
82 /// 88 ///
83 /// Throws a [FormatException] if the JSON is incorrectly formatted. 89 /// Throws a [FormatException] if the JSON is incorrectly formatted.
84 factory Credentials.fromJson(String json) { 90 factory Credentials.fromJson(String json) {
85 validate(condition, message) { 91 validate(condition, message) {
86 if (condition) return; 92 if (condition) return;
87 throw new FormatException( 93 throw new FormatException(
88 "Failed to load credentials: $message.\n\n$json"); 94 "Failed to load credentials: $message.\n\n$json");
89 } 95 }
(...skipping 29 matching lines...) Expand all
119 } 125 }
120 var expiration = parsed['expiration']; 126 var expiration = parsed['expiration'];
121 if (expiration != null) { 127 if (expiration != null) {
122 validate(expiration is int, 128 validate(expiration is int,
123 'field "expiration" was not an int, was "$expiration"'); 129 'field "expiration" was not an int, was "$expiration"');
124 expiration = new DateTime.fromMillisecondsSinceEpoch(expiration); 130 expiration = new DateTime.fromMillisecondsSinceEpoch(expiration);
125 } 131 }
126 132
127 return new Credentials( 133 return new Credentials(
128 parsed['accessToken'], 134 parsed['accessToken'],
129 parsed['refreshToken'], 135 refreshToken: parsed['refreshToken'],
130 tokenEndpoint, 136 tokenEndpoint: tokenEndpoint,
131 scopes, 137 scopes: scopes,
132 expiration); 138 expiration: expiration);
133 } 139 }
134 140
135 /// Serializes a set of credentials to JSON. 141 /// Serializes a set of credentials to JSON.
136 /// 142 ///
137 /// Nothing is guaranteed about the output except that it's valid JSON and 143 /// Nothing is guaranteed about the output except that it's valid JSON and
138 /// compatible with [Credentials.toJson]. 144 /// compatible with [Credentials.toJson].
139 String toJson() => JSON.encode({ 145 String toJson() => JSON.encode({
140 'accessToken': accessToken, 146 'accessToken': accessToken,
141 'refreshToken': refreshToken, 147 'refreshToken': refreshToken,
142 'tokenEndpoint': tokenEndpoint == null ? null : tokenEndpoint.toString(), 148 'tokenEndpoint': tokenEndpoint == null ? null : tokenEndpoint.toString(),
143 'scopes': scopes, 149 'scopes': scopes,
144 'expiration': expiration == null ? null : expiration.millisecondsSinceEpoch 150 'expiration': expiration == null ? null : expiration.millisecondsSinceEpoch
145 }); 151 });
146 152
147 /// Returns a new set of refreshed credentials. 153 /// Returns a new set of refreshed credentials.
148 /// 154 ///
149 /// See [Client.identifier] and [Client.secret] for explanations of those 155 /// See [Client.identifier] and [Client.secret] for explanations of those
150 /// parameters. 156 /// parameters.
151 /// 157 ///
152 /// You may request different scopes than the default by passing in 158 /// You may request different scopes than the default by passing in
153 /// [newScopes]. These must be a subset of [scopes]. 159 /// [newScopes]. These must be a subset of [scopes].
154 /// 160 ///
155 /// This will throw a [StateError] if these credentials can't be refreshed, an 161 /// This throws an [ArgumentError] if [secret] is passed without [identifier],
162 /// a [StateError] if these credentials can't be refreshed, an
156 /// [AuthorizationException] if refreshing the credentials fails, or a 163 /// [AuthorizationException] if refreshing the credentials fails, or a
157 /// [FormatError] if the authorization server returns invalid responses. 164 /// [FormatError] if the authorization server returns invalid responses.
158 Future<Credentials> refresh( 165 Future<Credentials> refresh(
159 String identifier, 166 {String identifier,
160 String secret, 167 String secret,
161 {List<String> newScopes, 168 Iterable<String> newScopes,
162 http.Client httpClient}) async { 169 bool basicAuth: true,
170 http.Client httpClient}) async {
163 var scopes = this.scopes; 171 var scopes = this.scopes;
164 if (newScopes != null) scopes = newScopes; 172 if (newScopes != null) scopes = newScopes.toList();
165 if (scopes == null) scopes = <String>[]; 173 if (scopes == null) scopes = [];
166 if (httpClient == null) httpClient = new http.Client(); 174 if (httpClient == null) httpClient = new http.Client();
167 175
176 if (identifier == null && secret != null) {
177 throw new ArgumentError("secret may not be passed without identifier.");
178 }
179
168 var startTime = new DateTime.now(); 180 var startTime = new DateTime.now();
169 if (refreshToken == null) { 181 if (refreshToken == null) {
170 throw new StateError("Can't refresh credentials without a refresh " 182 throw new StateError("Can't refresh credentials without a refresh "
171 "token."); 183 "token.");
172 } else if (tokenEndpoint == null) { 184 } else if (tokenEndpoint == null) {
173 throw new StateError("Can't refresh credentials without a token " 185 throw new StateError("Can't refresh credentials without a token "
174 "endpoint."); 186 "endpoint.");
175 } 187 }
176 188
177 var fields = { 189 var headers = {};
190
191 var body = {
178 "grant_type": "refresh_token", 192 "grant_type": "refresh_token",
179 "refresh_token": refreshToken, 193 "refresh_token": refreshToken
180 // TODO(nweiz): the spec recommends that HTTP basic auth be used in
181 // preference to form parameters, but Google doesn't support that.
182 // Should it be configurable?
183 "client_id": identifier,
184 "client_secret": secret
185 }; 194 };
186 if (!scopes.isEmpty) fields["scope"] = scopes.join(' '); 195 if (!scopes.isEmpty) body["scope"] = scopes.join(' ');
187 196
188 var response = await httpClient.post(tokenEndpoint, body: fields); 197 if (basicAuth && secret != null) {
198 headers["Authorization"] = basicAuthHeader(identifier, secret);
199 } else {
200 if (identifier != null) body["client_id"] = identifier;
201 if (secret != null) body["client_secret"] = secret;
202 }
203
204 var response = await httpClient.post(tokenEndpoint,
205 headers: headers, body: body);
189 var credentials = await handleAccessTokenResponse( 206 var credentials = await handleAccessTokenResponse(
190 response, tokenEndpoint, startTime, scopes); 207 response, tokenEndpoint, startTime, scopes);
191 208
192 // The authorization server may issue a new refresh token. If it doesn't, 209 // The authorization server may issue a new refresh token. If it doesn't,
193 // we should re-use the one we already have. 210 // we should re-use the one we already have.
194 if (credentials.refreshToken != null) return credentials; 211 if (credentials.refreshToken != null) return credentials;
195 return new Credentials( 212 return new Credentials(
196 credentials.accessToken, 213 credentials.accessToken,
197 this.refreshToken, 214 refreshToken: this.refreshToken,
198 credentials.tokenEndpoint, 215 tokenEndpoint: credentials.tokenEndpoint,
199 credentials.scopes, 216 scopes: credentials.scopes,
200 credentials.expiration); 217 expiration: credentials.expiration);
201 } 218 }
202 } 219 }
OLDNEW
« no previous file with comments | « lib/src/client.dart ('k') | lib/src/handle_access_token_response.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698