/** * Get a keyfile. * * Process: * 1. If $config['keyFile'] is set, use that. * 2. If $config['keyFilePath'] is set, load the file and use that. * 3. If GOOGLE_APPLICATION_CREDENTIALS environment variable is set, load * from that location and use that. * 4. If OS-specific well-known-file is set, load from that location and use * that. * 5. Exception. :( * * @param array $config * @return array Key data * @throws GoogleException */ private function getKeyFile(array $config = []) { $config += ['keyFile' => null, 'keyFilePath' => null]; if ($config['keyFile']) { return $config['keyFile']; } if ($config['keyFilePath']) { if (!file_exists($config['keyFilePath'])) { throw new GoogleException('Given keyfile path does not exist'); } $keyFileData = json_decode(file_get_contents($config['keyFilePath']), true); if (json_last_error() !== JSON_ERROR_NONE) { throw new GoogleException('Given keyfile was invalid'); } return $keyFileData; } return CredentialsLoader::fromEnv() ?: CredentialsLoader::fromWellKnownFile(); }
/** * Obtains the default FetchAuthTokenInterface implementation to use * in this environment. * * If supplied, $scope is used to in creating the credentials instance if * this does not fallback to the Compute Engine defaults. * * @param string|array scope the scope of the access request, expressed * either as an Array or as a space-delimited String. * * @param $client GuzzleHttp\ClientInterface optional client. * @throws DomainException if no implementation can be obtained. */ public static function getCredentials($scope = null, $client = null) { $creds = CredentialsLoader::fromEnv($scope); if (!is_null($creds)) { return $creds; } $creds = CredentialsLoader::fromWellKnownFile($scope); if (!is_null($creds)) { return $creds; } if (AppIdentityCredentials::onAppEngine()) { return new AppIdentityCredentials($scope); } if (GCECredentials::onGce($client)) { return new GCECredentials(); } throw new \DomainException(self::notFound()); }
/** * Obtains the default FetchAuthTokenInterface implementation to use * in this environment. * * If supplied, $scope is used to in creating the credentials instance if * this does not fallback to the Compute Engine defaults. * * @param string|array scope the scope of the access request, expressed * either as an Array or as a space-delimited String. * @param callable $httpHandler callback which delivers psr7 request * @param array $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface $cache * * @return CredentialsLoader * * @throws DomainException if no implementation can be obtained. */ public static function getCredentials($scope = null, callable $httpHandler = null, array $cacheConfig = null, CacheItemPoolInterface $cache = null) { $creds = null; $jsonKey = CredentialsLoader::fromEnv() ?: CredentialsLoader::fromWellKnownFile(); if (!is_null($jsonKey)) { $creds = CredentialsLoader::makeCredentials($scope, $jsonKey); } if (AppIdentityCredentials::onAppEngine() && !GCECredentials::onAppEngineFlexible()) { $creds = new AppIdentityCredentials($scope); } if (GCECredentials::onGce($httpHandler)) { $creds = new GCECredentials(); } if (is_null($creds)) { throw new \DomainException(self::notFound()); } if (!is_null($cache)) { $creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache); } return $creds; }
/** * Adds auth listeners to the HTTP client based on the credentials * set in the Google API Client object * * @param GuzzleHttp\ClientInterface $http the http client object. * @param GuzzleHttp\ClientInterface $authHttp an http client for authentication. * @return void */ public function authorize(ClientInterface $http, ClientInterface $authHttp = null) { $subscriber = null; $authIdentifier = null; // if we end up needing to make an HTTP request to retrieve credentials, we // can use our existing one, but we need to throw exceptions so the error // bubbles up. $authHttp = $authHttp ?: $this->createDefaultAuthHttpClient($http); // These conditionals represent the decision tree for authentication // 1. Check for Application Default Credentials // 2. Check for API Key // 3a. Check for an Access Token // 3b. If access token exists but is expired, try to refresh it if ($this->config->get('use_application_default_credentials')) { $scopes = $this->prepareScopes(); if ($sub = $this->config->get('subject')) { // for service account domain-wide authority (impersonating a user) // @see https://developers.google.com/identity/protocols/OAuth2ServiceAccount if (!($creds = CredentialsLoader::fromEnv($scopes))) { $creds = CredentialsLoader::fromWellKnownFile($scopes); } if (!$creds instanceof ServiceAccountCredentials) { throw new DomainException('domain-wide authority requires service account credentials'); } $creds->setSub($sub); $subscriber = new AuthTokenFetcher($creds, array(), $this->cache, $authHttp); } else { $subscriber = ApplicationDefaultCredentials::getFetcher($scopes, $authHttp, array(), $this->cache); } $authIdentifier = 'google_auth'; } elseif ($key = $this->config->get('developer_key')) { // if a developer key is set, authorize using that $subscriber = new Simple(['key' => $key]); $authIdentifier = 'simple'; } elseif ($token = $this->getAccessToken()) { $scopes = $this->prepareScopes(); // add refresh subscriber to request a new token if ($this->isAccessTokenExpired() && isset($token['refresh_token'])) { $subscriber = $this->createUserRefreshCredentials($scopes, $token['refresh_token'], $authHttp); $authIdentifier = 'google_auth'; } else { $subscriber = new ScopedAccessToken(function ($scopes) use($token) { return $token['access_token']; }, (array) $scopes, []); $authIdentifier = 'scoped'; } } if ($subscriber) { $http->setDefaultOption('auth', $authIdentifier); $http->getEmitter()->attach($subscriber); $this->getLogger()->log('info', sprintf('Added listener for auth type "%s"', $authIdentifier)); } return $http; }