All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rt.storage.auth.oauth2.DefaultCredentialsProvider Maven / Gradle / Ivy

package com.rt.storage.auth.oauth2;

import com.rt.storage.auth.http.HttpTransportFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessControlException;
import java.util.Collections;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Provides the Application Default Credential from the environment.
 *
 * 

An instance represents the per-process state used to get and cache the credential and allows * overriding the state and environment for testing purposes. */ class DefaultCredentialsProvider { static final DefaultCredentialsProvider DEFAULT = new DefaultCredentialsProvider(); static final String CREDENTIAL_ENV_VAR = "GOOGLE_APPLICATION_CREDENTIALS"; static final String WELL_KNOWN_CREDENTIALS_FILE = "application_default_credentials.json"; static final String CLOUDSDK_CONFIG_DIRECTORY = "gcloud"; static final String HELP_PERMALINK = "https://developers.google.com/accounts/docs/application-default-credentials"; static final String APP_ENGINE_SIGNAL_CLASS = "com.google.appengine.api.utils.SystemProperty"; static final String CLOUD_SHELL_ENV_VAR = "DEVSHELL_CLIENT_PORT"; static final String SKIP_APP_ENGINE_ENV_VAR = "GOOGLE_APPLICATION_CREDENTIALS_SKIP_APP_ENGINE"; static final String SPECIFICATION_VERSION = System.getProperty("java.specification.version"); static final String GAE_RUNTIME_VERSION = System.getProperty("com.google.appengine.runtime.version"); static final String RUNTIME_JETTY_LOGGER = System.getProperty("org.eclipse.jetty.util.log.class"); static final Logger LOGGER = Logger.getLogger(DefaultCredentialsProvider.class.getName()); static final String NO_GCE_CHECK_ENV_VAR = "NO_GCE_CHECK"; static final String GCE_METADATA_HOST_ENV_VAR = "GCE_METADATA_HOST"; static final String CLOUDSDK_CLIENT_ID = "764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com"; static final String CLOUDSDK_CREDENTIALS_WARNING = "Your application has authenticated using end user credentials from Google " + "Cloud SDK. We recommend that most server applications use service accounts " + "instead. If your application continues to use end user credentials from Cloud " + "SDK, you might receive a \"quota exceeded\" or \"API not enabled\" error. For " + "more information about service accounts, see " + "https://cloud.google.com/docs/authentication/."; public static final String SUPPRESS_GCLOUD_CREDS_WARNING_ENV_VAR = "SUPPRESS_GCLOUD_CREDS_WARNING"; // These variables should only be accessed inside a synchronized block private RtStorageCredentials cachedCredentials = null; private boolean checkedAppEngine = false; private boolean checkedComputeEngine = false; DefaultCredentialsProvider() {} /** * Returns the Application Default Credentials. * *

Returns the Application Default Credentials which are used to identify and authorize the * whole application. The following are searched (in order) to find the Application Default * Credentials: * * * @param transportFactory HTTP transport factory, creates the transport used to get access * tokens. * @return the credentials instance. * @throws IOException if the credentials cannot be created in the current environment. */ final RtStorageCredentials getDefaultCredentials(HttpTransportFactory transportFactory) throws IOException { synchronized (this) { if (cachedCredentials == null) { cachedCredentials = getDefaultCredentialsUnsynchronized(transportFactory); } if (cachedCredentials != null) { return cachedCredentials; } } throw new IOException( String.format( "The Application Default Credentials are not available. They are available if running" + " in Google Compute Engine. Otherwise, the environment variable %s must be defined" + " pointing to a file defining the credentials. See %s for more information.", CREDENTIAL_ENV_VAR, HELP_PERMALINK)); } private final RtStorageCredentials getDefaultCredentialsUnsynchronized( HttpTransportFactory transportFactory) throws IOException { // First try the environment variable RtStorageCredentials credentials = null; String credentialsPath = getEnv(CREDENTIAL_ENV_VAR); if (credentialsPath != null && credentialsPath.length() > 0) { InputStream credentialsStream = null; try { File credentialsFile = new File(credentialsPath); if (!isFile(credentialsFile)) { // Path will be put in the message from the catch block below throw new IOException("File does not exist."); } credentialsStream = readStream(credentialsFile); credentials = RtStorageCredentials.fromStream(credentialsStream, transportFactory); } catch (IOException e) { // Although it is also the cause, the message of the caught exception can have very // important information for diagnosing errors, so include its message in the // outer exception message also. throw new IOException( String.format( "Error reading credential file from environment variable %s, value '%s': %s", CREDENTIAL_ENV_VAR, credentialsPath, e.getMessage()), e); } catch (AccessControlException expected) { // Exception querying file system is expected on App-Engine } finally { if (credentialsStream != null) { credentialsStream.close(); } } } // Then try the well-known file if (credentials == null) { File wellKnownFileLocation = getWellKnownCredentialsFile(); InputStream credentialsStream = null; try { if (isFile(wellKnownFileLocation)) { credentialsStream = readStream(wellKnownFileLocation); credentials = RtStorageCredentials.fromStream(credentialsStream, transportFactory); } } catch (IOException e) { throw new IOException( String.format( "Error reading credential file from location %s: %s", wellKnownFileLocation, e.getMessage())); } catch (AccessControlException expected) { // Exception querying file system is expected on App-Engine } finally { if (credentialsStream != null) { credentialsStream.close(); } } warnAboutProblematicCredentials(credentials); } return credentials; } private void warnAboutProblematicCredentials(RtStorageCredentials credentials) { if (credentials instanceof UserCredentials && ((UserCredentials) credentials).getClientId().equals(CLOUDSDK_CLIENT_ID) && !Boolean.parseBoolean(getEnv(SUPPRESS_GCLOUD_CREDS_WARNING_ENV_VAR))) { LOGGER.log(Level.WARNING, CLOUDSDK_CREDENTIALS_WARNING); } } private final File getWellKnownCredentialsFile() { File cloudConfigPath; String os = getProperty("os.name", "").toLowerCase(Locale.US); String envPath = getEnv("CLOUDSDK_CONFIG"); if (envPath != null) { cloudConfigPath = new File(envPath); } else if (os.indexOf("windows") >= 0) { File appDataPath = new File(getEnv("APPDATA")); cloudConfigPath = new File(appDataPath, CLOUDSDK_CONFIG_DIRECTORY); } else { File configPath = new File(getProperty("user.home", ""), ".config"); cloudConfigPath = new File(configPath, CLOUDSDK_CONFIG_DIRECTORY); } return new File(cloudConfigPath, WELL_KNOWN_CREDENTIALS_FILE); } private boolean runningOnAppEngine() { Class systemPropertyClass = null; try { systemPropertyClass = forName(APP_ENGINE_SIGNAL_CLASS); } catch (ClassNotFoundException expected) { // SystemProperty will always be present on App Engine. return false; } Exception cause; Field environmentField; try { environmentField = systemPropertyClass.getField("environment"); Object environmentValue = environmentField.get(null); Class environmentType = environmentField.getType(); Method valueMethod = environmentType.getMethod("value"); Object environmentValueValue = valueMethod.invoke(environmentValue); return (environmentValueValue != null); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InvocationTargetException exception) { cause = exception; } throw new RuntimeException( String.format( "Unexpected error trying to determine if runnning on Google App Engine: %s", cause.getMessage()), cause); } // Skip app engine check if environment variable private boolean skipAppEngineCredentialsCheck() { boolean skip = false; // do not skip by default String value = getEnv(SKIP_APP_ENGINE_ENV_VAR); if (value != null) { skip = value.equalsIgnoreCase("true") || value.equals("1"); } return skip; } protected boolean isOnGAEStandard7() { return GAE_RUNTIME_VERSION != null && (SPECIFICATION_VERSION.equals("1.7") || RUNTIME_JETTY_LOGGER == null); } /* * Start of methods to allow overriding in the test code to isolate from the environment. */ Class forName(String className) throws ClassNotFoundException { return Class.forName(className); } String getEnv(String name) { return System.getenv(name); } String getProperty(String property, String def) { return System.getProperty(property, def); } boolean isFile(File file) { return file.isFile(); } InputStream readStream(File file) throws FileNotFoundException { return new FileInputStream(file); } /* * End of methods to allow overriding in the test code to isolate from the environment. */ }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy