1 | <?php |
||||
2 | /* |
||||
3 | * Copyright 2010 Google Inc. |
||||
4 | * |
||||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||||
6 | * you may not use this file except in compliance with the License. |
||||
7 | * You may obtain a copy of the License at |
||||
8 | * |
||||
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
||||
10 | * |
||||
11 | * Unless required by applicable law or agreed to in writing, software |
||||
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
||||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
14 | * See the License for the specific language governing permissions and |
||||
15 | * limitations under the License. |
||||
16 | */ |
||||
17 | |||||
18 | use Google\Auth\ApplicationDefaultCredentials; |
||||
19 | use Google\Auth\Cache\MemoryCacheItemPool; |
||||
20 | use Google\Auth\CredentialsLoader; |
||||
21 | use Google\Auth\HttpHandler\HttpHandlerFactory; |
||||
22 | use Google\Auth\OAuth2; |
||||
23 | use Google\Auth\Credentials\ServiceAccountCredentials; |
||||
24 | use Google\Auth\Credentials\UserRefreshCredentials; |
||||
25 | use GuzzleHttp\Client; |
||||
26 | use GuzzleHttp\ClientInterface; |
||||
27 | use GuzzleHttp\Ring\Client\StreamHandler; |
||||
0 ignored issues
–
show
|
|||||
28 | use Psr\Cache\CacheItemPoolInterface; |
||||
29 | use Psr\Http\Message\RequestInterface; |
||||
30 | use Psr\Log\LoggerInterface; |
||||
31 | use Monolog\Logger; |
||||
32 | use Monolog\Handler\StreamHandler as MonologStreamHandler; |
||||
33 | use Monolog\Handler\SyslogHandler as MonologSyslogHandler; |
||||
34 | |||||
35 | /** |
||||
36 | * The Google API Client |
||||
37 | * https://github.com/google/google-api-php-client |
||||
38 | */ |
||||
39 | class Google_Client |
||||
40 | { |
||||
41 | const LIBVER = "2.2.3"; |
||||
42 | const USER_AGENT_SUFFIX = "google-api-php-client/"; |
||||
43 | const OAUTH2_REVOKE_URI = 'https://oauth2.googleapis.com/revoke'; |
||||
44 | const OAUTH2_TOKEN_URI = 'https://oauth2.googleapis.com/token'; |
||||
45 | const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth'; |
||||
46 | const API_BASE_PATH = 'https://www.googleapis.com'; |
||||
47 | |||||
48 | /** |
||||
49 | * @var Google\Auth\OAuth2 $auth |
||||
50 | */ |
||||
51 | private $auth; |
||||
52 | |||||
53 | /** |
||||
54 | * @var GuzzleHttp\ClientInterface $http |
||||
55 | */ |
||||
56 | private $http; |
||||
57 | |||||
58 | /** |
||||
59 | * @var Psr\Cache\CacheItemPoolInterface $cache |
||||
60 | */ |
||||
61 | private $cache; |
||||
62 | |||||
63 | /** |
||||
64 | * @var array access token |
||||
65 | */ |
||||
66 | private $token; |
||||
67 | |||||
68 | /** |
||||
69 | * @var array $config |
||||
70 | */ |
||||
71 | private $config; |
||||
72 | |||||
73 | /** |
||||
74 | * @var Psr\Log\LoggerInterface $logger |
||||
75 | */ |
||||
76 | private $logger; |
||||
77 | |||||
78 | /** |
||||
79 | * @var boolean $deferExecution |
||||
80 | */ |
||||
81 | private $deferExecution = false; |
||||
82 | |||||
83 | /** @var array $scopes */ |
||||
84 | // Scopes requested by the client |
||||
85 | protected $requestedScopes = []; |
||||
86 | |||||
87 | /** |
||||
88 | * Construct the Google Client. |
||||
89 | * |
||||
90 | * @param array $config |
||||
91 | */ |
||||
92 | public function __construct(array $config = array()) |
||||
93 | { |
||||
94 | $this->config = array_merge( |
||||
95 | [ |
||||
96 | 'application_name' => '', |
||||
97 | |||||
98 | // Don't change these unless you're working against a special development |
||||
99 | // or testing environment. |
||||
100 | 'base_path' => self::API_BASE_PATH, |
||||
101 | |||||
102 | // https://developers.google.com/console |
||||
103 | 'client_id' => '', |
||||
104 | 'client_secret' => '', |
||||
105 | 'redirect_uri' => null, |
||||
106 | 'state' => null, |
||||
107 | |||||
108 | // Simple API access key, also from the API console. Ensure you get |
||||
109 | // a Server key, and not a Browser key. |
||||
110 | 'developer_key' => '', |
||||
111 | |||||
112 | // For use with Google Cloud Platform |
||||
113 | // fetch the ApplicationDefaultCredentials, if applicable |
||||
114 | // @see https://developers.google.com/identity/protocols/application-default-credentials |
||||
115 | 'use_application_default_credentials' => false, |
||||
116 | 'signing_key' => null, |
||||
117 | 'signing_algorithm' => null, |
||||
118 | 'subject' => null, |
||||
119 | |||||
120 | // Other OAuth2 parameters. |
||||
121 | 'hd' => '', |
||||
122 | 'prompt' => '', |
||||
123 | 'openid.realm' => '', |
||||
124 | 'include_granted_scopes' => null, |
||||
125 | 'login_hint' => '', |
||||
126 | 'request_visible_actions' => '', |
||||
127 | 'access_type' => 'online', |
||||
128 | 'approval_prompt' => 'auto', |
||||
129 | |||||
130 | // Task Runner retry configuration |
||||
131 | // @see Google_Task_Runner |
||||
132 | 'retry' => array(), |
||||
133 | 'retry_map' => null, |
||||
134 | |||||
135 | // cache config for downstream auth caching |
||||
136 | 'cache_config' => [], |
||||
137 | |||||
138 | // function to be called when an access token is fetched |
||||
139 | // follows the signature function ($cacheKey, $accessToken) |
||||
140 | 'token_callback' => null, |
||||
141 | |||||
142 | // Service class used in Google_Client::verifyIdToken. |
||||
143 | // Explicitly pass this in to avoid setting JWT::$leeway |
||||
144 | 'jwt' => null, |
||||
145 | |||||
146 | // Setting api_format_v2 will return more detailed error messages |
||||
147 | // from certain APIs. |
||||
148 | 'api_format_v2' => false |
||||
149 | ], |
||||
150 | $config |
||||
151 | ); |
||||
152 | } |
||||
153 | |||||
154 | /** |
||||
155 | * Get a string containing the version of the library. |
||||
156 | * |
||||
157 | * @return string |
||||
158 | */ |
||||
159 | public function getLibraryVersion() |
||||
160 | { |
||||
161 | return self::LIBVER; |
||||
162 | } |
||||
163 | |||||
164 | /** |
||||
165 | * For backwards compatibility |
||||
166 | * alias for fetchAccessTokenWithAuthCode |
||||
167 | * |
||||
168 | * @param $code string code from accounts.google.com |
||||
169 | * @return array access token |
||||
170 | * @deprecated |
||||
171 | */ |
||||
172 | public function authenticate($code) |
||||
173 | { |
||||
174 | return $this->fetchAccessTokenWithAuthCode($code); |
||||
175 | } |
||||
176 | |||||
177 | /** |
||||
178 | * Attempt to exchange a code for an valid authentication token. |
||||
179 | * Helper wrapped around the OAuth 2.0 implementation. |
||||
180 | * |
||||
181 | * @param $code string code from accounts.google.com |
||||
182 | * @return array access token |
||||
183 | */ |
||||
184 | public function fetchAccessTokenWithAuthCode($code) |
||||
185 | { |
||||
186 | if (strlen($code) == 0) { |
||||
187 | throw new InvalidArgumentException("Invalid code"); |
||||
188 | } |
||||
189 | |||||
190 | $auth = $this->getOAuth2Service(); |
||||
191 | $auth->setCode($code); |
||||
192 | $auth->setRedirectUri($this->getRedirectUri()); |
||||
193 | |||||
194 | $httpHandler = HttpHandlerFactory::build($this->getHttpClient()); |
||||
195 | $creds = $auth->fetchAuthToken($httpHandler); |
||||
196 | if ($creds && isset($creds['access_token'])) { |
||||
0 ignored issues
–
show
The expression
$creds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||||
197 | $creds['created'] = time(); |
||||
198 | $this->setAccessToken($creds); |
||||
199 | } |
||||
200 | |||||
201 | return $creds; |
||||
202 | } |
||||
203 | |||||
204 | /** |
||||
205 | * For backwards compatibility |
||||
206 | * alias for fetchAccessTokenWithAssertion |
||||
207 | * |
||||
208 | * @return array access token |
||||
209 | * @deprecated |
||||
210 | */ |
||||
211 | public function refreshTokenWithAssertion() |
||||
212 | { |
||||
213 | return $this->fetchAccessTokenWithAssertion(); |
||||
214 | } |
||||
215 | |||||
216 | /** |
||||
217 | * Fetches a fresh access token with a given assertion token. |
||||
218 | * @param ClientInterface $authHttp optional. |
||||
219 | * @return array access token |
||||
220 | */ |
||||
221 | public function fetchAccessTokenWithAssertion(ClientInterface $authHttp = null) |
||||
222 | { |
||||
223 | if (!$this->isUsingApplicationDefaultCredentials()) { |
||||
224 | throw new DomainException( |
||||
225 | 'set the JSON service account credentials using' |
||||
226 | . ' Google_Client::setAuthConfig or set the path to your JSON file' |
||||
227 | . ' with the "GOOGLE_APPLICATION_CREDENTIALS" environment variable' |
||||
228 | . ' and call Google_Client::useApplicationDefaultCredentials to' |
||||
229 | . ' refresh a token with assertion.' |
||||
230 | ); |
||||
231 | } |
||||
232 | |||||
233 | $this->getLogger()->log( |
||||
234 | 'info', |
||||
235 | 'OAuth2 access token refresh with Signed JWT assertion grants.' |
||||
236 | ); |
||||
237 | |||||
238 | $credentials = $this->createApplicationDefaultCredentials(); |
||||
239 | |||||
240 | $httpHandler = HttpHandlerFactory::build($authHttp); |
||||
241 | $creds = $credentials->fetchAuthToken($httpHandler); |
||||
242 | if ($creds && isset($creds['access_token'])) { |
||||
0 ignored issues
–
show
The expression
$creds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||||
243 | $creds['created'] = time(); |
||||
244 | $this->setAccessToken($creds); |
||||
245 | } |
||||
246 | |||||
247 | return $creds; |
||||
248 | } |
||||
249 | |||||
250 | /** |
||||
251 | * For backwards compatibility |
||||
252 | * alias for fetchAccessTokenWithRefreshToken |
||||
253 | * |
||||
254 | * @param string $refreshToken |
||||
255 | * @return array access token |
||||
256 | */ |
||||
257 | public function refreshToken($refreshToken) |
||||
258 | { |
||||
259 | return $this->fetchAccessTokenWithRefreshToken($refreshToken); |
||||
260 | } |
||||
261 | |||||
262 | /** |
||||
263 | * Fetches a fresh OAuth 2.0 access token with the given refresh token. |
||||
264 | * @param string $refreshToken |
||||
265 | * @return array access token |
||||
266 | */ |
||||
267 | public function fetchAccessTokenWithRefreshToken($refreshToken = null) |
||||
268 | { |
||||
269 | if (null === $refreshToken) { |
||||
270 | if (!isset($this->token['refresh_token'])) { |
||||
271 | throw new LogicException( |
||||
272 | 'refresh token must be passed in or set as part of setAccessToken' |
||||
273 | ); |
||||
274 | } |
||||
275 | $refreshToken = $this->token['refresh_token']; |
||||
276 | } |
||||
277 | $this->getLogger()->info('OAuth2 access token refresh'); |
||||
278 | $auth = $this->getOAuth2Service(); |
||||
279 | $auth->setRefreshToken($refreshToken); |
||||
280 | |||||
281 | $httpHandler = HttpHandlerFactory::build($this->getHttpClient()); |
||||
282 | $creds = $auth->fetchAuthToken($httpHandler); |
||||
283 | if ($creds && isset($creds['access_token'])) { |
||||
0 ignored issues
–
show
The expression
$creds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||||
284 | $creds['created'] = time(); |
||||
285 | if (!isset($creds['refresh_token'])) { |
||||
286 | $creds['refresh_token'] = $refreshToken; |
||||
287 | } |
||||
288 | $this->setAccessToken($creds); |
||||
289 | } |
||||
290 | |||||
291 | return $creds; |
||||
292 | } |
||||
293 | |||||
294 | /** |
||||
295 | * Create a URL to obtain user authorization. |
||||
296 | * The authorization endpoint allows the user to first |
||||
297 | * authenticate, and then grant/deny the access request. |
||||
298 | * @param string|array $scope The scope is expressed as an array or list of space-delimited strings. |
||||
299 | * @return string |
||||
300 | */ |
||||
301 | public function createAuthUrl($scope = null) |
||||
302 | { |
||||
303 | if (empty($scope)) { |
||||
304 | $scope = $this->prepareScopes(); |
||||
305 | } |
||||
306 | if (is_array($scope)) { |
||||
307 | $scope = implode(' ', $scope); |
||||
308 | } |
||||
309 | |||||
310 | // only accept one of prompt or approval_prompt |
||||
311 | $approvalPrompt = $this->config['prompt'] |
||||
312 | ? null |
||||
313 | : $this->config['approval_prompt']; |
||||
314 | |||||
315 | // include_granted_scopes should be string "true", string "false", or null |
||||
316 | $includeGrantedScopes = $this->config['include_granted_scopes'] === null |
||||
317 | ? null |
||||
318 | : var_export($this->config['include_granted_scopes'], true); |
||||
319 | |||||
320 | $params = array_filter( |
||||
321 | [ |
||||
322 | 'access_type' => $this->config['access_type'], |
||||
323 | 'approval_prompt' => $approvalPrompt, |
||||
324 | 'hd' => $this->config['hd'], |
||||
325 | 'include_granted_scopes' => $includeGrantedScopes, |
||||
326 | 'login_hint' => $this->config['login_hint'], |
||||
327 | 'openid.realm' => $this->config['openid.realm'], |
||||
328 | 'prompt' => $this->config['prompt'], |
||||
329 | 'response_type' => 'code', |
||||
330 | 'scope' => $scope, |
||||
331 | 'state' => $this->config['state'], |
||||
332 | ] |
||||
333 | ); |
||||
334 | |||||
335 | // If the list of scopes contains plus.login, add request_visible_actions |
||||
336 | // to auth URL. |
||||
337 | $rva = $this->config['request_visible_actions']; |
||||
338 | if (strlen($rva) > 0 && false !== strpos($scope, 'plus.login')) { |
||||
0 ignored issues
–
show
It seems like
$scope can also be of type array ; however, parameter $haystack of strpos() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
339 | $params['request_visible_actions'] = $rva; |
||||
340 | } |
||||
341 | |||||
342 | $auth = $this->getOAuth2Service(); |
||||
343 | |||||
344 | return (string) $auth->buildFullAuthorizationUri($params); |
||||
345 | } |
||||
346 | |||||
347 | /** |
||||
348 | * Adds auth listeners to the HTTP client based on the credentials |
||||
349 | * set in the Google API Client object |
||||
350 | * |
||||
351 | * @param GuzzleHttp\ClientInterface $http the http client object. |
||||
352 | * @return GuzzleHttp\ClientInterface the http client object |
||||
353 | */ |
||||
354 | public function authorize(ClientInterface $http = null) |
||||
355 | { |
||||
356 | $credentials = null; |
||||
357 | $token = null; |
||||
358 | $scopes = null; |
||||
359 | if (null === $http) { |
||||
360 | $http = $this->getHttpClient(); |
||||
361 | } |
||||
362 | |||||
363 | // These conditionals represent the decision tree for authentication |
||||
364 | // 1. Check for Application Default Credentials |
||||
365 | // 2. Check for API Key |
||||
366 | // 3a. Check for an Access Token |
||||
367 | // 3b. If access token exists but is expired, try to refresh it |
||||
368 | if ($this->isUsingApplicationDefaultCredentials()) { |
||||
369 | $credentials = $this->createApplicationDefaultCredentials(); |
||||
370 | } elseif ($token = $this->getAccessToken()) { |
||||
371 | $scopes = $this->prepareScopes(); |
||||
372 | // add refresh subscriber to request a new token |
||||
373 | if (isset($token['refresh_token']) && $this->isAccessTokenExpired()) { |
||||
374 | $credentials = $this->createUserRefreshCredentials( |
||||
375 | $scopes, |
||||
376 | $token['refresh_token'] |
||||
377 | ); |
||||
378 | } |
||||
379 | } |
||||
380 | |||||
381 | $authHandler = $this->getAuthHandler(); |
||||
382 | |||||
383 | if ($credentials) { |
||||
384 | $callback = $this->config['token_callback']; |
||||
385 | $http = $authHandler->attachCredentials($http, $credentials, $callback); |
||||
386 | } elseif ($token) { |
||||
387 | $http = $authHandler->attachToken($http, $token, (array) $scopes); |
||||
388 | } elseif ($key = $this->config['developer_key']) { |
||||
389 | $http = $authHandler->attachKey($http, $key); |
||||
390 | } |
||||
391 | |||||
392 | return $http; |
||||
393 | } |
||||
394 | |||||
395 | /** |
||||
396 | * Set the configuration to use application default credentials for |
||||
397 | * authentication |
||||
398 | * |
||||
399 | * @see https://developers.google.com/identity/protocols/application-default-credentials |
||||
400 | * @param boolean $useAppCreds |
||||
401 | */ |
||||
402 | public function useApplicationDefaultCredentials($useAppCreds = true) |
||||
403 | { |
||||
404 | $this->config['use_application_default_credentials'] = $useAppCreds; |
||||
405 | } |
||||
406 | |||||
407 | /** |
||||
408 | * To prevent useApplicationDefaultCredentials from inappropriately being |
||||
409 | * called in a conditional |
||||
410 | * |
||||
411 | * @see https://developers.google.com/identity/protocols/application-default-credentials |
||||
412 | */ |
||||
413 | public function isUsingApplicationDefaultCredentials() |
||||
414 | { |
||||
415 | return $this->config['use_application_default_credentials']; |
||||
416 | } |
||||
417 | |||||
418 | /** |
||||
419 | * @param string|array $token |
||||
420 | * @throws InvalidArgumentException |
||||
421 | */ |
||||
422 | public function setAccessToken($token) |
||||
423 | { |
||||
424 | if (is_string($token)) { |
||||
425 | if ($json = json_decode($token, true)) { |
||||
426 | $token = $json; |
||||
427 | } else { |
||||
428 | // assume $token is just the token string |
||||
429 | $token = array( |
||||
430 | 'access_token' => $token, |
||||
431 | ); |
||||
432 | } |
||||
433 | } |
||||
434 | if ($token == null) { |
||||
435 | throw new InvalidArgumentException('invalid json token'); |
||||
436 | } |
||||
437 | if (!isset($token['access_token'])) { |
||||
438 | throw new InvalidArgumentException("Invalid token format"); |
||||
439 | } |
||||
440 | $this->token = $token; |
||||
441 | } |
||||
442 | |||||
443 | public function getAccessToken() |
||||
444 | { |
||||
445 | return $this->token; |
||||
446 | } |
||||
447 | |||||
448 | /** |
||||
449 | * @return string|null |
||||
450 | */ |
||||
451 | public function getRefreshToken() |
||||
452 | { |
||||
453 | if (isset($this->token['refresh_token'])) { |
||||
454 | return $this->token['refresh_token']; |
||||
455 | } |
||||
456 | |||||
457 | return null; |
||||
458 | } |
||||
459 | |||||
460 | /** |
||||
461 | * Returns if the access_token is expired. |
||||
462 | * @return bool Returns True if the access_token is expired. |
||||
463 | */ |
||||
464 | public function isAccessTokenExpired() |
||||
465 | { |
||||
466 | if (!$this->token) { |
||||
0 ignored issues
–
show
The expression
$this->token of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||||
467 | return true; |
||||
468 | } |
||||
469 | |||||
470 | $created = 0; |
||||
471 | if (isset($this->token['created'])) { |
||||
472 | $created = $this->token['created']; |
||||
473 | } elseif (isset($this->token['id_token'])) { |
||||
474 | // check the ID token for "iat" |
||||
475 | // signature verification is not required here, as we are just |
||||
476 | // using this for convenience to save a round trip request |
||||
477 | // to the Google API server |
||||
478 | $idToken = $this->token['id_token']; |
||||
479 | if (substr_count($idToken, '.') == 2) { |
||||
480 | $parts = explode('.', $idToken); |
||||
481 | $payload = json_decode(base64_decode($parts[1]), true); |
||||
482 | if ($payload && isset($payload['iat'])) { |
||||
483 | $created = $payload['iat']; |
||||
484 | } |
||||
485 | } |
||||
486 | } |
||||
487 | |||||
488 | // If the token is set to expire in the next 30 seconds. |
||||
489 | return ($created + ($this->token['expires_in'] - 30)) < time(); |
||||
490 | } |
||||
491 | |||||
492 | /** |
||||
493 | * @deprecated See UPGRADING.md for more information |
||||
494 | */ |
||||
495 | public function getAuth() |
||||
496 | { |
||||
497 | throw new BadMethodCallException( |
||||
498 | 'This function no longer exists. See UPGRADING.md for more information' |
||||
499 | ); |
||||
500 | } |
||||
501 | |||||
502 | /** |
||||
503 | * @deprecated See UPGRADING.md for more information |
||||
504 | */ |
||||
505 | public function setAuth($auth) |
||||
0 ignored issues
–
show
The parameter
$auth is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
506 | { |
||||
507 | throw new BadMethodCallException( |
||||
508 | 'This function no longer exists. See UPGRADING.md for more information' |
||||
509 | ); |
||||
510 | } |
||||
511 | |||||
512 | /** |
||||
513 | * Set the OAuth 2.0 Client ID. |
||||
514 | * @param string $clientId |
||||
515 | */ |
||||
516 | public function setClientId($clientId) |
||||
517 | { |
||||
518 | $this->config['client_id'] = $clientId; |
||||
519 | } |
||||
520 | |||||
521 | public function getClientId() |
||||
522 | { |
||||
523 | return $this->config['client_id']; |
||||
524 | } |
||||
525 | |||||
526 | /** |
||||
527 | * Set the OAuth 2.0 Client Secret. |
||||
528 | * @param string $clientSecret |
||||
529 | */ |
||||
530 | public function setClientSecret($clientSecret) |
||||
531 | { |
||||
532 | $this->config['client_secret'] = $clientSecret; |
||||
533 | } |
||||
534 | |||||
535 | public function getClientSecret() |
||||
536 | { |
||||
537 | return $this->config['client_secret']; |
||||
538 | } |
||||
539 | |||||
540 | /** |
||||
541 | * Set the OAuth 2.0 Redirect URI. |
||||
542 | * @param string $redirectUri |
||||
543 | */ |
||||
544 | public function setRedirectUri($redirectUri) |
||||
545 | { |
||||
546 | $this->config['redirect_uri'] = $redirectUri; |
||||
547 | } |
||||
548 | |||||
549 | public function getRedirectUri() |
||||
550 | { |
||||
551 | return $this->config['redirect_uri']; |
||||
552 | } |
||||
553 | |||||
554 | /** |
||||
555 | * Set OAuth 2.0 "state" parameter to achieve per-request customization. |
||||
556 | * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2 |
||||
557 | * @param string $state |
||||
558 | */ |
||||
559 | public function setState($state) |
||||
560 | { |
||||
561 | $this->config['state'] = $state; |
||||
562 | } |
||||
563 | |||||
564 | /** |
||||
565 | * @param string $accessType Possible values for access_type include: |
||||
566 | * {@code "offline"} to request offline access from the user. |
||||
567 | * {@code "online"} to request online access from the user. |
||||
568 | */ |
||||
569 | public function setAccessType($accessType) |
||||
570 | { |
||||
571 | $this->config['access_type'] = $accessType; |
||||
572 | } |
||||
573 | |||||
574 | /** |
||||
575 | * @param string $approvalPrompt Possible values for approval_prompt include: |
||||
576 | * {@code "force"} to force the approval UI to appear. |
||||
577 | * {@code "auto"} to request auto-approval when possible. (This is the default value) |
||||
578 | */ |
||||
579 | public function setApprovalPrompt($approvalPrompt) |
||||
580 | { |
||||
581 | $this->config['approval_prompt'] = $approvalPrompt; |
||||
582 | } |
||||
583 | |||||
584 | /** |
||||
585 | * Set the login hint, email address or sub id. |
||||
586 | * @param string $loginHint |
||||
587 | */ |
||||
588 | public function setLoginHint($loginHint) |
||||
589 | { |
||||
590 | $this->config['login_hint'] = $loginHint; |
||||
591 | } |
||||
592 | |||||
593 | /** |
||||
594 | * Set the application name, this is included in the User-Agent HTTP header. |
||||
595 | * @param string $applicationName |
||||
596 | */ |
||||
597 | public function setApplicationName($applicationName) |
||||
598 | { |
||||
599 | $this->config['application_name'] = $applicationName; |
||||
600 | } |
||||
601 | |||||
602 | /** |
||||
603 | * If 'plus.login' is included in the list of requested scopes, you can use |
||||
604 | * this method to define types of app activities that your app will write. |
||||
605 | * You can find a list of available types here: |
||||
606 | * @link https://developers.google.com/+/api/moment-types |
||||
607 | * |
||||
608 | * @param array $requestVisibleActions Array of app activity types |
||||
609 | */ |
||||
610 | public function setRequestVisibleActions($requestVisibleActions) |
||||
611 | { |
||||
612 | if (is_array($requestVisibleActions)) { |
||||
0 ignored issues
–
show
|
|||||
613 | $requestVisibleActions = implode(" ", $requestVisibleActions); |
||||
614 | } |
||||
615 | $this->config['request_visible_actions'] = $requestVisibleActions; |
||||
616 | } |
||||
617 | |||||
618 | /** |
||||
619 | * Set the developer key to use, these are obtained through the API Console. |
||||
620 | * @see http://code.google.com/apis/console-help/#generatingdevkeys |
||||
621 | * @param string $developerKey |
||||
622 | */ |
||||
623 | public function setDeveloperKey($developerKey) |
||||
624 | { |
||||
625 | $this->config['developer_key'] = $developerKey; |
||||
626 | } |
||||
627 | |||||
628 | /** |
||||
629 | * Set the hd (hosted domain) parameter streamlines the login process for |
||||
630 | * Google Apps hosted accounts. By including the domain of the user, you |
||||
631 | * restrict sign-in to accounts at that domain. |
||||
632 | * @param $hd string - the domain to use. |
||||
633 | */ |
||||
634 | public function setHostedDomain($hd) |
||||
635 | { |
||||
636 | $this->config['hd'] = $hd; |
||||
637 | } |
||||
638 | |||||
639 | /** |
||||
640 | * Set the prompt hint. Valid values are none, consent and select_account. |
||||
641 | * If no value is specified and the user has not previously authorized |
||||
642 | * access, then the user is shown a consent screen. |
||||
643 | * @param $prompt string |
||||
644 | * {@code "none"} Do not display any authentication or consent screens. Must not be specified with other values. |
||||
645 | * {@code "consent"} Prompt the user for consent. |
||||
646 | * {@code "select_account"} Prompt the user to select an account. |
||||
647 | */ |
||||
648 | public function setPrompt($prompt) |
||||
649 | { |
||||
650 | $this->config['prompt'] = $prompt; |
||||
651 | } |
||||
652 | |||||
653 | /** |
||||
654 | * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth |
||||
655 | * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which |
||||
656 | * an authentication request is valid. |
||||
657 | * @param $realm string - the URL-space to use. |
||||
658 | */ |
||||
659 | public function setOpenidRealm($realm) |
||||
660 | { |
||||
661 | $this->config['openid.realm'] = $realm; |
||||
662 | } |
||||
663 | |||||
664 | /** |
||||
665 | * If this is provided with the value true, and the authorization request is |
||||
666 | * granted, the authorization will include any previous authorizations |
||||
667 | * granted to this user/application combination for other scopes. |
||||
668 | * @param $include boolean - the URL-space to use. |
||||
669 | */ |
||||
670 | public function setIncludeGrantedScopes($include) |
||||
671 | { |
||||
672 | $this->config['include_granted_scopes'] = $include; |
||||
673 | } |
||||
674 | |||||
675 | /** |
||||
676 | * sets function to be called when an access token is fetched |
||||
677 | * @param callable $tokenCallback - function ($cacheKey, $accessToken) |
||||
678 | */ |
||||
679 | public function setTokenCallback(callable $tokenCallback) |
||||
680 | { |
||||
681 | $this->config['token_callback'] = $tokenCallback; |
||||
682 | } |
||||
683 | |||||
684 | /** |
||||
685 | * Revoke an OAuth2 access token or refresh token. This method will revoke the current access |
||||
686 | * token, if a token isn't provided. |
||||
687 | * |
||||
688 | * @param string|array|null $token The token (access token or a refresh token) that should be revoked. |
||||
689 | * @return boolean Returns True if the revocation was successful, otherwise False. |
||||
690 | */ |
||||
691 | public function revokeToken($token = null) |
||||
692 | { |
||||
693 | $tokenRevoker = new Google_AccessToken_Revoke( |
||||
694 | $this->getHttpClient() |
||||
695 | ); |
||||
696 | |||||
697 | return $tokenRevoker->revokeToken($token ?: $this->getAccessToken()); |
||||
698 | } |
||||
699 | |||||
700 | /** |
||||
701 | * Verify an id_token. This method will verify the current id_token, if one |
||||
702 | * isn't provided. |
||||
703 | * |
||||
704 | * @throws LogicException If no token was provided and no token was set using `setAccessToken`. |
||||
705 | * @throws UnexpectedValueException If the token is not a valid JWT. |
||||
706 | * @param string|null $idToken The token (id_token) that should be verified. |
||||
707 | * @return array|false Returns the token payload as an array if the verification was |
||||
708 | * successful, false otherwise. |
||||
709 | */ |
||||
710 | public function verifyIdToken($idToken = null) |
||||
711 | { |
||||
712 | $tokenVerifier = new Google_AccessToken_Verify( |
||||
713 | $this->getHttpClient(), |
||||
714 | $this->getCache(), |
||||
715 | $this->config['jwt'] |
||||
716 | ); |
||||
717 | |||||
718 | if (null === $idToken) { |
||||
719 | $token = $this->getAccessToken(); |
||||
720 | if (!isset($token['id_token'])) { |
||||
721 | throw new LogicException( |
||||
722 | 'id_token must be passed in or set as part of setAccessToken' |
||||
723 | ); |
||||
724 | } |
||||
725 | $idToken = $token['id_token']; |
||||
726 | } |
||||
727 | |||||
728 | return $tokenVerifier->verifyIdToken( |
||||
729 | $idToken, |
||||
730 | $this->getClientId() |
||||
731 | ); |
||||
732 | } |
||||
733 | |||||
734 | /** |
||||
735 | * Set the scopes to be requested. Must be called before createAuthUrl(). |
||||
736 | * Will remove any previously configured scopes. |
||||
737 | * @param string|array $scope_or_scopes, ie: array('https://www.googleapis.com/auth/plus.login', |
||||
738 | * 'https://www.googleapis.com/auth/moderator') |
||||
739 | */ |
||||
740 | public function setScopes($scope_or_scopes) |
||||
741 | { |
||||
742 | $this->requestedScopes = array(); |
||||
743 | $this->addScope($scope_or_scopes); |
||||
744 | } |
||||
745 | |||||
746 | /** |
||||
747 | * This functions adds a scope to be requested as part of the OAuth2.0 flow. |
||||
748 | * Will append any scopes not previously requested to the scope parameter. |
||||
749 | * A single string will be treated as a scope to request. An array of strings |
||||
750 | * will each be appended. |
||||
751 | * @param $scope_or_scopes string|array e.g. "profile" |
||||
752 | */ |
||||
753 | public function addScope($scope_or_scopes) |
||||
754 | { |
||||
755 | if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) { |
||||
756 | $this->requestedScopes[] = $scope_or_scopes; |
||||
757 | } else if (is_array($scope_or_scopes)) { |
||||
758 | foreach ($scope_or_scopes as $scope) { |
||||
759 | $this->addScope($scope); |
||||
760 | } |
||||
761 | } |
||||
762 | } |
||||
763 | |||||
764 | /** |
||||
765 | * Returns the list of scopes requested by the client |
||||
766 | * @return array the list of scopes |
||||
767 | * |
||||
768 | */ |
||||
769 | public function getScopes() |
||||
770 | { |
||||
771 | return $this->requestedScopes; |
||||
772 | } |
||||
773 | |||||
774 | /** |
||||
775 | * @return string|null |
||||
776 | * @visible For Testing |
||||
777 | */ |
||||
778 | public function prepareScopes() |
||||
779 | { |
||||
780 | if (empty($this->requestedScopes)) { |
||||
781 | return null; |
||||
782 | } |
||||
783 | |||||
784 | return implode(' ', $this->requestedScopes); |
||||
785 | } |
||||
786 | |||||
787 | /** |
||||
788 | * Helper method to execute deferred HTTP requests. |
||||
789 | * |
||||
790 | * @param $request Psr\Http\Message\RequestInterface|Google_Http_Batch |
||||
791 | * @throws Google_Exception |
||||
792 | * @return object of the type of the expected class or Psr\Http\Message\ResponseInterface. |
||||
793 | */ |
||||
794 | public function execute(RequestInterface $request, $expectedClass = null) |
||||
795 | { |
||||
796 | $request = $request->withHeader( |
||||
797 | 'User-Agent', |
||||
798 | $this->config['application_name'] |
||||
799 | . " " . self::USER_AGENT_SUFFIX |
||||
800 | . $this->getLibraryVersion() |
||||
801 | ); |
||||
802 | |||||
803 | if ($this->config['api_format_v2']) { |
||||
804 | $request = $request->withHeader( |
||||
805 | 'X-GOOG-API-FORMAT-VERSION', |
||||
806 | 2 |
||||
807 | ); |
||||
808 | } |
||||
809 | |||||
810 | // call the authorize method |
||||
811 | // this is where most of the grunt work is done |
||||
812 | $http = $this->authorize(); |
||||
813 | |||||
814 | return Google_Http_REST::execute( |
||||
0 ignored issues
–
show
|
|||||
815 | $http, |
||||
816 | $request, |
||||
817 | $expectedClass, |
||||
818 | $this->config['retry'], |
||||
819 | $this->config['retry_map'] |
||||
820 | ); |
||||
821 | } |
||||
822 | |||||
823 | /** |
||||
824 | * Declare whether batch calls should be used. This may increase throughput |
||||
825 | * by making multiple requests in one connection. |
||||
826 | * |
||||
827 | * @param boolean $useBatch True if the batch support should |
||||
828 | * be enabled. Defaults to False. |
||||
829 | */ |
||||
830 | public function setUseBatch($useBatch) |
||||
831 | { |
||||
832 | // This is actually an alias for setDefer. |
||||
833 | $this->setDefer($useBatch); |
||||
834 | } |
||||
835 | |||||
836 | /** |
||||
837 | * Are we running in Google AppEngine? |
||||
838 | * return bool |
||||
839 | */ |
||||
840 | public function isAppEngine() |
||||
841 | { |
||||
842 | return (isset($_SERVER['SERVER_SOFTWARE']) && |
||||
843 | strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false); |
||||
844 | } |
||||
845 | |||||
846 | public function setConfig($name, $value) |
||||
847 | { |
||||
848 | $this->config[$name] = $value; |
||||
849 | } |
||||
850 | |||||
851 | public function getConfig($name, $default = null) |
||||
852 | { |
||||
853 | return isset($this->config[$name]) ? $this->config[$name] : $default; |
||||
854 | } |
||||
855 | |||||
856 | /** |
||||
857 | * For backwards compatibility |
||||
858 | * alias for setAuthConfig |
||||
859 | * |
||||
860 | * @param string $file the configuration file |
||||
861 | * @throws Google_Exception |
||||
862 | * @deprecated |
||||
863 | */ |
||||
864 | public function setAuthConfigFile($file) |
||||
865 | { |
||||
866 | $this->setAuthConfig($file); |
||||
867 | } |
||||
868 | |||||
869 | /** |
||||
870 | * Set the auth config from new or deprecated JSON config. |
||||
871 | * This structure should match the file downloaded from |
||||
872 | * the "Download JSON" button on in the Google Developer |
||||
873 | * Console. |
||||
874 | * @param string|array $config the configuration json |
||||
875 | * @throws Google_Exception |
||||
876 | */ |
||||
877 | public function setAuthConfig($config) |
||||
878 | { |
||||
879 | if (is_string($config)) { |
||||
880 | if (!file_exists($config)) { |
||||
881 | throw new InvalidArgumentException(sprintf('file "%s" does not exist', $config)); |
||||
882 | } |
||||
883 | |||||
884 | $json = file_get_contents($config); |
||||
885 | |||||
886 | if (!$config = json_decode($json, true)) { |
||||
887 | throw new LogicException('invalid json for auth config'); |
||||
888 | } |
||||
889 | } |
||||
890 | |||||
891 | $key = isset($config['installed']) ? 'installed' : 'web'; |
||||
892 | if (isset($config['type']) && $config['type'] == 'service_account') { |
||||
893 | // application default credentials |
||||
894 | $this->useApplicationDefaultCredentials(); |
||||
895 | |||||
896 | // set the information from the config |
||||
897 | $this->setClientId($config['client_id']); |
||||
898 | $this->config['client_email'] = $config['client_email']; |
||||
899 | $this->config['signing_key'] = $config['private_key']; |
||||
900 | $this->config['signing_algorithm'] = 'HS256'; |
||||
901 | } elseif (isset($config[$key])) { |
||||
902 | // old-style |
||||
903 | $this->setClientId($config[$key]['client_id']); |
||||
904 | $this->setClientSecret($config[$key]['client_secret']); |
||||
905 | if (isset($config[$key]['redirect_uris'])) { |
||||
906 | $this->setRedirectUri($config[$key]['redirect_uris'][0]); |
||||
907 | } |
||||
908 | } else { |
||||
909 | // new-style |
||||
910 | $this->setClientId($config['client_id']); |
||||
911 | $this->setClientSecret($config['client_secret']); |
||||
912 | if (isset($config['redirect_uris'])) { |
||||
913 | $this->setRedirectUri($config['redirect_uris'][0]); |
||||
914 | } |
||||
915 | } |
||||
916 | } |
||||
917 | |||||
918 | /** |
||||
919 | * Use when the service account has been delegated domain wide access. |
||||
920 | * |
||||
921 | * @param string $subject an email address account to impersonate |
||||
922 | */ |
||||
923 | public function setSubject($subject) |
||||
924 | { |
||||
925 | $this->config['subject'] = $subject; |
||||
926 | } |
||||
927 | |||||
928 | /** |
||||
929 | * Declare whether making API calls should make the call immediately, or |
||||
930 | * return a request which can be called with ->execute(); |
||||
931 | * |
||||
932 | * @param boolean $defer True if calls should not be executed right away. |
||||
933 | */ |
||||
934 | public function setDefer($defer) |
||||
935 | { |
||||
936 | $this->deferExecution = $defer; |
||||
937 | } |
||||
938 | |||||
939 | /** |
||||
940 | * Whether or not to return raw requests |
||||
941 | * @return boolean |
||||
942 | */ |
||||
943 | public function shouldDefer() |
||||
944 | { |
||||
945 | return $this->deferExecution; |
||||
946 | } |
||||
947 | |||||
948 | /** |
||||
949 | * @return Google\Auth\OAuth2 implementation |
||||
950 | */ |
||||
951 | public function getOAuth2Service() |
||||
952 | { |
||||
953 | if (!isset($this->auth)) { |
||||
954 | $this->auth = $this->createOAuth2Service(); |
||||
955 | } |
||||
956 | |||||
957 | return $this->auth; |
||||
958 | } |
||||
959 | |||||
960 | /** |
||||
961 | * create a default google auth object |
||||
962 | */ |
||||
963 | protected function createOAuth2Service() |
||||
964 | { |
||||
965 | $auth = new OAuth2( |
||||
966 | [ |
||||
967 | 'clientId' => $this->getClientId(), |
||||
968 | 'clientSecret' => $this->getClientSecret(), |
||||
969 | 'authorizationUri' => self::OAUTH2_AUTH_URL, |
||||
970 | 'tokenCredentialUri' => self::OAUTH2_TOKEN_URI, |
||||
971 | 'redirectUri' => $this->getRedirectUri(), |
||||
972 | 'issuer' => $this->config['client_id'], |
||||
973 | 'signingKey' => $this->config['signing_key'], |
||||
974 | 'signingAlgorithm' => $this->config['signing_algorithm'], |
||||
975 | ] |
||||
976 | ); |
||||
977 | |||||
978 | return $auth; |
||||
979 | } |
||||
980 | |||||
981 | /** |
||||
982 | * Set the Cache object |
||||
983 | * @param Psr\Cache\CacheItemPoolInterface $cache |
||||
984 | */ |
||||
985 | public function setCache(CacheItemPoolInterface $cache) |
||||
986 | { |
||||
987 | $this->cache = $cache; |
||||
988 | } |
||||
989 | |||||
990 | /** |
||||
991 | * @return Psr\Cache\CacheItemPoolInterface Cache implementation |
||||
992 | */ |
||||
993 | public function getCache() |
||||
994 | { |
||||
995 | if (!$this->cache) { |
||||
996 | $this->cache = $this->createDefaultCache(); |
||||
997 | } |
||||
998 | |||||
999 | return $this->cache; |
||||
1000 | } |
||||
1001 | |||||
1002 | /** |
||||
1003 | * @param array $cacheConfig |
||||
1004 | */ |
||||
1005 | public function setCacheConfig(array $cacheConfig) |
||||
1006 | { |
||||
1007 | $this->config['cache_config'] = $cacheConfig; |
||||
1008 | } |
||||
1009 | |||||
1010 | /** |
||||
1011 | * Set the Logger object |
||||
1012 | * @param Psr\Log\LoggerInterface $logger |
||||
1013 | */ |
||||
1014 | public function setLogger(LoggerInterface $logger) |
||||
1015 | { |
||||
1016 | $this->logger = $logger; |
||||
1017 | } |
||||
1018 | |||||
1019 | /** |
||||
1020 | * @return Psr\Log\LoggerInterface implementation |
||||
1021 | */ |
||||
1022 | public function getLogger() |
||||
1023 | { |
||||
1024 | if (!isset($this->logger)) { |
||||
1025 | $this->logger = $this->createDefaultLogger(); |
||||
1026 | } |
||||
1027 | |||||
1028 | return $this->logger; |
||||
1029 | } |
||||
1030 | |||||
1031 | protected function createDefaultLogger() |
||||
1032 | { |
||||
1033 | $logger = new Logger('google-api-php-client'); |
||||
1034 | if ($this->isAppEngine()) { |
||||
1035 | $handler = new MonologSyslogHandler('app', LOG_USER, Logger::NOTICE); |
||||
1036 | } else { |
||||
1037 | $handler = new MonologStreamHandler('php://stderr', Logger::NOTICE); |
||||
1038 | } |
||||
1039 | $logger->pushHandler($handler); |
||||
1040 | |||||
1041 | return $logger; |
||||
1042 | } |
||||
1043 | |||||
1044 | protected function createDefaultCache() |
||||
1045 | { |
||||
1046 | return new MemoryCacheItemPool; |
||||
1047 | } |
||||
1048 | |||||
1049 | /** |
||||
1050 | * Set the Http Client object |
||||
1051 | * @param GuzzleHttp\ClientInterface $http |
||||
1052 | */ |
||||
1053 | public function setHttpClient(ClientInterface $http) |
||||
1054 | { |
||||
1055 | $this->http = $http; |
||||
1056 | } |
||||
1057 | |||||
1058 | /** |
||||
1059 | * @return GuzzleHttp\ClientInterface implementation |
||||
1060 | */ |
||||
1061 | public function getHttpClient() |
||||
1062 | { |
||||
1063 | if (null === $this->http) { |
||||
1064 | $this->http = $this->createDefaultHttpClient(); |
||||
1065 | } |
||||
1066 | |||||
1067 | return $this->http; |
||||
1068 | } |
||||
1069 | |||||
1070 | /** |
||||
1071 | * Set the API format version. |
||||
1072 | * |
||||
1073 | * `true` will use V2, which may return more useful error messages. |
||||
1074 | * |
||||
1075 | * @param bool $value |
||||
1076 | */ |
||||
1077 | public function setApiFormatV2($value) |
||||
1078 | { |
||||
1079 | $this->config['api_format_v2'] = (bool) $value; |
||||
1080 | } |
||||
1081 | |||||
1082 | protected function createDefaultHttpClient() |
||||
1083 | { |
||||
1084 | $options = ['exceptions' => false]; |
||||
1085 | |||||
1086 | $version = ClientInterface::VERSION; |
||||
0 ignored issues
–
show
|
|||||
1087 | if ('5' === $version[0]) { |
||||
1088 | $options = [ |
||||
1089 | 'base_url' => $this->config['base_path'], |
||||
1090 | 'defaults' => $options, |
||||
1091 | ]; |
||||
1092 | if ($this->isAppEngine()) { |
||||
1093 | // set StreamHandler on AppEngine by default |
||||
1094 | $options['handler'] = new StreamHandler(); |
||||
1095 | $options['defaults']['verify'] = '/etc/ca-certificates.crt'; |
||||
1096 | } |
||||
1097 | } else { |
||||
1098 | // guzzle 6 |
||||
1099 | $options['base_uri'] = $this->config['base_path']; |
||||
1100 | } |
||||
1101 | |||||
1102 | return new Client($options); |
||||
1103 | } |
||||
1104 | |||||
1105 | private function createApplicationDefaultCredentials() |
||||
1106 | { |
||||
1107 | $scopes = $this->prepareScopes(); |
||||
1108 | $sub = $this->config['subject']; |
||||
1109 | $signingKey = $this->config['signing_key']; |
||||
1110 | |||||
1111 | // create credentials using values supplied in setAuthConfig |
||||
1112 | if ($signingKey) { |
||||
1113 | $serviceAccountCredentials = array( |
||||
1114 | 'client_id' => $this->config['client_id'], |
||||
1115 | 'client_email' => $this->config['client_email'], |
||||
1116 | 'private_key' => $signingKey, |
||||
1117 | 'type' => 'service_account', |
||||
1118 | ); |
||||
1119 | $credentials = CredentialsLoader::makeCredentials($scopes, $serviceAccountCredentials); |
||||
1120 | } else { |
||||
1121 | $credentials = ApplicationDefaultCredentials::getCredentials($scopes); |
||||
1122 | } |
||||
1123 | |||||
1124 | // for service account domain-wide authority (impersonating a user) |
||||
1125 | // @see https://developers.google.com/identity/protocols/OAuth2ServiceAccount |
||||
1126 | if ($sub) { |
||||
1127 | if (!$credentials instanceof ServiceAccountCredentials) { |
||||
1128 | throw new DomainException('domain-wide authority requires service account credentials'); |
||||
1129 | } |
||||
1130 | |||||
1131 | $credentials->setSub($sub); |
||||
1132 | } |
||||
1133 | |||||
1134 | return $credentials; |
||||
1135 | } |
||||
1136 | |||||
1137 | protected function getAuthHandler() |
||||
1138 | { |
||||
1139 | // Be very careful using the cache, as the underlying auth library's cache |
||||
1140 | // implementation is naive, and the cache keys do not account for user |
||||
1141 | // sessions. |
||||
1142 | // |
||||
1143 | // @see https://github.com/google/google-api-php-client/issues/821 |
||||
1144 | return Google_AuthHandler_AuthHandlerFactory::build( |
||||
1145 | $this->getCache(), |
||||
1146 | $this->config['cache_config'] |
||||
1147 | ); |
||||
1148 | } |
||||
1149 | |||||
1150 | private function createUserRefreshCredentials($scope, $refreshToken) |
||||
1151 | { |
||||
1152 | $creds = array_filter( |
||||
1153 | array( |
||||
1154 | 'client_id' => $this->getClientId(), |
||||
1155 | 'client_secret' => $this->getClientSecret(), |
||||
1156 | 'refresh_token' => $refreshToken, |
||||
1157 | ) |
||||
1158 | ); |
||||
1159 | |||||
1160 | return new UserRefreshCredentials($scope, $creds); |
||||
1161 | } |
||||
1162 | } |
||||
1163 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths