Files
yavsc/Yavsc/GoogleApiSupport/Google.Apis.Auth/OAuth2/GoogleCredential.cs
2017-06-20 02:47:52 +02:00

223 lines
9.7 KiB
C#

/*
Copyright 2015 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.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Http;
namespace Google.Apis.Auth.OAuth2
{
/// <summary>
/// Credential for authorizing calls using OAuth 2.0.
/// It is a convenience wrapper that allows handling of different types of
/// credentials (like <see cref="ServiceAccountCredential"/>, <see cref="ComputeCredential"/>
/// or <see cref="UserCredential"/>) in a unified way.
/// <para>
/// See <see cref="GetApplicationDefaultAsync"/> for the credential retrieval logic.
/// </para>
/// </summary>
public class GoogleCredential : ICredential
{
/// <summary>Provider implements the logic for creating the application default credential.</summary>
private static DefaultCredentialProvider defaultCredentialProvider = new DefaultCredentialProvider();
/// <summary>The underlying credential being wrapped by this object.</summary>
protected readonly ICredential credential;
/// <summary>Creates a new <c>GoogleCredential</c>.</summary>
internal GoogleCredential(ICredential credential)
{
this.credential = credential;
}
/// <summary>
/// <para>Returns the Application Default Credentials which are ambient credentials that identify and authorize
/// the whole application.</para>
/// <para>The ambient credentials are determined as following order:</para>
/// <list type="number">
/// <item>
/// <description>
/// The environment variable GOOGLE_APPLICATION_CREDENTIALS is checked. If this variable is specified, it
/// should point to a file that defines the credentials. The simplest way to get a credential for this purpose
/// is to create a service account using the
/// <a href="https://console.developers.google.com">Google Developers Console</a> in the section APIs &amp;
/// Auth, in the sub-section Credentials. Create a service account or choose an existing one and select
/// Generate new JSON key. Set the environment variable to the path of the JSON file downloaded.
/// </description>
/// </item>
/// <item>
/// <description>
/// If you have installed the Google Cloud SDK on your machine and have run the command
/// <a href="https://cloud.google.com/sdk/gcloud/reference/auth/login">GCloud Auth Login</a>, your identity can
/// be used as a proxy to test code calling APIs from that machine.
/// </description>
/// </item>
/// <item>
/// <description>
/// If you are running in Google Compute Engine production, the built-in service account associated with the
/// virtual machine instance will be used.
/// </description>
/// </item>
/// <item>
/// <description>
/// If all previous steps have failed, <c>InvalidOperationException</c> is thrown.
/// </description>
/// </item>
/// </list>
/// </summary>
/// <returns>A task which completes with the application default credentials.</returns>
public static Task<GoogleCredential> GetApplicationDefaultAsync()
{
return defaultCredentialProvider.GetDefaultCredentialAsync();
}
/// <summary>
/// <para>Synchronously returns the Application Default Credentials which are ambient credentials that identify and authorize
/// the whole application. See <see cref="GetApplicationDefaultAsync"/> for details on application default credentials.</para>
/// <para>This method will block until the credentials are available (or an exception is thrown).
/// It is highly preferable to call <see cref="GetApplicationDefaultAsync"/> where possible.</para>
/// </summary>
/// <returns>The application default credentials.</returns>
public static GoogleCredential GetApplicationDefault() => Task.Run(() => GetApplicationDefaultAsync()).Result;
/// <summary>
/// Loads credential from stream containing JSON credential data.
/// <para>
/// The stream can contain a Service Account key file in JSON format from the Google Developers
/// Console or a stored user credential using the format supported by the Cloud SDK.
/// </para>
/// </summary>
public static GoogleCredential FromStream(Stream stream)
{
return defaultCredentialProvider.CreateDefaultCredentialFromStream(stream);
}
/// <summary>
/// Loads credential from a string containing JSON credential data.
/// <para>
/// The string can contain a Service Account key file in JSON format from the Google Developers
/// Console or a stored user credential using the format supported by the Cloud SDK.
/// </para>
/// </summary>
public static GoogleCredential FromJson(string json)
{
return defaultCredentialProvider.CreateDefaultCredentialFromJson(json);
}
/// <summary>
/// <para>Returns <c>true</c> only if this credential type has no scopes by default and requires
/// a call to <see cref="o:CreateScoped"/> before use.</para>
///
/// <para>Credentials need to have scopes in them before they can be used to access Google services.
/// Some Credential types have scopes built-in, and some don't. This property indicates whether
/// the Credential type has scopes built-in.</para>
///
/// <list type="number">
/// <item>
/// <description>
/// <see cref="ComputeCredential"/> has scopes built-in. Nothing additional is required.
/// </description>
/// </item>
/// <item>
/// <description>
/// <see cref="UserCredential"/> has scopes built-in, as they were obtained during the consent
/// screen. Nothing additional is required.</description>
/// </item>
/// <item>
/// <description>
/// <see cref="ServiceAccountCredential"/> does not have scopes built-in by default. Caller should
/// invoke <see cref="o:CreateScoped"/> to add scopes to the credential.
/// </description>
/// </item>
/// </list>
/// </summary>
public virtual bool IsCreateScopedRequired
{
get { return false; }
}
/// <summary>
/// If the credential supports scopes, creates a copy with the specified scopes. Otherwise, it returns the same
/// instance.
/// </summary>
public virtual GoogleCredential CreateScoped(IEnumerable<string> scopes)
{
return this;
}
/// <summary>
/// If the credential supports scopes, creates a copy with the specified scopes. Otherwise, it returns the same
/// instance.
/// </summary>
public GoogleCredential CreateScoped(params string[] scopes)
{
return CreateScoped((IEnumerable<string>) scopes);
}
void IConfigurableHttpClientInitializer.Initialize(ConfigurableHttpClient httpClient)
{
credential.Initialize(httpClient);
}
Task<string> ITokenAccess.GetAccessTokenForRequestAsync(string authUri, CancellationToken cancellationToken)
{
return credential.GetAccessTokenForRequestAsync(authUri, cancellationToken);
}
/// <summary>
/// Gets the underlying credential instance being wrapped.
/// </summary>
public ICredential UnderlyingCredential => credential;
/// <summary>Creates a <c>GoogleCredential</c> wrapping a <see cref="ServiceAccountCredential"/>.</summary>
internal static GoogleCredential FromCredential(ServiceAccountCredential credential)
{
return new ServiceAccountGoogleCredential(credential);
}
/// <summary>
/// Wraps <c>ServiceAccountCredential</c> as <c>GoogleCredential</c>.
/// We need this subclass because wrapping <c>ServiceAccountCredential</c> (unlike other wrapped credential
/// types) requires special handling for <c>IsCreateScopedRequired</c> and <c>CreateScoped</c> members.
/// </summary>
internal class ServiceAccountGoogleCredential : GoogleCredential
{
public ServiceAccountGoogleCredential(ServiceAccountCredential credential)
: base(credential) { }
public override bool IsCreateScopedRequired
{
get { return !(credential as ServiceAccountCredential).HasScopes; }
}
public override GoogleCredential CreateScoped(IEnumerable<string> scopes)
{
var serviceAccountCredential = credential as ServiceAccountCredential;
var initializer = new ServiceAccountCredential.Initializer(serviceAccountCredential.Id)
{
User = serviceAccountCredential.User,
Key = serviceAccountCredential.Key,
Scopes = scopes
};
return new ServiceAccountGoogleCredential(new ServiceAccountCredential(initializer));
}
}
}
}