diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java index d82548a082fd..59e2766928fd 100644 --- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java +++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java @@ -32,6 +32,8 @@ package com.google.auth.oauth2; import java.io.File; +import java.io.FileNotFoundException; +import java.io.UncheckedIOException; /** * This public class provides shared utilities for common OAuth2 utils or ADC. It also exposes @@ -70,7 +72,14 @@ static final File getWellKnownCredentialsFile(DefaultCredentialsProvider provide if (envPath != null) { cloudConfigPath = new File(envPath); } else if (provider.getOsName().indexOf("windows") >= 0) { - File appDataPath = new File(provider.getEnv("APPDATA")); + String appDataEnv = provider.getEnv("APPDATA"); + if (appDataEnv == null || appDataEnv.trim().isEmpty()) { + throw new UncheckedIOException( + new FileNotFoundException( + "APPDATA environment variable is not set or empty; cannot locate the well-known" + + " credentials file on Windows.")); + } + File appDataPath = new File(appDataEnv); cloudConfigPath = new File(appDataPath, provider.CLOUDSDK_CONFIG_DIRECTORY); } else { File configPath = new File(provider.getProperty("user.home", ""), ".config"); diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java index de7077ef6277..d756cc9e4f77 100644 --- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java +++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java @@ -33,12 +33,64 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; +import java.io.FileNotFoundException; +import java.io.UncheckedIOException; import org.junit.jupiter.api.Test; class GoogleAuthUtilsTest { + @Test + void getWellKnownCredentialsFile_windows_nullAppData_throwsUncheckedIOException() { + DefaultCredentialsProviderTest.TestDefaultCredentialsProvider provider = + new DefaultCredentialsProviderTest.TestDefaultCredentialsProvider(); + provider.setProperty("os.name", "windows"); + // APPDATA is intentionally not set, so getEnv("APPDATA") returns null + + UncheckedIOException thrown = + assertThrows( + UncheckedIOException.class, + () -> GoogleAuthUtils.getWellKnownCredentialsFile(provider)); + assertTrue(thrown.getCause() instanceof FileNotFoundException); + assertTrue(thrown.getCause().getMessage().contains("APPDATA")); + assertTrue(thrown.getCause().getMessage().contains("not set or empty")); + } + + @Test + void getWellKnownCredentialsFile_windows_emptyAppData_throwsUncheckedIOException() { + DefaultCredentialsProviderTest.TestDefaultCredentialsProvider provider = + new DefaultCredentialsProviderTest.TestDefaultCredentialsProvider(); + provider.setProperty("os.name", "windows"); + provider.setEnv("APPDATA", ""); + + UncheckedIOException thrown = + assertThrows( + UncheckedIOException.class, + () -> GoogleAuthUtils.getWellKnownCredentialsFile(provider)); + assertTrue(thrown.getCause() instanceof FileNotFoundException); + assertTrue(thrown.getCause().getMessage().contains("APPDATA")); + assertTrue(thrown.getCause().getMessage().contains("not set or empty")); + } + + @Test + void getWellKnownCredentialsFile_windows_blankAppData_throwsUncheckedIOException() { + DefaultCredentialsProviderTest.TestDefaultCredentialsProvider provider = + new DefaultCredentialsProviderTest.TestDefaultCredentialsProvider(); + provider.setProperty("os.name", "windows"); + provider.setEnv("APPDATA", " "); + + UncheckedIOException thrown = + assertThrows( + UncheckedIOException.class, + () -> GoogleAuthUtils.getWellKnownCredentialsFile(provider)); + assertTrue(thrown.getCause() instanceof FileNotFoundException); + assertTrue(thrown.getCause().getMessage().contains("APPDATA")); + assertTrue(thrown.getCause().getMessage().contains("not set or empty")); + } + @Test void getWellKnownCredentialsPath_correct() { DefaultCredentialsProvider provider =