Google Api
This commit is contained in:
parent
e307811d89
commit
83f9fc1bd8
123 changed files with 12961 additions and 60 deletions
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright 2013 Google Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Google.Apis.Auth.OAuth2.Responses
|
||||
{
|
||||
/// <summary>
|
||||
/// Authorization Code response for the redirect URL after end user grants or denies authorization as specified
|
||||
/// in http://tools.ietf.org/html/rfc6749#section-4.1.2.
|
||||
/// <para>
|
||||
/// Check that <see cref="Code"/> is not <c>null</c> or empty to verify the end-user granted authorization.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class AuthorizationCodeResponseUrl
|
||||
{
|
||||
/// <summary>Gets or sets the authorization code generated by the authorization server.</summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the state parameter matching the state parameter in the authorization request.
|
||||
/// </summary>
|
||||
public string State { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the error code (e.g. "invalid_request", "unauthorized_client", "access_denied",
|
||||
/// "unsupported_response_type", "invalid_scope", "server_error", "temporarily_unavailable") as specified in
|
||||
/// http://tools.ietf.org/html/rfc6749#section-4.1.2.1.
|
||||
/// </summary>
|
||||
public string Error { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the human-readable text which provides additional information used to assist the client
|
||||
/// developer in understanding the error occurred.
|
||||
/// </summary>
|
||||
public string ErrorDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI identifying a human-readable web page with provides information about the error.
|
||||
/// </summary>
|
||||
public string ErrorUri { get; set; }
|
||||
|
||||
/// <summary>Constructs a new authorization code response URL from the specified dictionary.</summary>
|
||||
public AuthorizationCodeResponseUrl(IDictionary<string, string> queryString)
|
||||
{
|
||||
InitFromDictionary(queryString);
|
||||
}
|
||||
|
||||
#region Constructs
|
||||
|
||||
/// <summary>Constructs a new authorization code response URL from the specified query string.</summary>
|
||||
public AuthorizationCodeResponseUrl(string query)
|
||||
{
|
||||
var pairs = query.Split('&');
|
||||
var queryString = new Dictionary<string, string>();
|
||||
foreach (var pair in pairs)
|
||||
{
|
||||
var keyValue = pair.Split('=');
|
||||
queryString[keyValue[0]] = keyValue[1];
|
||||
}
|
||||
|
||||
InitFromDictionary(queryString);
|
||||
}
|
||||
|
||||
/// <summary>Initializes this instance from the input dictionary.</summary>
|
||||
private void InitFromDictionary(IDictionary<string, string> queryString)
|
||||
{
|
||||
//TODO(peleyal): improve the following code and make it a utility
|
||||
IDictionary<string, Action<string>> setters = new Dictionary<string, Action<string>>();
|
||||
setters["code"] = v => Code = v;
|
||||
setters["state"] = v => State = v;
|
||||
setters["error"] = v => Error = v;
|
||||
setters["error_description"] = v => ErrorDescription = v;
|
||||
setters["error_uri"] = v => ErrorUri = v;
|
||||
|
||||
Action<string> setter;
|
||||
foreach (var pair in queryString)
|
||||
{
|
||||
if (setters.TryGetValue(pair.Key, out setter))
|
||||
{
|
||||
setter(pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Constructs a new empty authorization code response URL.</summary>
|
||||
public AuthorizationCodeResponseUrl()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2013 Google Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Google.Apis.Auth.OAuth2.Responses
|
||||
{
|
||||
/// <summary>
|
||||
/// OAuth 2.0 model for a unsuccessful access token response as specified in
|
||||
/// http://tools.ietf.org/html/rfc6749#section-5.2.
|
||||
/// </summary>
|
||||
public class TokenErrorResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets error code (e.g. "invalid_request", "invalid_client", "invalid_grant", "unauthorized_client",
|
||||
/// "unsupported_grant_type", "invalid_scope") as specified in http://tools.ietf.org/html/rfc6749#section-5.2.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("error")]
|
||||
public string Error { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a human-readable text which provides additional information used to assist the client
|
||||
/// developer in understanding the error occurred.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("error_description")]
|
||||
public string ErrorDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the URI identifying a human-readable web page with provides information about the error.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("error_uri")]
|
||||
public string ErrorUri { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Error:\"{0}\", Description:\"{1}\", Uri:\"{2}\"", Error, ErrorDescription, ErrorUri);
|
||||
}
|
||||
|
||||
/// <summary>Constructs a new empty token error response.</summary>
|
||||
public TokenErrorResponse()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Constructs a new token error response from the given authorization code response.</summary>
|
||||
public TokenErrorResponse(AuthorizationCodeResponseUrl authorizationCode)
|
||||
{
|
||||
Error = authorizationCode.Error;
|
||||
ErrorDescription = authorizationCode.ErrorDescription;
|
||||
ErrorUri = authorizationCode.ErrorUri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
Copyright 2013 Google Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
using Google.Apis.Util;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
using Google.Apis.Json;
|
||||
using Google.Apis.Logging;
|
||||
|
||||
namespace Google.Apis.Auth.OAuth2.Responses
|
||||
{
|
||||
/// <summary>
|
||||
/// OAuth 2.0 model for a successful access token response as specified in
|
||||
/// http://tools.ietf.org/html/rfc6749#section-5.1.
|
||||
/// </summary>
|
||||
public class TokenResponse
|
||||
{
|
||||
private const int TokenExpiryTimeWindowSeconds = 60 * 5; // Refresh token 5 minutes before it expires.
|
||||
|
||||
/// <summary>Gets or sets the access token issued by the authorization server.</summary>
|
||||
[Newtonsoft.Json.JsonPropertyAttribute("access_token")]
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the token type as specified in http://tools.ietf.org/html/rfc6749#section-7.1.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonPropertyAttribute("token_type")]
|
||||
public string TokenType { get; set; }
|
||||
|
||||
/// <summary>Gets or sets the lifetime in seconds of the access token.</summary>
|
||||
[Newtonsoft.Json.JsonPropertyAttribute("expires_in")]
|
||||
public Nullable<long> ExpiresInSeconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the refresh token which can be used to obtain a new access token.
|
||||
/// For example, the value "3600" denotes that the access token will expire in one hour from the time the
|
||||
/// response was generated.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonPropertyAttribute("refresh_token")]
|
||||
public string RefreshToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scope of the access token as specified in http://tools.ietf.org/html/rfc6749#section-3.3.
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonPropertyAttribute("scope")]
|
||||
public string Scope { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the id_token, which is a JSON Web Token (JWT) as specified in http://tools.ietf.org/html/draft-ietf-oauth-json-web-token
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonPropertyAttribute("id_token")]
|
||||
public string IdToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The date and time that this token was issued, expressed in the system time zone.
|
||||
/// This property only exists for backward compatibility; it can cause inappropriate behavior around
|
||||
/// time zone transitions (e.g. daylight saving transitions).
|
||||
/// </summary>
|
||||
[Obsolete("Use IssuedUtc instead")]
|
||||
[Newtonsoft.Json.JsonPropertyAttribute(Order = 1)] // Serialize this before IssuedUtc, so that IssuedUtc takes priority when deserializing
|
||||
public DateTime Issued
|
||||
{
|
||||
get { return IssuedUtc.ToLocalTime(); }
|
||||
set { IssuedUtc = value.ToUniversalTime(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The date and time that this token was issued, expressed in UTC.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This should be set by the CLIENT after the token was received from the server.
|
||||
/// </remarks>
|
||||
[Newtonsoft.Json.JsonPropertyAttribute(Order = 2)]
|
||||
public DateTime IssuedUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if the token is expired or it's going to be expired in the next minute.
|
||||
/// </summary>
|
||||
public bool IsExpired(IClock clock)
|
||||
{
|
||||
if (AccessToken == null || !ExpiresInSeconds.HasValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return IssuedUtc.AddSeconds(ExpiresInSeconds.Value - TokenExpiryTimeWindowSeconds) <= clock.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously parses a <see cref="TokenResponse"/> instance from the specified <see cref="HttpResponseMessage"/>.
|
||||
/// </summary>
|
||||
/// <param name="response">The http response from which to parse the token.</param>
|
||||
/// <param name="clock">The clock used to set the <see cref="Issued"/> value of the token.</param>
|
||||
/// <param name="logger">The logger used to output messages incase of error.</param>
|
||||
/// <exception cref="TokenResponseException">
|
||||
/// The response was not successful or there is an error parsing the response into valid <see cref="TokenResponse"/> instance.
|
||||
/// </exception>
|
||||
/// <returns>
|
||||
/// A task containing the <see cref="TokenResponse"/> parsed form the response message.
|
||||
/// </returns>
|
||||
public static async Task<TokenResponse> FromHttpResponseAsync(HttpResponseMessage response, Util.IClock clock, ILogger logger)
|
||||
{
|
||||
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
var typeName = "";
|
||||
try
|
||||
{
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
typeName = nameof(TokenErrorResponse);
|
||||
var error = NewtonsoftJsonSerializer.Instance.Deserialize<TokenErrorResponse>(content);
|
||||
throw new TokenResponseException(error, response.StatusCode);
|
||||
}
|
||||
|
||||
// Gets the token and sets its issued time.
|
||||
typeName = nameof(TokenResponse);
|
||||
var newToken = NewtonsoftJsonSerializer.Instance.Deserialize<TokenResponse>(content);
|
||||
newToken.IssuedUtc = clock.UtcNow;
|
||||
return newToken;
|
||||
}
|
||||
catch (Newtonsoft.Json.JsonException ex)
|
||||
{
|
||||
logger.Error(ex, $"Exception was caught when deserializing {typeName}. Content is: {content}");
|
||||
throw new TokenResponseException(new TokenErrorResponse
|
||||
{
|
||||
Error = "Server response does not contain a JSON object. Status code is: " + response.StatusCode
|
||||
}, response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2013 Google Inc
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace Google.Apis.Auth.OAuth2.Responses
|
||||
{
|
||||
/// <summary>
|
||||
/// Token response exception which is thrown in case of receiving a token error when an authorization code or an
|
||||
/// access token is expected.
|
||||
/// </summary>
|
||||
public class TokenResponseException : Exception
|
||||
{
|
||||
/// <summary>The error information.</summary>
|
||||
public TokenErrorResponse Error { get; }
|
||||
|
||||
/// <summary>HTTP status code of error, or null if unknown.</summary>
|
||||
public HttpStatusCode? StatusCode { get; }
|
||||
|
||||
/// <summary>Constructs a new token response exception from the given error.</summary>
|
||||
public TokenResponseException(TokenErrorResponse error)
|
||||
: this(error, null) { }
|
||||
|
||||
/// <summary>Constructs a new token response exception from the given error nad optional HTTP status code.</summary>
|
||||
public TokenResponseException(TokenErrorResponse error, HttpStatusCode? statusCode)
|
||||
: base(error.ToString())
|
||||
{
|
||||
Error = error;
|
||||
StatusCode = statusCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue