| Index: lib/src/authorization_code_grant.dart
|
| diff --git a/lib/src/authorization_code_grant.dart b/lib/src/authorization_code_grant.dart
|
| index e3bb645382ab124eae1dd023ac91367d6a1bccfc..7a73d44ab0baad33cabb4b8c2c15cc8b993007cd 100644
|
| --- a/lib/src/authorization_code_grant.dart
|
| +++ b/lib/src/authorization_code_grant.dart
|
| @@ -68,6 +68,9 @@ class AuthorizationCodeGrant {
|
| /// documentation.
|
| final Uri tokenEndpoint;
|
|
|
| + /// Whether to use HTTP Basic authentication for authorizing the client.
|
| + final bool _basicAuth;
|
| +
|
| /// The HTTP client used to make HTTP requests.
|
| http.Client _httpClient;
|
|
|
| @@ -87,15 +90,23 @@ class AuthorizationCodeGrant {
|
|
|
| /// Creates a new grant.
|
| ///
|
| + /// If [basicAuth] is `true` (the default), the client credentials are sent to
|
| + /// the server using using HTTP Basic authentication as defined in [RFC 2617].
|
| + /// Otherwise, they're included in the request body. Note that the latter form
|
| + /// is not recommended by the OAuth 2.0 spec, and should only be used if the
|
| + /// server doesn't support Basic authentication.
|
| + ///
|
| + /// [RFC 2617]: https://tools.ietf.org/html/rfc2617
|
| + ///
|
| /// [httpClient] is used for all HTTP requests made by this grant, as well as
|
| /// those of the [Client] is constructs.
|
| AuthorizationCodeGrant(
|
| this.identifier,
|
| - this.secret,
|
| this.authorizationEndpoint,
|
| this.tokenEndpoint,
|
| - {http.Client httpClient})
|
| - : _httpClient = httpClient == null ? new http.Client() : httpClient;
|
| + {this.secret, bool basicAuth: true, http.Client httpClient})
|
| + : _basicAuth = basicAuth,
|
| + _httpClient = httpClient == null ? new http.Client() : httpClient;
|
|
|
| /// Returns the URL to which the resource owner should be redirected to
|
| /// authorize this client.
|
| @@ -116,13 +127,19 @@ class AuthorizationCodeGrant {
|
| /// query parameters provided to the redirect URL.
|
| ///
|
| /// It is a [StateError] to call this more than once.
|
| - Uri getAuthorizationUrl(Uri redirect,
|
| - {List<String> scopes: const <String>[], String state}) {
|
| + Uri getAuthorizationUrl(Uri redirect, {Iterable<String> scopes,
|
| + String state}) {
|
| if (_state != _State.initial) {
|
| throw new StateError('The authorization URL has already been generated.');
|
| }
|
| _state = _State.awaitingResponse;
|
|
|
| + if (scopes == null) {
|
| + scopes = [];
|
| + } else {
|
| + scopes = scopes.toList();
|
| + }
|
| +
|
| this._redirectEndpoint = redirect;
|
| this._scopes = scopes;
|
| this._stateString = state;
|
| @@ -224,21 +241,35 @@ class AuthorizationCodeGrant {
|
| /// the state beforehand.
|
| Future<Client> _handleAuthorizationCode(String authorizationCode) async {
|
| var startTime = new DateTime.now();
|
| - var response = await _httpClient.post(this.tokenEndpoint, body: {
|
| +
|
| + var headers = {};
|
| +
|
| + var body = {
|
| "grant_type": "authorization_code",
|
| "code": authorizationCode,
|
| - "redirect_uri": this._redirectEndpoint.toString(),
|
| - // TODO(nweiz): the spec recommends that HTTP basic auth be used in
|
| - // preference to form parameters, but Google doesn't support that. Should
|
| - // it be configurable?
|
| - "client_id": this.identifier,
|
| - "client_secret": this.secret
|
| - });
|
| + "redirect_uri": this._redirectEndpoint.toString()
|
| + };
|
| +
|
| + if (_basicAuth && secret != null) {
|
| + headers["Authorization"] = basicAuthHeader(identifier, secret);
|
| + } else {
|
| + // The ID is required for this request any time basic auth isn't being
|
| + // used, even if there's no actual client authentication to be done.
|
| + body["client_id"] = identifier;
|
| + if (secret != null) body["client_secret"] = secret;
|
| + }
|
| +
|
| + var response = await _httpClient.post(this.tokenEndpoint,
|
| + headers: headers, body: body);
|
|
|
| var credentials = handleAccessTokenResponse(
|
| response, tokenEndpoint, startTime, _scopes);
|
| return new Client(
|
| - this.identifier, this.secret, credentials, httpClient: _httpClient);
|
| + credentials,
|
| + identifier: this.identifier,
|
| + secret: this.secret,
|
| + basicAuth: _basicAuth,
|
| + httpClient: _httpClient);
|
| }
|
|
|
| /// Closes the grant and frees its resources.
|
|
|