public async Task RefreshesOidcToken() { // A little bit after the tokens returned from OidcTokenFakes were issued. var clock = new MockClock(new DateTime(2020, 5, 21, 9, 20, 0, 0, DateTimeKind.Utc)); var messageHandler = new OidcComputeSuccessMessageHandler(); var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored") { Clock = clock, HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var credential = new ComputeCredential(initializer); // The fake Oidc server returns valid tokens (expired in the real world for safty) // but with a set audience that lets us know if the token was refreshed or not. var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("will.be.ignored")); var signedToken = SignedToken <Header, Payload> .FromSignedToken(await oidcToken.GetAccessTokenAsync()); Assert.Equal("https://first_call.test", signedToken.Payload.Audience); // Move the clock so that the token expires. clock.UtcNow = clock.UtcNow.AddHours(2); signedToken = SignedToken <Header, Payload> .FromSignedToken(await oidcToken.GetAccessTokenAsync()); Assert.Equal("https://subsequent_calls.test", signedToken.Payload.Audience); // Two calls, because the second time we tried to get the token, the first one had expired. Assert.Equal(2, messageHandler.Calls); }
public async Task SignBlobAsync_UnsupportedCredential() { var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored"); var computeCredential = new ComputeCredential(initializer); var googleCredential = GoogleCredential.FromComputeCredential(computeCredential); await Assert.ThrowsAsync <InvalidOperationException>(() => googleCredential.SignBlobAsync(Encoding.ASCII.GetBytes("toSign"))); }
/// <summary> /// Adds firebase authentication to the service collection using a compute credential for the key (not recommended) /// </summary> /// <param name="services">IServiceCollection instance to which you will be adding the auth policy</param> /// <param name="computeCredential">The compute credential to use in the returned Google.Apis.Auth.OAuth2.GoogleCredential</param> public static void AddFirebaseAdminFromComputeCredential( this IServiceCollection services, ComputeCredential computeCredential = null) { AddAuthPolicy(services); CreateApp(GoogleCredential.FromComputeCredential(computeCredential)); }
public OnGceFactAttribute() { // Ugly, but this is for tests. if (!ComputeCredential.IsRunningOnComputeEngine().GetAwaiter().GetResult()) { Skip = "Not running on GCE"; } }
public void WithHttpClientFactory() { var credential = new ComputeCredential(); var factory = new HttpClientFactory(); var credentialWithFactory = Assert.IsType <ComputeCredential>(((IGoogleCredential)credential).WithHttpClientFactory(factory)); Assert.NotSame(credential, credentialWithFactory); Assert.NotSame(credential.HttpClient, credentialWithFactory.HttpClient); Assert.NotSame(credential.HttpClientFactory, credentialWithFactory.HttpClientFactory); Assert.Same(factory, credentialWithFactory.HttpClientFactory); }
public async Task Scoped_Initializer_WithCustomTokenUrl(string[] scopes, string customTokenUrl, string expectedTokenUrl) { var fakeMessageHandler = new FetchesTokenMessageHandler(); var credential = new ComputeCredential(new ComputeCredential.Initializer(customTokenUrl) { Scopes = scopes, HttpClientFactory = new MockHttpClientFactory(fakeMessageHandler) }); AssertScoped(credential, scopes, expectedTokenUrl); await AssertUsesScopedUrl(credential, fakeMessageHandler, expectedTokenUrl); }
/// <summary> /// Will use compute credentials if running on compute engine, otherwise will use environment variables /// </summary> /// <returns></returns> public static async Task <BigtableCredentials> UseApplicationDefaultCredentialsAsync() { if (await ComputeCredential.IsRunningOnComputeEngine()) { // Hookup .pem file SetDefaultSslKeyFilePath(); // Get credential var credentials = new ComputeCredential(new ComputeCredential.Initializer()); // Return results return(new BigtableCredentials(credentials)); } // Use environment return(await UseEnvironmentAsync()); }
public async Task FetchesOidcToken_WithDefaultOptions() { // A little bit after the tokens returned from OidcTokenFakes were issued. var clock = new MockClock(new DateTime(2020, 5, 21, 9, 20, 0, 0, DateTimeKind.Utc)); var messageHandler = new OidcComputeSuccessMessageHandler(); var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored") { Clock = clock, HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var credential = new ComputeCredential(initializer); var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("any_audience")); await oidcToken.GetAccessTokenAsync(); Assert.Equal("?audience=any_audience&format=full", messageHandler.LatestRequest.RequestUri.Query); }
public async Task FromComputeCredential_FetchesOidcToken() { var clock = new MockClock { UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) }; var messageHandler = new OidcTokenSuccessMessageHandler(clock); var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored") { Clock = clock, HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var computeCredential = new ComputeCredential(initializer); var googleCredential = GoogleCredential.FromComputeCredential(computeCredential); var oidcToken = await googleCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience")); Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync()); }
public async Task FetchesOidcToken_WithDefaultOptions() { var clock = new MockClock { UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) }; var messageHandler = new OidcTokenSuccessMessageHandler(clock); var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored") { Clock = clock, HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var credential = new ComputeCredential(initializer); var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("any_audience")); await oidcToken.GetAccessTokenAsync(); Assert.Equal("?audience=any_audience&format=full", messageHandler.LatestRequest.RequestUri.Query); }
public async Task FromComputeCredential_FetchesOidcToken() { // A little bit after the tokens returned from OidcTokenFakes were issued. var clock = new MockClock(new DateTime(2020, 5, 21, 9, 20, 0, 0, DateTimeKind.Utc)); var messageHandler = new OidcComputeSuccessMessageHandler(); var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored") { Clock = clock, HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var computeCredential = new ComputeCredential(initializer); var googleCredential = GoogleCredential.FromComputeCredential(computeCredential); // The fake Oidc server returns valid tokens (expired in the real world for safty) // but with a set audience that lets us know if the token was refreshed or not. var oidcToken = await googleCredential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("will.be.ignored")); var signedToken = SignedToken <Header, Payload> .FromSignedToken(await oidcToken.GetAccessTokenAsync()); Assert.Equal("https://first_call.test", signedToken.Payload.Audience); }
public async Task RefreshesOidcToken() { var clock = new MockClock { UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) }; var messageHandler = new OidcTokenSuccessMessageHandler(clock); var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored") { Clock = clock, HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var credential = new ComputeCredential(initializer); var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience")); Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync()); // Move the clock so that the token expires. clock.UtcNow = clock.UtcNow.AddHours(2); Assert.Equal("very_fake_access_token_2", await oidcToken.GetAccessTokenAsync()); // Two calls, because the second time we tried to get the token, the first one had expired. Assert.Equal(2, messageHandler.Calls); }
public async Task FetchesOidcToken() { var clock = new MockClock { UtcNow = new DateTime(2020, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc) }; var messageHandler = new OidcTokenSuccessMessageHandler(clock); var initializer = new ComputeCredential.Initializer("http://will.be.ignored", "http://will.be.ignored") { Clock = clock, HttpClientFactory = new MockHttpClientFactory(messageHandler) }; var credential = new ComputeCredential(initializer); var oidcToken = await credential.GetOidcTokenAsync(OidcTokenOptions.FromTargetAudience("audience")); Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync()); // Move the clock some but not enough that the token expires. clock.UtcNow = clock.UtcNow.AddMinutes(20); Assert.Equal("very_fake_access_token_1", await oidcToken.GetAccessTokenAsync()); // Only the first call should have resulted in a request. The second time the token hadn't expired. Assert.Equal(1, messageHandler.Calls); }
public static async Task <string> DetermineRuntime() { // Check for environment variables that indicate a specific runtime. foreach (var indicator in environmentIndicators) { if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable(indicator.Key))) { return(indicator.Value); } } // Check metadata server, which indicates GCE. if (await ComputeCredential.IsRunningOnComputeEngine()) { return("Compute Engine"); } else { // Metadata server not available, so it's probably not nunning // on Google Cloud. return(null); } }
private void AssertScoped(ComputeCredential credential, string[] scopes, string expectedTokenUrl) { Assert.Collection(credential.Scopes ?? Enumerable.Empty <string>(), (scopes?.Select <string, Action <string> >(expectedScope => actualScope => Assert.Equal(expectedScope, actualScope)) ?? Enumerable.Empty <Action <string> >()).ToArray()); Assert.Equal(expectedTokenUrl, credential.EffectiveTokenServerUrl); }
/// <summary> /// Scoped cannot be used /// </summary> public BigtableCredentials(ComputeCredential computeCredentials) { _computeCredentials = computeCredentials; }
static string ShowRunningOnComputeEngine() => ComputeCredential.IsRunningOnComputeEngine().Result.ToString();
public void IsRunningOnComputeEngine_ResultIsCached() { // Two subsequent invocations should return the same task. Assert.Same(ComputeCredential.IsRunningOnComputeEngine(), ComputeCredential.IsRunningOnComputeEngine()); }
/// <summary>Creates a new default credential.</summary> private async Task <GoogleCredential> CreateDefaultCredentialAsync() { // 1. First try the environment variable. string credentialPath = GetEnvironmentVariable(CredentialEnvironmentVariable); if (!String.IsNullOrWhiteSpace(credentialPath)) { try { return(CreateDefaultCredentialFromFile(credentialPath)); } catch (Exception e) { // Catching generic exception type because any corrupted file could manifest in different ways // including but not limited to the System, System.IO or from the Newtonsoft.Json namespace. throw new InvalidOperationException( String.Format("Error reading credential file from location {0}: {1}" + "\nPlease check the value of the Environment Variable {2}", credentialPath, e.Message, CredentialEnvironmentVariable), e); } } // 2. Then try the well known file. credentialPath = GetWellKnownCredentialFilePath(); if (!String.IsNullOrWhiteSpace(credentialPath)) { try { return(CreateDefaultCredentialFromFile(credentialPath)); } catch (FileNotFoundException) { // File is not present, eat the exception and move on to the next check. Logger.Debug("Well-known credential file {0} not found.", credentialPath); } catch (DirectoryNotFoundException) { // Directory not present, eat the exception and move on to the next check. Logger.Debug("Well-known credential file {0} not found.", credentialPath); } catch (Exception e) { throw new InvalidOperationException( String.Format("Error reading credential file from location {0}: {1}" + "\nPlease rerun 'gcloud auth login' to regenerate credentials file.", credentialPath, e.Message), e); } } // 3. Then try the compute engine. Logger.Debug("Checking whether the application is running on ComputeEngine."); if (await ComputeCredential.IsRunningOnComputeEngine().ConfigureAwait(false)) { Logger.Debug("ComputeEngine check passed. Using ComputeEngine Credentials."); return(new GoogleCredential(new ComputeCredential())); } // If everything we tried has failed, throw an exception. throw new InvalidOperationException( String.Format("The Application Default Credentials are not available. They are available if running" + " in Google Compute Engine. Otherwise, the environment variable {0} must be defined" + " pointing to a file defining the credentials. See {1} for more information.", CredentialEnvironmentVariable, HelpPermalink)); }
private async Task AssertUsesScopedUrl(ComputeCredential credential, FetchesTokenMessageHandler fakeMessageHandler, string expectedTokenUrl) { Assert.NotNull(await credential.GetAccessTokenForRequestAsync()); Assert.Equal(1, fakeMessageHandler.Calls); Assert.Equal(expectedTokenUrl, fakeMessageHandler.Requests.First().RequestUri.AbsoluteUri); }