123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128 |
- <?php
- /*
- * Copyright 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- use Google\Auth\ApplicationDefaultCredentials;
- use Google\Auth\Cache\MemoryCacheItemPool;
- use Google\Auth\CredentialsLoader;
- use Google\Auth\HttpHandler\HttpHandlerFactory;
- use Google\Auth\OAuth2;
- use Google\Auth\Credentials\ServiceAccountCredentials;
- use Google\Auth\Credentials\UserRefreshCredentials;
- use GuzzleHttp\Client;
- use GuzzleHttp\ClientInterface;
- use GuzzleHttp\Ring\Client\StreamHandler;
- use Psr\Cache\CacheItemPoolInterface;
- use Psr\Http\Message\RequestInterface;
- use Psr\Log\LoggerInterface;
- use Monolog\Logger;
- use Monolog\Handler\StreamHandler as MonologStreamHandler;
- use Monolog\Handler\SyslogHandler as MonologSyslogHandler;
-
- /**
- * The Google API Client
- * https://github.com/google/google-api-php-client
- */
- class Google_Client
- {
- const LIBVER = "2.2.2";
- const USER_AGENT_SUFFIX = "google-api-php-client/";
- const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
- const OAUTH2_TOKEN_URI = 'https://www.googleapis.com/oauth2/v4/token';
- const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
- const API_BASE_PATH = 'https://www.googleapis.com';
-
- /**
- * @var Google\Auth\OAuth2 $auth
- */
- private $auth;
-
- /**
- * @var GuzzleHttp\ClientInterface $http
- */
- private $http;
-
- /**
- * @var Psr\Cache\CacheItemPoolInterface $cache
- */
- private $cache;
-
- /**
- * @var array access token
- */
- private $token;
-
- /**
- * @var array $config
- */
- private $config;
-
- /**
- * @var Psr\Log\LoggerInterface $logger
- */
- private $logger;
-
- /**
- * @var boolean $deferExecution
- */
- private $deferExecution = false;
-
- /** @var array $scopes */
- // Scopes requested by the client
- protected $requestedScopes = [];
-
- /**
- * Construct the Google Client.
- *
- * @param array $config
- */
- public function __construct(array $config = array())
- {
- $this->config = array_merge(
- [
- 'application_name' => '',
-
- // Don't change these unless you're working against a special development
- // or testing environment.
- 'base_path' => self::API_BASE_PATH,
-
- // https://developers.google.com/console
- 'client_id' => '',
- 'client_secret' => '',
- 'redirect_uri' => null,
- 'state' => null,
-
- // Simple API access key, also from the API console. Ensure you get
- // a Server key, and not a Browser key.
- 'developer_key' => '',
-
- // For use with Google Cloud Platform
- // fetch the ApplicationDefaultCredentials, if applicable
- // @see https://developers.google.com/identity/protocols/application-default-credentials
- 'use_application_default_credentials' => false,
- 'signing_key' => null,
- 'signing_algorithm' => null,
- 'subject' => null,
-
- // Other OAuth2 parameters.
- 'hd' => '',
- 'prompt' => '',
- 'openid.realm' => '',
- 'include_granted_scopes' => null,
- 'login_hint' => '',
- 'request_visible_actions' => '',
- 'access_type' => 'online',
- 'approval_prompt' => 'auto',
-
- // Task Runner retry configuration
- // @see Google_Task_Runner
- 'retry' => array(),
-
- // cache config for downstream auth caching
- 'cache_config' => [],
-
- // function to be called when an access token is fetched
- // follows the signature function ($cacheKey, $accessToken)
- 'token_callback' => null,
-
- // Service class used in Google_Client::verifyIdToken.
- // Explicitly pass this in to avoid setting JWT::$leeway
- 'jwt' => null,
- ],
- $config
- );
- }
-
- /**
- * Get a string containing the version of the library.
- *
- * @return string
- */
- public function getLibraryVersion()
- {
- return self::LIBVER;
- }
-
- /**
- * For backwards compatibility
- * alias for fetchAccessTokenWithAuthCode
- *
- * @param $code string code from accounts.google.com
- * @return array access token
- * @deprecated
- */
- public function authenticate($code)
- {
- return $this->fetchAccessTokenWithAuthCode($code);
- }
-
- /**
- * Attempt to exchange a code for an valid authentication token.
- * Helper wrapped around the OAuth 2.0 implementation.
- *
- * @param $code string code from accounts.google.com
- * @return array access token
- */
- public function fetchAccessTokenWithAuthCode($code)
- {
- if (strlen($code) == 0) {
- throw new InvalidArgumentException("Invalid code");
- }
-
- $auth = $this->getOAuth2Service();
- $auth->setCode($code);
- $auth->setRedirectUri($this->getRedirectUri());
-
- $httpHandler = HttpHandlerFactory::build($this->getHttpClient());
- $creds = $auth->fetchAuthToken($httpHandler);
- if ($creds && isset($creds['access_token'])) {
- $creds['created'] = time();
- $this->setAccessToken($creds);
- }
-
- return $creds;
- }
-
- /**
- * For backwards compatibility
- * alias for fetchAccessTokenWithAssertion
- *
- * @return array access token
- * @deprecated
- */
- public function refreshTokenWithAssertion()
- {
- return $this->fetchAccessTokenWithAssertion();
- }
-
- /**
- * Fetches a fresh access token with a given assertion token.
- * @param ClientInterface $authHttp optional.
- * @return array access token
- */
- public function fetchAccessTokenWithAssertion(ClientInterface $authHttp = null)
- {
- if (!$this->isUsingApplicationDefaultCredentials()) {
- throw new DomainException(
- 'set the JSON service account credentials using'
- . ' Google_Client::setAuthConfig or set the path to your JSON file'
- . ' with the "GOOGLE_APPLICATION_CREDENTIALS" environment variable'
- . ' and call Google_Client::useApplicationDefaultCredentials to'
- . ' refresh a token with assertion.'
- );
- }
-
- $this->getLogger()->log(
- 'info',
- 'OAuth2 access token refresh with Signed JWT assertion grants.'
- );
-
- $credentials = $this->createApplicationDefaultCredentials();
-
- $httpHandler = HttpHandlerFactory::build($authHttp);
- $creds = $credentials->fetchAuthToken($httpHandler);
- if ($creds && isset($creds['access_token'])) {
- $creds['created'] = time();
- $this->setAccessToken($creds);
- }
-
- return $creds;
- }
-
- /**
- * For backwards compatibility
- * alias for fetchAccessTokenWithRefreshToken
- *
- * @param string $refreshToken
- * @return array access token
- */
- public function refreshToken($refreshToken)
- {
- return $this->fetchAccessTokenWithRefreshToken($refreshToken);
- }
-
- /**
- * Fetches a fresh OAuth 2.0 access token with the given refresh token.
- * @param string $refreshToken
- * @return array access token
- */
- public function fetchAccessTokenWithRefreshToken($refreshToken = null)
- {
- if (null === $refreshToken) {
- if (!isset($this->token['refresh_token'])) {
- throw new LogicException(
- 'refresh token must be passed in or set as part of setAccessToken'
- );
- }
- $refreshToken = $this->token['refresh_token'];
- }
- $this->getLogger()->info('OAuth2 access token refresh');
- $auth = $this->getOAuth2Service();
- $auth->setRefreshToken($refreshToken);
-
- $httpHandler = HttpHandlerFactory::build($this->getHttpClient());
- $creds = $auth->fetchAuthToken($httpHandler);
- if ($creds && isset($creds['access_token'])) {
- $creds['created'] = time();
- if (!isset($creds['refresh_token'])) {
- $creds['refresh_token'] = $refreshToken;
- }
- $this->setAccessToken($creds);
- }
-
- return $creds;
- }
-
- /**
- * Create a URL to obtain user authorization.
- * The authorization endpoint allows the user to first
- * authenticate, and then grant/deny the access request.
- * @param string|array $scope The scope is expressed as an array or list of space-delimited strings.
- * @return string
- */
- public function createAuthUrl($scope = null)
- {
- if (empty($scope)) {
- $scope = $this->prepareScopes();
- }
- if (is_array($scope)) {
- $scope = implode(' ', $scope);
- }
-
- // only accept one of prompt or approval_prompt
- $approvalPrompt = $this->config['prompt']
- ? null
- : $this->config['approval_prompt'];
-
- // include_granted_scopes should be string "true", string "false", or null
- $includeGrantedScopes = $this->config['include_granted_scopes'] === null
- ? null
- : var_export($this->config['include_granted_scopes'], true);
-
- $params = array_filter(
- [
- 'access_type' => $this->config['access_type'],
- 'approval_prompt' => $approvalPrompt,
- 'hd' => $this->config['hd'],
- 'include_granted_scopes' => $includeGrantedScopes,
- 'login_hint' => $this->config['login_hint'],
- 'openid.realm' => $this->config['openid.realm'],
- 'prompt' => $this->config['prompt'],
- 'response_type' => 'code',
- 'scope' => $scope,
- 'state' => $this->config['state'],
- ]
- );
-
- // If the list of scopes contains plus.login, add request_visible_actions
- // to auth URL.
- $rva = $this->config['request_visible_actions'];
- if (strlen($rva) > 0 && false !== strpos($scope, 'plus.login')) {
- $params['request_visible_actions'] = $rva;
- }
-
- $auth = $this->getOAuth2Service();
-
- return (string) $auth->buildFullAuthorizationUri($params);
- }
-
- /**
- * 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.
- * @return GuzzleHttp\ClientInterface the http client object
- */
- public function authorize(ClientInterface $http = null)
- {
- $credentials = null;
- $token = null;
- $scopes = null;
- if (null === $http) {
- $http = $this->getHttpClient();
- }
-
- // 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->isUsingApplicationDefaultCredentials()) {
- $credentials = $this->createApplicationDefaultCredentials();
- } elseif ($token = $this->getAccessToken()) {
- $scopes = $this->prepareScopes();
- // add refresh subscriber to request a new token
- if (isset($token['refresh_token']) && $this->isAccessTokenExpired()) {
- $credentials = $this->createUserRefreshCredentials(
- $scopes,
- $token['refresh_token']
- );
- }
- }
-
- $authHandler = $this->getAuthHandler();
-
- if ($credentials) {
- $callback = $this->config['token_callback'];
- $http = $authHandler->attachCredentials($http, $credentials, $callback);
- } elseif ($token) {
- $http = $authHandler->attachToken($http, $token, (array) $scopes);
- } elseif ($key = $this->config['developer_key']) {
- $http = $authHandler->attachKey($http, $key);
- }
-
- return $http;
- }
-
- /**
- * Set the configuration to use application default credentials for
- * authentication
- *
- * @see https://developers.google.com/identity/protocols/application-default-credentials
- * @param boolean $useAppCreds
- */
- public function useApplicationDefaultCredentials($useAppCreds = true)
- {
- $this->config['use_application_default_credentials'] = $useAppCreds;
- }
-
- /**
- * To prevent useApplicationDefaultCredentials from inappropriately being
- * called in a conditional
- *
- * @see https://developers.google.com/identity/protocols/application-default-credentials
- */
- public function isUsingApplicationDefaultCredentials()
- {
- return $this->config['use_application_default_credentials'];
- }
-
- /**
- * @param string|array $token
- * @throws InvalidArgumentException
- */
- public function setAccessToken($token)
- {
- if (is_string($token)) {
- if ($json = json_decode($token, true)) {
- $token = $json;
- } else {
- // assume $token is just the token string
- $token = array(
- 'access_token' => $token,
- );
- }
- }
- if ($token == null) {
- throw new InvalidArgumentException('invalid json token');
- }
- if (!isset($token['access_token'])) {
- throw new InvalidArgumentException("Invalid token format");
- }
- $this->token = $token;
- }
-
- public function getAccessToken()
- {
- return $this->token;
- }
-
- /**
- * @return string|null
- */
- public function getRefreshToken()
- {
- if (isset($this->token['refresh_token'])) {
- return $this->token['refresh_token'];
- }
-
- return null;
- }
-
- /**
- * Returns if the access_token is expired.
- * @return bool Returns True if the access_token is expired.
- */
- public function isAccessTokenExpired()
- {
- if (!$this->token) {
- return true;
- }
-
- $created = 0;
- if (isset($this->token['created'])) {
- $created = $this->token['created'];
- } elseif (isset($this->token['id_token'])) {
- // check the ID token for "iat"
- // signature verification is not required here, as we are just
- // using this for convenience to save a round trip request
- // to the Google API server
- $idToken = $this->token['id_token'];
- if (substr_count($idToken, '.') == 2) {
- $parts = explode('.', $idToken);
- $payload = json_decode(base64_decode($parts[1]), true);
- if ($payload && isset($payload['iat'])) {
- $created = $payload['iat'];
- }
- }
- }
-
- // If the token is set to expire in the next 30 seconds.
- return ($created + ($this->token['expires_in'] - 30)) < time();
- }
-
- /**
- * @deprecated See UPGRADING.md for more information
- */
- public function getAuth()
- {
- throw new BadMethodCallException(
- 'This function no longer exists. See UPGRADING.md for more information'
- );
- }
-
- /**
- * @deprecated See UPGRADING.md for more information
- */
- public function setAuth($auth)
- {
- throw new BadMethodCallException(
- 'This function no longer exists. See UPGRADING.md for more information'
- );
- }
-
- /**
- * Set the OAuth 2.0 Client ID.
- * @param string $clientId
- */
- public function setClientId($clientId)
- {
- $this->config['client_id'] = $clientId;
- }
-
- public function getClientId()
- {
- return $this->config['client_id'];
- }
-
- /**
- * Set the OAuth 2.0 Client Secret.
- * @param string $clientSecret
- */
- public function setClientSecret($clientSecret)
- {
- $this->config['client_secret'] = $clientSecret;
- }
-
- public function getClientSecret()
- {
- return $this->config['client_secret'];
- }
-
- /**
- * Set the OAuth 2.0 Redirect URI.
- * @param string $redirectUri
- */
- public function setRedirectUri($redirectUri)
- {
- $this->config['redirect_uri'] = $redirectUri;
- }
-
- public function getRedirectUri()
- {
- return $this->config['redirect_uri'];
- }
-
- /**
- * Set OAuth 2.0 "state" parameter to achieve per-request customization.
- * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
- * @param string $state
- */
- public function setState($state)
- {
- $this->config['state'] = $state;
- }
-
- /**
- * @param string $accessType Possible values for access_type include:
- * {@code "offline"} to request offline access from the user.
- * {@code "online"} to request online access from the user.
- */
- public function setAccessType($accessType)
- {
- $this->config['access_type'] = $accessType;
- }
-
- /**
- * @param string $approvalPrompt Possible values for approval_prompt include:
- * {@code "force"} to force the approval UI to appear.
- * {@code "auto"} to request auto-approval when possible. (This is the default value)
- */
- public function setApprovalPrompt($approvalPrompt)
- {
- $this->config['approval_prompt'] = $approvalPrompt;
- }
-
- /**
- * Set the login hint, email address or sub id.
- * @param string $loginHint
- */
- public function setLoginHint($loginHint)
- {
- $this->config['login_hint'] = $loginHint;
- }
-
- /**
- * Set the application name, this is included in the User-Agent HTTP header.
- * @param string $applicationName
- */
- public function setApplicationName($applicationName)
- {
- $this->config['application_name'] = $applicationName;
- }
-
- /**
- * If 'plus.login' is included in the list of requested scopes, you can use
- * this method to define types of app activities that your app will write.
- * You can find a list of available types here:
- * @link https://developers.google.com/+/api/moment-types
- *
- * @param array $requestVisibleActions Array of app activity types
- */
- public function setRequestVisibleActions($requestVisibleActions)
- {
- if (is_array($requestVisibleActions)) {
- $requestVisibleActions = implode(" ", $requestVisibleActions);
- }
- $this->config['request_visible_actions'] = $requestVisibleActions;
- }
-
- /**
- * Set the developer key to use, these are obtained through the API Console.
- * @see http://code.google.com/apis/console-help/#generatingdevkeys
- * @param string $developerKey
- */
- public function setDeveloperKey($developerKey)
- {
- $this->config['developer_key'] = $developerKey;
- }
-
- /**
- * Set the hd (hosted domain) parameter streamlines the login process for
- * Google Apps hosted accounts. By including the domain of the user, you
- * restrict sign-in to accounts at that domain.
- * @param $hd string - the domain to use.
- */
- public function setHostedDomain($hd)
- {
- $this->config['hd'] = $hd;
- }
-
- /**
- * Set the prompt hint. Valid values are none, consent and select_account.
- * If no value is specified and the user has not previously authorized
- * access, then the user is shown a consent screen.
- * @param $prompt string
- */
- public function setPrompt($prompt)
- {
- $this->config['prompt'] = $prompt;
- }
-
- /**
- * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth
- * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which
- * an authentication request is valid.
- * @param $realm string - the URL-space to use.
- */
- public function setOpenidRealm($realm)
- {
- $this->config['openid.realm'] = $realm;
- }
-
- /**
- * If this is provided with the value true, and the authorization request is
- * granted, the authorization will include any previous authorizations
- * granted to this user/application combination for other scopes.
- * @param $include boolean - the URL-space to use.
- */
- public function setIncludeGrantedScopes($include)
- {
- $this->config['include_granted_scopes'] = $include;
- }
-
- /**
- * sets function to be called when an access token is fetched
- * @param callable $tokenCallback - function ($cacheKey, $accessToken)
- */
- public function setTokenCallback(callable $tokenCallback)
- {
- $this->config['token_callback'] = $tokenCallback;
- }
-
- /**
- * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
- * token, if a token isn't provided.
- *
- * @param string|null $token The token (access token or a refresh token) that should be revoked.
- * @return boolean Returns True if the revocation was successful, otherwise False.
- */
- public function revokeToken($token = null)
- {
- $tokenRevoker = new Google_AccessToken_Revoke(
- $this->getHttpClient()
- );
-
- return $tokenRevoker->revokeToken($token ?: $this->getAccessToken());
- }
-
- /**
- * Verify an id_token. This method will verify the current id_token, if one
- * isn't provided.
- *
- * @throws LogicException
- * @param string|null $idToken The token (id_token) that should be verified.
- * @return array|false Returns the token payload as an array if the verification was
- * successful, false otherwise.
- */
- public function verifyIdToken($idToken = null)
- {
- $tokenVerifier = new Google_AccessToken_Verify(
- $this->getHttpClient(),
- $this->getCache(),
- $this->config['jwt']
- );
-
- if (null === $idToken) {
- $token = $this->getAccessToken();
- if (!isset($token['id_token'])) {
- throw new LogicException(
- 'id_token must be passed in or set as part of setAccessToken'
- );
- }
- $idToken = $token['id_token'];
- }
-
- return $tokenVerifier->verifyIdToken(
- $idToken,
- $this->getClientId()
- );
- }
-
- /**
- * Set the scopes to be requested. Must be called before createAuthUrl().
- * Will remove any previously configured scopes.
- * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.login',
- * 'https://www.googleapis.com/auth/moderator')
- */
- public function setScopes($scopes)
- {
- $this->requestedScopes = array();
- $this->addScope($scopes);
- }
-
- /**
- * This functions adds a scope to be requested as part of the OAuth2.0 flow.
- * Will append any scopes not previously requested to the scope parameter.
- * A single string will be treated as a scope to request. An array of strings
- * will each be appended.
- * @param $scope_or_scopes string|array e.g. "profile"
- */
- public function addScope($scope_or_scopes)
- {
- if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) {
- $this->requestedScopes[] = $scope_or_scopes;
- } else if (is_array($scope_or_scopes)) {
- foreach ($scope_or_scopes as $scope) {
- $this->addScope($scope);
- }
- }
- }
-
- /**
- * Returns the list of scopes requested by the client
- * @return array the list of scopes
- *
- */
- public function getScopes()
- {
- return $this->requestedScopes;
- }
-
- /**
- * @return string|null
- * @visible For Testing
- */
- public function prepareScopes()
- {
- if (empty($this->requestedScopes)) {
- return null;
- }
-
- return implode(' ', $this->requestedScopes);
- }
-
- /**
- * Helper method to execute deferred HTTP requests.
- *
- * @param $request Psr\Http\Message\RequestInterface|Google_Http_Batch
- * @throws Google_Exception
- * @return object of the type of the expected class or Psr\Http\Message\ResponseInterface.
- */
- public function execute(RequestInterface $request, $expectedClass = null)
- {
- $request = $request->withHeader(
- 'User-Agent',
- $this->config['application_name']
- . " " . self::USER_AGENT_SUFFIX
- . $this->getLibraryVersion()
- );
-
- // call the authorize method
- // this is where most of the grunt work is done
- $http = $this->authorize();
-
- return Google_Http_REST::execute($http, $request, $expectedClass, $this->config['retry']);
- }
-
- /**
- * Declare whether batch calls should be used. This may increase throughput
- * by making multiple requests in one connection.
- *
- * @param boolean $useBatch True if the batch support should
- * be enabled. Defaults to False.
- */
- public function setUseBatch($useBatch)
- {
- // This is actually an alias for setDefer.
- $this->setDefer($useBatch);
- }
-
- /**
- * Are we running in Google AppEngine?
- * return bool
- */
- public function isAppEngine()
- {
- return (isset($_SERVER['SERVER_SOFTWARE']) &&
- strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false);
- }
-
- public function setConfig($name, $value)
- {
- $this->config[$name] = $value;
- }
-
- public function getConfig($name, $default = null)
- {
- return isset($this->config[$name]) ? $this->config[$name] : $default;
- }
-
- /**
- * For backwards compatibility
- * alias for setAuthConfig
- *
- * @param string $file the configuration file
- * @throws Google_Exception
- * @deprecated
- */
- public function setAuthConfigFile($file)
- {
- $this->setAuthConfig($file);
- }
-
- /**
- * Set the auth config from new or deprecated JSON config.
- * This structure should match the file downloaded from
- * the "Download JSON" button on in the Google Developer
- * Console.
- * @param string|array $config the configuration json
- * @throws Google_Exception
- */
- public function setAuthConfig($config)
- {
- if (is_string($config)) {
- if (!file_exists($config)) {
- throw new InvalidArgumentException('file does not exist');
- }
-
- $json = file_get_contents($config);
-
- if (!$config = json_decode($json, true)) {
- throw new LogicException('invalid json for auth config');
- }
- }
-
- $key = isset($config['installed']) ? 'installed' : 'web';
- if (isset($config['type']) && $config['type'] == 'service_account') {
- // application default credentials
- $this->useApplicationDefaultCredentials();
-
- // set the information from the config
- $this->setClientId($config['client_id']);
- $this->config['client_email'] = $config['client_email'];
- $this->config['signing_key'] = $config['private_key'];
- $this->config['signing_algorithm'] = 'HS256';
- } elseif (isset($config[$key])) {
- // old-style
- $this->setClientId($config[$key]['client_id']);
- $this->setClientSecret($config[$key]['client_secret']);
- if (isset($config[$key]['redirect_uris'])) {
- $this->setRedirectUri($config[$key]['redirect_uris'][0]);
- }
- } else {
- // new-style
- $this->setClientId($config['client_id']);
- $this->setClientSecret($config['client_secret']);
- if (isset($config['redirect_uris'])) {
- $this->setRedirectUri($config['redirect_uris'][0]);
- }
- }
- }
-
- /**
- * Use when the service account has been delegated domain wide access.
- *
- * @param string $subject an email address account to impersonate
- */
- public function setSubject($subject)
- {
- $this->config['subject'] = $subject;
- }
-
- /**
- * Declare whether making API calls should make the call immediately, or
- * return a request which can be called with ->execute();
- *
- * @param boolean $defer True if calls should not be executed right away.
- */
- public function setDefer($defer)
- {
- $this->deferExecution = $defer;
- }
-
- /**
- * Whether or not to return raw requests
- * @return boolean
- */
- public function shouldDefer()
- {
- return $this->deferExecution;
- }
-
- /**
- * @return Google\Auth\OAuth2 implementation
- */
- public function getOAuth2Service()
- {
- if (!isset($this->auth)) {
- $this->auth = $this->createOAuth2Service();
- }
-
- return $this->auth;
- }
-
- /**
- * create a default google auth object
- */
- protected function createOAuth2Service()
- {
- $auth = new OAuth2(
- [
- 'clientId' => $this->getClientId(),
- 'clientSecret' => $this->getClientSecret(),
- 'authorizationUri' => self::OAUTH2_AUTH_URL,
- 'tokenCredentialUri' => self::OAUTH2_TOKEN_URI,
- 'redirectUri' => $this->getRedirectUri(),
- 'issuer' => $this->config['client_id'],
- 'signingKey' => $this->config['signing_key'],
- 'signingAlgorithm' => $this->config['signing_algorithm'],
- ]
- );
-
- return $auth;
- }
-
- /**
- * Set the Cache object
- * @param Psr\Cache\CacheItemPoolInterface $cache
- */
- public function setCache(CacheItemPoolInterface $cache)
- {
- $this->cache = $cache;
- }
-
- /**
- * @return Psr\Cache\CacheItemPoolInterface Cache implementation
- */
- public function getCache()
- {
- if (!$this->cache) {
- $this->cache = $this->createDefaultCache();
- }
-
- return $this->cache;
- }
-
- /**
- * @param array $cacheConfig
- */
- public function setCacheConfig(array $cacheConfig)
- {
- $this->config['cache_config'] = $cacheConfig;
- }
-
- /**
- * Set the Logger object
- * @param Psr\Log\LoggerInterface $logger
- */
- public function setLogger(LoggerInterface $logger)
- {
- $this->logger = $logger;
- }
-
- /**
- * @return Psr\Log\LoggerInterface implementation
- */
- public function getLogger()
- {
- if (!isset($this->logger)) {
- $this->logger = $this->createDefaultLogger();
- }
-
- return $this->logger;
- }
-
- protected function createDefaultLogger()
- {
- $logger = new Logger('google-api-php-client');
- if ($this->isAppEngine()) {
- $handler = new MonologSyslogHandler('app', LOG_USER, Logger::NOTICE);
- } else {
- $handler = new MonologStreamHandler('php://stderr', Logger::NOTICE);
- }
- $logger->pushHandler($handler);
-
- return $logger;
- }
-
- protected function createDefaultCache()
- {
- return new MemoryCacheItemPool;
- }
-
- /**
- * Set the Http Client object
- * @param GuzzleHttp\ClientInterface $http
- */
- public function setHttpClient(ClientInterface $http)
- {
- $this->http = $http;
- }
-
- /**
- * @return GuzzleHttp\ClientInterface implementation
- */
- public function getHttpClient()
- {
- if (null === $this->http) {
- $this->http = $this->createDefaultHttpClient();
- }
-
- return $this->http;
- }
-
- protected function createDefaultHttpClient()
- {
- $options = ['exceptions' => false];
-
- $version = ClientInterface::VERSION;
- if ('5' === $version[0]) {
- $options = [
- 'base_url' => $this->config['base_path'],
- 'defaults' => $options,
- ];
- if ($this->isAppEngine()) {
- // set StreamHandler on AppEngine by default
- $options['handler'] = new StreamHandler();
- $options['defaults']['verify'] = '/etc/ca-certificates.crt';
- }
- } else {
- // guzzle 6
- $options['base_uri'] = $this->config['base_path'];
- }
-
- return new Client($options);
- }
-
- private function createApplicationDefaultCredentials()
- {
- $scopes = $this->prepareScopes();
- $sub = $this->config['subject'];
- $signingKey = $this->config['signing_key'];
-
- // create credentials using values supplied in setAuthConfig
- if ($signingKey) {
- $serviceAccountCredentials = array(
- 'client_id' => $this->config['client_id'],
- 'client_email' => $this->config['client_email'],
- 'private_key' => $signingKey,
- 'type' => 'service_account',
- );
- $credentials = CredentialsLoader::makeCredentials($scopes, $serviceAccountCredentials);
- } else {
- $credentials = ApplicationDefaultCredentials::getCredentials($scopes);
- }
-
- // for service account domain-wide authority (impersonating a user)
- // @see https://developers.google.com/identity/protocols/OAuth2ServiceAccount
- if ($sub) {
- if (!$credentials instanceof ServiceAccountCredentials) {
- throw new DomainException('domain-wide authority requires service account credentials');
- }
-
- $credentials->setSub($sub);
- }
-
- return $credentials;
- }
-
- protected function getAuthHandler()
- {
- // Be very careful using the cache, as the underlying auth library's cache
- // implementation is naive, and the cache keys do not account for user
- // sessions.
- //
- // @see https://github.com/google/google-api-php-client/issues/821
- return Google_AuthHandler_AuthHandlerFactory::build(
- $this->getCache(),
- $this->config['cache_config']
- );
- }
-
- private function createUserRefreshCredentials($scope, $refreshToken)
- {
- $creds = array_filter(
- array(
- 'client_id' => $this->getClientId(),
- 'client_secret' => $this->getClientSecret(),
- 'refresh_token' => $refreshToken,
- )
- );
-
- return new UserRefreshCredentials($scope, $creds);
- }
- }
|