Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(600)

Unified Diff: Src/GoogleApis.Auth/OAuth2/Credential.cs

Issue 14341043: Issue 351: Reimplement OAuth2 (Step 4): ServiceAccount and MVC (Closed) Base URL: https://google-api-dotnet-client.googlecode.com/hg/
Patch Set: Gus comments Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Src/GoogleApis.Auth/OAuth2/Credential.cs
===================================================================
deleted file mode 100644
--- a/Src/GoogleApis.Auth/OAuth2/Credential.cs
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-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;
-using System.Net.Http;
-using System.Threading;
-using System.Threading.Tasks;
-
-using Google.Apis.Auth.OAuth2.Responses;
-using Google.Apis.Http;
-using Google.Apis.Logging;
-
-namespace Google.Apis.Auth.OAuth2
-{
- /// <summary>
- /// OAuth 2.0 credential for accessing protected resources using an access token, as well as optionally refreshing
- /// the access token when it expires using a refresh token.
- /// </summary>
- public class Credential : IHttpExecuteInterceptor, IHttpUnsuccessfulResponseHandler,
- IConfigurableHttpClientInitializer
- {
- private static readonly ILogger Logger = ApplicationContext.Logger.ForType<Credential>();
-
- private TokenResponse token;
- private object lockObject = new object();
-
- public TokenResponse Token
- {
- get
- {
- lock (lockObject)
- {
- return token;
- }
- }
- private set
- {
- lock (lockObject)
- {
- token = value;
- }
- }
- }
-
- private readonly IAuthorizationCodeFlow flow;
- private readonly string userId;
-
- /// <summary>Constructs a new credential instance.</summary>
- /// <param name="flow">Authorization code flow</param>
- /// <param name="userId">User identifier</param>
- /// <param name="token">An initial token for the user</param>
- public Credential(IAuthorizationCodeFlow flow, string userId, TokenResponse token)
- {
- this.flow = flow;
- this.userId = userId;
- this.token = token;
- }
-
- /// <summary>
- /// Default implementation is to try to refresh the access token if there is no access token or if we are 1
- /// minute away from expiration. If token server is unavailable, it will try to use the access token even if
- /// has expired. If successful, it will call <seealso cref="IAccessMethod.Intercept"/>.
- /// </summary>
- public async Task InterceptAsync(HttpRequestMessage request, CancellationToken taskCancellationToken)
- {
- if (Token.IsExpired(flow.Clock))
- {
- if (!await RefreshTokenAsync(taskCancellationToken).ConfigureAwait(false))
- {
- throw new InvalidOperationException("The access token is expired but we can't refresh it");
- }
- }
-
- flow.AccessMethod.Intercept(request, Token.AccessToken);
- }
-
- /// <summary>
- /// Refreshes the token by calling to <seealso cref="IAuthorizationCodeFlow.RefreshTokenAsync"/>. Then it
- /// updates the <see cref="TokenResponse"/> with the new token instance.
- /// </summary>
- /// <param name="taskCancellationToken">Cancellation token to cancel an operation</param>
- /// <returns><c>true</c> if the token was refreshed</returns>
- private async Task<bool> RefreshTokenAsync(CancellationToken taskCancellationToken)
- {
- if (Token.RefreshToken == null)
- {
- Logger.Warning("Refresh token is null, can't refresh the token!");
- return false;
- }
-
- // It's possible that two concurrent calls will be made to refresh the token, in that case the last one
- // will win.
- var newToken = await flow.RefreshTokenAsync(userId, Token.RefreshToken, taskCancellationToken)
- .ConfigureAwait(false);
-
- Logger.Info("Access token was refreshed");
-
- if (newToken.RefreshToken == null)
- {
- newToken.RefreshToken = Token.RefreshToken;
- }
-
- Token = newToken;
- return true;
- }
-
- public async Task<bool> HandleResponseAsync(HandleUnsuccessfulResponseArgs args)
- {
- // TODO(peleyal): check WWW-Authenticate header
- if (args.Response.StatusCode == HttpStatusCode.Unauthorized)
- {
- return !Object.Equals(Token.AccessToken, flow.AccessMethod.GetAccessToken(args.Request))
- || await RefreshTokenAsync(args.CancellationToken).ConfigureAwait(false);
- }
-
- return false;
- }
-
- public void Initialize(ConfigurableHttpClient httpClient)
- {
- httpClient.MessageHandler.ExecuteInterceptors.Add(this);
- httpClient.MessageHandler.UnsuccessfulResponseHandlers.Add(this);
- }
- }
-}
« no previous file with comments | « Src/GoogleApis.Auth/OAuth2/AuthorizationCodeInstalledApp.cs ('k') | Src/GoogleApis.Auth/OAuth2/Flows/AuthorizationCodeFlow.cs » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b