Google Api

This commit is contained in:
Paul Schneider 2017-06-20 02:47:52 +02:00
commit 83f9fc1bd8
123 changed files with 12961 additions and 60 deletions

View file

@ -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
}
}

View file

@ -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;
}
}
}

View file

@ -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);
}
}
}
}

View file

@ -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;
}
}
}