| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | using System.Threading; |
| | using System.Threading.Tasks; |
| |
|
| | using Google.Apis.Auth.OAuth2.Flows; |
| | using Google.Apis.Auth.OAuth2.Responses; |
| | using Google.Apis.Auth.OAuth2.Requests; |
| | using Google.Apis.Logging; |
| | using Google.Apis.Util; |
| | using Google.Apis.Util.Store; |
| |
|
| | namespace Google.Apis.Auth.OAuth2 |
| | { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public class AuthorizationCodeInstalledApp : IAuthorizationCodeInstalledApp |
| | { |
| | private static readonly ILogger Logger = ApplicationContext.Logger.ForType<AuthorizationCodeInstalledApp>(); |
| |
|
| | private readonly IPkceAuthorizationCodeFlow flow; |
| | private readonly ICodeReceiver codeReceiver; |
| |
|
| | |
| | |
| | |
| | public AuthorizationCodeInstalledApp(IAuthorizationCodeFlow flow, ICodeReceiver codeReceiver) |
| | { |
| | this.flow = flow switch |
| | { |
| | IPkceAuthorizationCodeFlow pkceFlow => pkceFlow, |
| | _ => new NoOpPckeAuthorizationFlow(flow) |
| | }; |
| | this.codeReceiver = codeReceiver; |
| | } |
| |
|
| | #region IAuthorizationCodeInstalledApp Members |
| |
|
| | |
| | public IAuthorizationCodeFlow Flow |
| | { |
| | get { return flow; } |
| | } |
| |
|
| | |
| | public ICodeReceiver CodeReceiver |
| | { |
| | get { return codeReceiver; } |
| | } |
| |
|
| | |
| | public async Task<UserCredential> AuthorizeAsync(string userId, CancellationToken taskCancellationToken) |
| | { |
| | |
| | var token = await Flow.LoadTokenAsync(userId, taskCancellationToken).ConfigureAwait(false); |
| |
|
| | |
| | if (ShouldRequestAuthorizationCode(token)) |
| | { |
| | |
| | var redirectUri = CodeReceiver.RedirectUri; |
| | AuthorizationCodeRequestUrl codeRequest = flow.CreateAuthorizationCodeRequest(redirectUri, out string codeVerifier); |
| |
|
| | |
| | var response = await CodeReceiver.ReceiveCodeAsync(codeRequest, taskCancellationToken) |
| | .ConfigureAwait(false); |
| |
|
| | if (string.IsNullOrEmpty(response.Code)) |
| | { |
| | var errorResponse = new TokenErrorResponse(response); |
| | Logger.Info("Received an error. The response is: {0}", errorResponse); |
| | throw new TokenResponseException(errorResponse); |
| | } |
| |
|
| | Logger.Debug("Received \"{0}\" code", response.Code); |
| |
|
| | |
| | token = await flow.ExchangeCodeForTokenAsync(userId, response.Code, codeVerifier, redirectUri, |
| | taskCancellationToken).ConfigureAwait(false); |
| | } |
| |
|
| | return new UserCredential(flow, userId, token); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | public bool ShouldRequestAuthorizationCode(TokenResponse token) |
| | { |
| | |
| | |
| | |
| | return Flow.ShouldForceTokenRetrieval() || token == null || (token.RefreshToken == null |
| | && token.ShouldBeRefreshed(flow.Clock)); |
| | } |
| |
|
| | #endregion |
| |
|
| | |
| | |
| | |
| | |
| | private class NoOpPckeAuthorizationFlow : IPkceAuthorizationCodeFlow |
| | { |
| | private readonly IAuthorizationCodeFlow flow; |
| |
|
| | internal NoOpPckeAuthorizationFlow(IAuthorizationCodeFlow flow) => this.flow = flow; |
| |
|
| | public IAccessMethod AccessMethod => flow.AccessMethod; |
| |
|
| | public IClock Clock => flow.Clock; |
| |
|
| | public IDataStore DataStore => flow.DataStore; |
| |
|
| | public AuthorizationCodeRequestUrl CreateAuthorizationCodeRequest(string redirectUri, out string codeVerifier) |
| | { |
| | |
| | |
| | codeVerifier = "invalid+*/"; |
| | return flow.CreateAuthorizationCodeRequest(redirectUri); |
| | } |
| |
|
| | public AuthorizationCodeRequestUrl CreateAuthorizationCodeRequest(string redirectUri) => |
| | flow.CreateAuthorizationCodeRequest(redirectUri); |
| |
|
| | public Task DeleteTokenAsync(string userId, CancellationToken taskCancellationToken) => |
| | flow.DeleteTokenAsync(userId, taskCancellationToken); |
| |
|
| | public void Dispose() => flow.Dispose(); |
| |
|
| | public Task<TokenResponse> ExchangeCodeForTokenAsync(string userId, string code, string codeVerifier, string redirectUri, CancellationToken taskCancellationToken) => |
| | |
| | flow.ExchangeCodeForTokenAsync(userId, code, redirectUri, taskCancellationToken); |
| |
|
| | public Task<TokenResponse> ExchangeCodeForTokenAsync(string userId, string code, string redirectUri, CancellationToken taskCancellationToken) => |
| | flow.ExchangeCodeForTokenAsync(userId, code, redirectUri, taskCancellationToken); |
| |
|
| | public Task<TokenResponse> LoadTokenAsync(string userId, CancellationToken taskCancellationToken) => |
| | flow.LoadTokenAsync(userId, taskCancellationToken); |
| |
|
| | public Task<TokenResponse> RefreshTokenAsync(string userId, string refreshToken, CancellationToken taskCancellationToken) => |
| | flow.RefreshTokenAsync(userId, refreshToken, taskCancellationToken); |
| |
|
| | public Task RevokeTokenAsync(string userId, string token, CancellationToken taskCancellationToken) => |
| | flow.RevokeTokenAsync(userId, token, taskCancellationToken); |
| |
|
| | public bool ShouldForceTokenRetrieval() => |
| | flow.ShouldForceTokenRetrieval(); |
| | } |
| | } |
| | } |