|
| 1 | +/* |
| 2 | + * Copyright 2024 Google LLC |
| 3 | + * |
| 4 | + * Redistribution and use in source and binary forms, with or without |
| 5 | + * modification, are permitted provided that the following conditions are |
| 6 | + * met: |
| 7 | + * |
| 8 | + * * Redistributions of source code must retain the above copyright |
| 9 | + * notice, this list of conditions and the following disclaimer. |
| 10 | + * * Redistributions in binary form must reproduce the above |
| 11 | + * copyright notice, this list of conditions and the following disclaimer |
| 12 | + * in the documentation and/or other materials provided with the |
| 13 | + * distribution. |
| 14 | + * |
| 15 | + * * Neither the name of Google LLC nor the names of its |
| 16 | + * contributors may be used to endorse or promote products derived from |
| 17 | + * this software without specific prior written permission. |
| 18 | + * |
| 19 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 20 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 21 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 | + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 | + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 | + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 | + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | + */ |
| 31 | + |
| 32 | +package com.google.auth.oauth2; |
| 33 | + |
| 34 | +import static com.google.auth.oauth2.ServiceAccountCredentialsTest.ACCESS_TOKEN; |
| 35 | +import static com.google.auth.oauth2.ServiceAccountCredentialsTest.CALL_URI; |
| 36 | +import static com.google.auth.oauth2.ServiceAccountCredentialsTest.CLIENT_EMAIL; |
| 37 | +import static com.google.auth.oauth2.ServiceAccountCredentialsTest.DEFAULT_ID_TOKEN; |
| 38 | +import static com.google.auth.oauth2.ServiceAccountCredentialsTest.SCOPES; |
| 39 | +import static com.google.auth.oauth2.ServiceAccountCredentialsTest.createDefaultBuilder; |
| 40 | +import static org.junit.Assert.assertEquals; |
| 41 | + |
| 42 | +import ch.qos.logback.classic.LoggerContext; |
| 43 | +import com.google.api.client.http.HttpStatusCodes; |
| 44 | +import com.google.auth.TestAppender; |
| 45 | +import com.google.auth.TestUtils; |
| 46 | +import java.io.IOException; |
| 47 | +import java.util.List; |
| 48 | +import java.util.Map; |
| 49 | +import org.junit.After; |
| 50 | +import org.junit.Before; |
| 51 | +import org.junit.Test; |
| 52 | +import org.slf4j.Logger; |
| 53 | +import org.slf4j.LoggerFactory; |
| 54 | + |
| 55 | +public class LoggingTest { |
| 56 | + |
| 57 | + private static final Logger LOGGER = LoggerFactory.getLogger(LoggingTest.class); |
| 58 | + private TestEnvironmentProvider testEnvironmentProvider; |
| 59 | + |
| 60 | + @Before |
| 61 | + public void setup() { |
| 62 | + testEnvironmentProvider = new TestEnvironmentProvider(); |
| 63 | + testEnvironmentProvider.setEnv("GOOGLE_SDK_JAVA_LOGGING", "true"); |
| 64 | + LoggingConfigs.setEnvironmentProvider(testEnvironmentProvider); |
| 65 | + } |
| 66 | + |
| 67 | + @After |
| 68 | + public void tearDown() { |
| 69 | + LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); |
| 70 | + loggerContext.getLogger(Logger.ROOT_LOGGER_NAME).detachAppender("CONSOLE"); |
| 71 | + } |
| 72 | + |
| 73 | + private TestAppender setupTestLogger(Class<?> clazz) { |
| 74 | + TestAppender testAppender = new TestAppender(); |
| 75 | + testAppender.start(); |
| 76 | + Logger logger = LoggerFactory.getLogger(clazz); |
| 77 | + ((ch.qos.logback.classic.Logger) logger).addAppender(testAppender); |
| 78 | + return testAppender; |
| 79 | + } |
| 80 | + |
| 81 | + @Test |
| 82 | + public void getRequestMetadata_hasAccessToken() throws IOException { |
| 83 | + TestAppender testAppender = setupTestLogger(ServiceAccountCredentials.class); |
| 84 | + GoogleCredentials credentials = |
| 85 | + ServiceAccountCredentialsTest.createDefaultBuilderWithToken(ACCESS_TOKEN) |
| 86 | + .setScopes(SCOPES) |
| 87 | + .build(); |
| 88 | + Map<String, List<String>> metadata = credentials.getRequestMetadata(CALL_URI); |
| 89 | + TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN); |
| 90 | + |
| 91 | + assertEquals(3, testAppender.events.size()); |
| 92 | + assertEquals( |
| 93 | + "Sending auth request to refresh access token.", |
| 94 | + testAppender.events.get(0).getFormattedMessage()); |
| 95 | + testAppender.stop(); |
| 96 | + } |
| 97 | + |
| 98 | + @Test |
| 99 | + public void idTokenWithAudience_iamFlow_targetAudienceMatchesAudClaim() throws IOException { |
| 100 | + TestAppender testAppender = setupTestLogger(ServiceAccountCredentials.class); |
| 101 | + String nonGDU = "test.com"; |
| 102 | + MockIAMCredentialsServiceTransportFactory transportFactory = |
| 103 | + new MockIAMCredentialsServiceTransportFactory(nonGDU); |
| 104 | + transportFactory.getTransport().setTargetPrincipal(CLIENT_EMAIL); |
| 105 | + transportFactory.getTransport().setIdToken(DEFAULT_ID_TOKEN); |
| 106 | + transportFactory.getTransport().addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, ""); |
| 107 | + ServiceAccountCredentials credentials = |
| 108 | + createDefaultBuilder() |
| 109 | + .setScopes(SCOPES) |
| 110 | + .setHttpTransportFactory(transportFactory) |
| 111 | + .setUniverseDomain(nonGDU) |
| 112 | + .build(); |
| 113 | + |
| 114 | + String targetAudience = "https://foo.bar"; |
| 115 | + IdTokenCredentials tokenCredential = |
| 116 | + IdTokenCredentials.newBuilder() |
| 117 | + .setIdTokenProvider(credentials) |
| 118 | + .setTargetAudience(targetAudience) |
| 119 | + .build(); |
| 120 | + tokenCredential.refresh(); |
| 121 | + assertEquals(DEFAULT_ID_TOKEN, tokenCredential.getAccessToken().getTokenValue()); |
| 122 | + assertEquals(DEFAULT_ID_TOKEN, tokenCredential.getIdToken().getTokenValue()); |
| 123 | + |
| 124 | + // ID Token's aud claim is `https://foo.bar` |
| 125 | + assertEquals( |
| 126 | + targetAudience, |
| 127 | + tokenCredential.getIdToken().getJsonWebSignature().getPayload().getAudience()); |
| 128 | + |
| 129 | + assertEquals(2, testAppender.events.size()); |
| 130 | + assertEquals( |
| 131 | + "Sending id token request to Iam Endpoint.", |
| 132 | + testAppender.events.get(0).getFormattedMessage()); |
| 133 | + assertEquals("Auth response payload.", testAppender.events.get(1).getFormattedMessage()); |
| 134 | + |
| 135 | + testAppender.stop(); |
| 136 | + } |
| 137 | +} |
0 commit comments