diff --git a/src/AccessToken.php b/src/AccessToken.php index 630b27961..9e27b692e 100644 --- a/src/AccessToken.php +++ b/src/AccessToken.php @@ -65,12 +65,12 @@ class AccessToken private $cache; /** - * @param callable $httpHandler [optional] An HTTP Handler to deliver PSR-7 requests. - * @param CacheItemPoolInterface $cache [optional] A PSR-6 compatible cache implementation. + * @param callable|null $httpHandler [optional] An HTTP Handler to deliver PSR-7 requests. + * @param CacheItemPoolInterface|null $cache [optional] A PSR-6 compatible cache implementation. */ public function __construct( - callable $httpHandler = null, - CacheItemPoolInterface $cache = null + ?callable $httpHandler = null, + ?CacheItemPoolInterface $cache = null ) { $this->httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); diff --git a/src/ApplicationDefaultCredentials.php b/src/ApplicationDefaultCredentials.php index 80437c8c9..1593721f0 100644 --- a/src/ApplicationDefaultCredentials.php +++ b/src/ApplicationDefaultCredentials.php @@ -21,6 +21,7 @@ use Google\Auth\Credentials\AppIdentityCredentials; use Google\Auth\Credentials\GCECredentials; use Google\Auth\Credentials\ServiceAccountCredentials; +use Google\Auth\Credentials\UserRefreshCredentials; use Google\Auth\HttpHandler\HttpClientCache; use Google\Auth\HttpHandler\HttpHandlerFactory; use Google\Auth\Middleware\AuthTokenMiddleware; @@ -80,18 +81,18 @@ class ApplicationDefaultCredentials * * @param string|string[] $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 A cache implementation, may be + * @param callable|null $httpHandler callback which delivers psr7 request + * @param array|null $cacheConfig configuration for the cache when it's present + * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return AuthTokenSubscriber * @throws DomainException if no implementation can be obtained. */ public static function getSubscriber(// @phpstan-ignore-line $scope = null, - callable $httpHandler = null, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null + ?callable $httpHandler = null, + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $creds = self::getCredentials($scope, $httpHandler, $cacheConfig, $cache); @@ -108,9 +109,9 @@ public static function getSubscriber(// @phpstan-ignore-line * * @param string|string[] $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 A cache implementation, may be + * @param callable|null $httpHandler callback which delivers psr7 request + * @param array|null $cacheConfig configuration for the cache when it's present + * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @param string $quotaProject specifies a project to bill for access * charges associated with the request. @@ -119,9 +120,9 @@ public static function getSubscriber(// @phpstan-ignore-line */ public static function getMiddleware( $scope = null, - callable $httpHandler = null, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null, + ?callable $httpHandler = null, + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null, $quotaProject = null ) { $creds = self::getCredentials($scope, $httpHandler, $cacheConfig, $cache, $quotaProject); @@ -135,16 +136,16 @@ public static function getMiddleware( * * @param string|string[] $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 A cache implementation, may be + * @param callable|null $httpHandler callback which delivers psr7 request + * @param array|null $cacheConfig configuration for the cache when it's present + * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. - * @param string $quotaProject specifies a project to bill for access + * @param string|null $quotaProject specifies a project to bill for access * charges associated with the request. - * @param string|string[] $defaultScope The default scope to use if no + * @param string|string[]|null $defaultScope The default scope to use if no * user-defined scopes exist, expressed either as an Array or as a * space-delimited string. - * @param string $universeDomain Specifies a universe domain to use for the + * @param string|null $universeDomain Specifies a universe domain to use for the * calling client library * * @return FetchAuthTokenInterface @@ -152,12 +153,12 @@ public static function getMiddleware( */ public static function getCredentials( $scope = null, - callable $httpHandler = null, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null, + ?callable $httpHandler = null, + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null, $quotaProject = null, $defaultScope = null, - string $universeDomain = null + ?string $universeDomain = null ) { $creds = null; $jsonKey = CredentialsLoader::fromEnv() @@ -215,18 +216,18 @@ public static function getCredentials( * ID token. * * @param string $targetAudience The audience for the ID token. - * @param callable $httpHandler callback which delivers psr7 request - * @param array $cacheConfig configuration for the cache when it's present - * @param CacheItemPoolInterface $cache A cache implementation, may be + * @param callable|null $httpHandler callback which delivers psr7 request + * @param array|null $cacheConfig configuration for the cache when it's present + * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return AuthTokenMiddleware * @throws DomainException if no implementation can be obtained. */ public static function getIdTokenMiddleware( $targetAudience, - callable $httpHandler = null, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null + ?callable $httpHandler = null, + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache); @@ -242,18 +243,18 @@ public static function getIdTokenMiddleware( * ID token. * * @param string $targetAudience The audience for the ID token. - * @param callable $httpHandler callback which delivers psr7 request - * @param array $cacheConfig configuration for the cache when it's present - * @param CacheItemPoolInterface $cache A cache implementation, may be + * @param callable|null $httpHandler callback which delivers psr7 request + * @param array|null $cacheConfig configuration for the cache when it's present + * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return ProxyAuthTokenMiddleware * @throws DomainException if no implementation can be obtained. */ public static function getProxyIdTokenMiddleware( $targetAudience, - callable $httpHandler = null, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null + ?callable $httpHandler = null, + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache); @@ -266,9 +267,9 @@ public static function getProxyIdTokenMiddleware( * token. * * @param string $targetAudience The audience for the ID token. - * @param callable $httpHandler callback which delivers psr7 request - * @param array $cacheConfig configuration for the cache when it's present - * @param CacheItemPoolInterface $cache A cache implementation, may be + * @param callable|null $httpHandler callback which delivers psr7 request + * @param array|null $cacheConfig configuration for the cache when it's present + * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return FetchAuthTokenInterface * @throws DomainException if no implementation can be obtained. @@ -276,9 +277,9 @@ public static function getProxyIdTokenMiddleware( */ public static function getIdTokenCredentials( $targetAudience, - callable $httpHandler = null, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null + ?callable $httpHandler = null, + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $creds = null; $jsonKey = CredentialsLoader::fromEnv() @@ -299,14 +300,12 @@ public static function getIdTokenCredentials( } if ($jsonKey['type'] == 'authorized_user') { - throw new InvalidArgumentException('ID tokens are not supported for end user credentials'); - } - - if ($jsonKey['type'] != 'service_account') { + $creds = new UserRefreshCredentials(null, $jsonKey, $targetAudience); + } elseif ($jsonKey['type'] == 'service_account') { + $creds = new ServiceAccountCredentials(null, $jsonKey, null, $targetAudience); + } else { throw new InvalidArgumentException('invalid value in the type field'); } - - $creds = new ServiceAccountCredentials(null, $jsonKey, null, $targetAudience); } elseif (self::onGce($httpHandler, $cacheConfig, $cache)) { $creds = new GCECredentials(null, null, $targetAudience); $creds->setIsOnGce(true); // save the credentials a trip to the metadata server @@ -334,15 +333,15 @@ private static function notFound() } /** - * @param callable $httpHandler - * @param array $cacheConfig - * @param CacheItemPoolInterface $cache + * @param callable|null $httpHandler + * @param array|null $cacheConfig + * @param CacheItemPoolInterface|null $cache * @return bool */ private static function onGce( - callable $httpHandler = null, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null + ?callable $httpHandler = null, + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $gceCacheConfig = []; foreach (['lifetime', 'prefix'] as $key) { diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index e99d0ee6f..880ca1001 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -50,9 +50,9 @@ class AwsNativeSource implements ExternalAccountCredentialSourceInterface public function __construct( string $audience, string $regionalCredVerificationUrl, - string $regionUrl = null, - string $securityCredentialsUrl = null, - string $imdsv2SessionTokenUrl = null + ?string $regionUrl = null, + ?string $securityCredentialsUrl = null, + ?string $imdsv2SessionTokenUrl = null ) { $this->audience = $audience; $this->regionalCredVerificationUrl = $regionalCredVerificationUrl; @@ -61,7 +61,7 @@ public function __construct( $this->imdsv2SessionTokenUrl = $imdsv2SessionTokenUrl; } - public function fetchSubjectToken(callable $httpHandler = null): string + public function fetchSubjectToken(?callable $httpHandler = null): string { if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index ce3bd9fda..f6255bec9 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -88,12 +88,12 @@ class ExecutableSource implements ExternalAccountCredentialSourceInterface /** * @param string $command The string command to run to get the subject token. - * @param string $outputFile + * @param string|null $outputFile */ public function __construct( string $command, ?string $outputFile, - ExecutableHandler $executableHandler = null, + ?ExecutableHandler $executableHandler = null, ) { $this->command = $command; $this->outputFile = $outputFile; @@ -113,12 +113,12 @@ public function getCacheKey(): ?string } /** - * @param callable $httpHandler unused. + * @param callable|null $httpHandler unused. * @return string * @throws RuntimeException if the executable is not allowed to run. * @throws ExecutableResponseError if the executable response is invalid. */ - public function fetchSubjectToken(callable $httpHandler = null): string + public function fetchSubjectToken(?callable $httpHandler = null): string { // Check if the executable is allowed to run. if (getenv(self::GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES) !== '1') { diff --git a/src/CredentialSource/FileSource.php b/src/CredentialSource/FileSource.php index 00ac835a8..2e79119b8 100644 --- a/src/CredentialSource/FileSource.php +++ b/src/CredentialSource/FileSource.php @@ -31,15 +31,15 @@ class FileSource implements ExternalAccountCredentialSourceInterface private ?string $subjectTokenFieldName; /** - * @param string $file The file to read the subject token from. - * @param string $format The format of the token in the file. Can be null or "json". - * @param string $subjectTokenFieldName The name of the field containing the token in the file. This is required - * when format is "json". + * @param string $file The file to read the subject token from. + * @param string|null $format The format of the token in the file. Can be null or "json". + * @param string|null $subjectTokenFieldName The name of the field containing the token in the file. This is required + * when format is "json". */ public function __construct( string $file, - string $format = null, - string $subjectTokenFieldName = null + ?string $format = null, + ?string $subjectTokenFieldName = null ) { $this->file = $file; @@ -53,7 +53,7 @@ public function __construct( $this->subjectTokenFieldName = $subjectTokenFieldName; } - public function fetchSubjectToken(callable $httpHandler = null): string + public function fetchSubjectToken(?callable $httpHandler = null): string { $contents = file_get_contents($this->file); if ($this->format === 'json') { diff --git a/src/CredentialSource/UrlSource.php b/src/CredentialSource/UrlSource.php index 6046d52fa..d2f875ebf 100644 --- a/src/CredentialSource/UrlSource.php +++ b/src/CredentialSource/UrlSource.php @@ -39,17 +39,17 @@ class UrlSource implements ExternalAccountCredentialSourceInterface private ?array $headers; /** - * @param string $url The URL to fetch the subject token from. - * @param string $format The format of the token in the response. Can be null or "json". - * @param string $subjectTokenFieldName The name of the field containing the token in the response. This is required + * @param string $url The URL to fetch the subject token from. + * @param string|null $format The format of the token in the response. Can be null or "json". + * @param string|null $subjectTokenFieldName The name of the field containing the token in the response. This is required * when format is "json". - * @param array $headers Request headers to send in with the request to the URL. + * @param array|null $headers Request headers to send in with the request to the URL. */ public function __construct( string $url, - string $format = null, - string $subjectTokenFieldName = null, - array $headers = null + ?string $format = null, + ?string $subjectTokenFieldName = null, + ?array $headers = null ) { $this->url = $url; @@ -64,7 +64,7 @@ public function __construct( $this->headers = $headers; } - public function fetchSubjectToken(callable $httpHandler = null): string + public function fetchSubjectToken(?callable $httpHandler = null): string { if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); diff --git a/src/Credentials/AppIdentityCredentials.php b/src/Credentials/AppIdentityCredentials.php index db29438ab..5e4cfa53a 100644 --- a/src/Credentials/AppIdentityCredentials.php +++ b/src/Credentials/AppIdentityCredentials.php @@ -116,7 +116,7 @@ public static function onAppEngine() * As the AppIdentityService uses protobufs to fetch the access token, * the GuzzleHttp\ClientInterface instance passed in will not be used. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array { * A set of auth related metadata, containing the following * @@ -124,7 +124,7 @@ public static function onAppEngine() * @type string $expiration_time * } */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { try { $this->checkAppEngineContext(); @@ -161,10 +161,10 @@ public function signBlob($stringToSign, $forceOpenSsl = false) * * Returns null if AppIdentityService is unavailable. * - * @param callable $httpHandler Not used by this type. + * @param callable|null $httpHandler Not used by this type. * @return string|null */ - public function getProjectId(callable $httpHandler = null) + public function getProjectId(?callable $httpHandler = null) { try { $this->checkAppEngineContext(); @@ -181,11 +181,11 @@ public function getProjectId(callable $httpHandler = null) * * Subsequent calls to this method will return a cached value. * - * @param callable $httpHandler Not used in this implementation. + * @param callable|null $httpHandler Not used in this implementation. * @return string * @throws \Exception If AppEngine SDK or mock is not available. */ - public function getClientName(callable $httpHandler = null) + public function getClientName(?callable $httpHandler = null) { $this->checkAppEngineContext(); diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 3614d24d0..21ed1b602 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -211,7 +211,7 @@ private static function buildCredentialSource(array $jsonKey): ExternalAccountCr /** * @param string $stsToken - * @param callable $httpHandler + * @param callable|null $httpHandler * * @return array { * A set of auth related metadata, containing the following @@ -220,7 +220,7 @@ private static function buildCredentialSource(array $jsonKey): ExternalAccountCr * @type int $expires_at * } */ - private function getImpersonatedAccessToken(string $stsToken, callable $httpHandler = null): array + private function getImpersonatedAccessToken(string $stsToken, ?callable $httpHandler = null): array { if (!isset($this->serviceAccountImpersonationUrl)) { throw new InvalidArgumentException( @@ -251,7 +251,7 @@ private function getImpersonatedAccessToken(string $stsToken, callable $httpHand } /** - * @param callable $httpHandler + * @param callable|null $httpHandler * * @return array { * A set of auth related metadata, containing the following @@ -263,7 +263,7 @@ private function getImpersonatedAccessToken(string $stsToken, callable $httpHand * @type string $token_type (identity pool only) * } */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { $stsToken = $this->auth->fetchAuthToken($httpHandler); @@ -325,13 +325,13 @@ public function getUniverseDomain(): string /** * Get the project ID. * - * @param callable $httpHandler Callback which delivers psr7 request - * @param string $accessToken The access token to use to sign the blob. If + * @param callable|null $httpHandler Callback which delivers psr7 request + * @param string|null $accessToken The access token to use to sign the blob. If * provided, saves a call to the metadata server for a new access * token. **Defaults to** `null`. * @return string|null */ - public function getProjectId(callable $httpHandler = null, string $accessToken = null) + public function getProjectId(?callable $httpHandler = null, ?string $accessToken = null) { if (isset($this->projectId)) { return $this->projectId; diff --git a/src/Credentials/GCECredentials.php b/src/Credentials/GCECredentials.php index 49030a845..235b34a60 100644 --- a/src/Credentials/GCECredentials.php +++ b/src/Credentials/GCECredentials.php @@ -199,7 +199,7 @@ class GCECredentials extends CredentialsLoader implements private ?string $universeDomain; /** - * @param Iam $iam [optional] An IAM instance. + * @param Iam|null $iam [optional] An IAM instance. * @param string|string[] $scope [optional] the scope of the access request, * expressed either as an array or as a space-delimited string. * @param string $targetAudience [optional] The audience for the ID token. @@ -207,16 +207,16 @@ class GCECredentials extends CredentialsLoader implements * charges associated with the request. * @param string $serviceAccountIdentity [optional] Specify a service * account identity name to use instead of "default". - * @param string $universeDomain [optional] Specify a universe domain to use + * @param string|null $universeDomain [optional] Specify a universe domain to use * instead of fetching one from the metadata server. */ public function __construct( - Iam $iam = null, + ?Iam $iam = null, $scope = null, $targetAudience = null, $quotaProject = null, $serviceAccountIdentity = null, - string $universeDomain = null + ?string $universeDomain = null ) { $this->iam = $iam; @@ -355,10 +355,10 @@ public static function onAppEngineFlexible() * host. * If $httpHandler is not specified a the default HttpHandler is used. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return bool True if this a GCEInstance, false otherwise */ - public static function onGce(callable $httpHandler = null) + public static function onGce(?callable $httpHandler = null) { $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); @@ -441,7 +441,7 @@ private static function detectResidencyWindows(string $registryProductKey): bool * Fetches the auth tokens from the GCE metadata host if it is available. * If $httpHandler is not specified a the default HttpHandler is used. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * * @return array { * A set of auth related metadata, based on the token type. @@ -453,7 +453,7 @@ private static function detectResidencyWindows(string $registryProductKey): bool * } * @throws \Exception */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); @@ -524,10 +524,10 @@ public function getLastReceivedToken() * * Subsequent calls will return a cached value. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return string */ - public function getClientName(callable $httpHandler = null) + public function getClientName(?callable $httpHandler = null) { if ($this->clientName) { return $this->clientName; @@ -558,10 +558,10 @@ public function getClientName(callable $httpHandler = null) * * Returns null if called outside GCE. * - * @param callable $httpHandler Callback which delivers psr7 request + * @param callable|null $httpHandler Callback which delivers psr7 request * @return string|null */ - public function getProjectId(callable $httpHandler = null) + public function getProjectId(?callable $httpHandler = null) { if ($this->projectId) { return $this->projectId; @@ -586,10 +586,10 @@ public function getProjectId(callable $httpHandler = null) /** * Fetch the default universe domain from the metadata server. * - * @param callable $httpHandler Callback which delivers psr7 request + * @param callable|null $httpHandler Callback which delivers psr7 request * @return string */ - public function getUniverseDomain(callable $httpHandler = null): string + public function getUniverseDomain(?callable $httpHandler = null): string { if (null !== $this->universeDomain) { return $this->universeDomain; diff --git a/src/Credentials/IAMCredentials.php b/src/Credentials/IAMCredentials.php index 98780c6e0..96d1df734 100644 --- a/src/Credentials/IAMCredentials.php +++ b/src/Credentials/IAMCredentials.php @@ -71,7 +71,7 @@ public function getUpdateMetadataFunc() * * @param array $metadata metadata hashmap * @param string $unusedAuthUri optional auth uri - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * Note: this param is unused here, only included here for * consistency with other credentials class * @@ -80,7 +80,7 @@ public function getUpdateMetadataFunc() public function updateMetadata( $metadata, $unusedAuthUri = null, - callable $httpHandler = null + ?callable $httpHandler = null ) { $metadata_copy = $metadata; $metadata_copy[self::SELECTOR_KEY] = $this->selector; diff --git a/src/Credentials/ImpersonatedServiceAccountCredentials.php b/src/Credentials/ImpersonatedServiceAccountCredentials.php index 5d3522827..c34a1539b 100644 --- a/src/Credentials/ImpersonatedServiceAccountCredentials.php +++ b/src/Credentials/ImpersonatedServiceAccountCredentials.php @@ -103,13 +103,13 @@ private function getImpersonatedServiceAccountNameFromUrl( * @param callable|null $unusedHttpHandler not used by this credentials type. * @return string Token issuer email */ - public function getClientName(callable $unusedHttpHandler = null) + public function getClientName(?callable $unusedHttpHandler = null) { return $this->impersonatedServiceAccountName; } /** - * @param callable $httpHandler + * @param callable|null $httpHandler * * @return array { * A set of auth related metadata, containing the following @@ -121,7 +121,7 @@ public function getClientName(callable $unusedHttpHandler = null) * @type string $id_token * } */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { // We don't support id token endpoint requests as of now for Impersonated Cred return $this->sourceCredentials->fetchAuthToken( diff --git a/src/Credentials/InsecureCredentials.php b/src/Credentials/InsecureCredentials.php index 9b9e24b11..5a2bef1c5 100644 --- a/src/Credentials/InsecureCredentials.php +++ b/src/Credentials/InsecureCredentials.php @@ -36,10 +36,10 @@ class InsecureCredentials implements FetchAuthTokenInterface /** * Fetches the auth token. In this case it returns an empty string. * - * @param callable $httpHandler + * @param callable|null $httpHandler * @return array{access_token:string} A set of auth related metadata */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { return $this->token; } diff --git a/src/Credentials/ServiceAccountCredentials.php b/src/Credentials/ServiceAccountCredentials.php index 5c651bb71..c13b22921 100644 --- a/src/Credentials/ServiceAccountCredentials.php +++ b/src/Credentials/ServiceAccountCredentials.php @@ -193,7 +193,7 @@ public function useJwtAccessWithScope() } /** - * @param callable $httpHandler + * @param callable|null $httpHandler * * @return array { * A set of auth related metadata, containing the following @@ -203,7 +203,7 @@ public function useJwtAccessWithScope() * @type string $token_type * } */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { if ($this->useSelfSignedJwt()) { $jwtCreds = $this->createJwtAccessCredentials(); @@ -287,10 +287,10 @@ public function getLastReceivedToken() * * Returns null if the project ID does not exist in the keyfile. * - * @param callable $httpHandler Not used by this credentials type. + * @param callable|null $httpHandler Not used by this credentials type. * @return string|null */ - public function getProjectId(callable $httpHandler = null) + public function getProjectId(?callable $httpHandler = null) { return $this->projectId; } @@ -300,13 +300,13 @@ public function getProjectId(callable $httpHandler = null) * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, - callable $httpHandler = null + ?callable $httpHandler = null ) { // scope exists. use oauth implementation if (!$this->useSelfSignedJwt()) { @@ -364,10 +364,10 @@ public function setSub($sub) * * In this case, it returns the keyfile's client_email key. * - * @param callable $httpHandler Not used by this credentials type. + * @param callable|null $httpHandler Not used by this credentials type. * @return string */ - public function getClientName(callable $httpHandler = null) + public function getClientName(?callable $httpHandler = null) { return $this->auth->getIssuer(); } diff --git a/src/Credentials/ServiceAccountJwtAccessCredentials.php b/src/Credentials/ServiceAccountJwtAccessCredentials.php index 7bdc21848..50373760b 100644 --- a/src/Credentials/ServiceAccountJwtAccessCredentials.php +++ b/src/Credentials/ServiceAccountJwtAccessCredentials.php @@ -114,13 +114,13 @@ public function __construct($jsonKey, $scope = null) * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, - callable $httpHandler = null + ?callable $httpHandler = null ) { $scope = $this->auth->getScope(); if (empty($authUri) && empty($scope)) { @@ -135,11 +135,11 @@ public function updateMetadata( /** * Implements FetchAuthTokenInterface#fetchAuthToken. * - * @param callable $httpHandler + * @param callable|null $httpHandler * * @return null|array{access_token:string} A set of auth related metadata */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { $audience = $this->auth->getAudience(); $scope = $this->auth->getScope(); @@ -196,10 +196,10 @@ public function getLastReceivedToken() * * Returns null if the project ID does not exist in the keyfile. * - * @param callable $httpHandler Not used by this credentials type. + * @param callable|null $httpHandler Not used by this credentials type. * @return string|null */ - public function getProjectId(callable $httpHandler = null) + public function getProjectId(?callable $httpHandler = null) { return $this->projectId; } @@ -209,10 +209,10 @@ public function getProjectId(callable $httpHandler = null) * * In this case, it returns the keyfile's client_email key. * - * @param callable $httpHandler Not used by this credentials type. + * @param callable|null $httpHandler Not used by this credentials type. * @return string */ - public function getClientName(callable $httpHandler = null) + public function getClientName(?callable $httpHandler = null) { return $this->auth->getIssuer(); } diff --git a/src/Credentials/UserRefreshCredentials.php b/src/Credentials/UserRefreshCredentials.php index d40055562..051634f79 100644 --- a/src/Credentials/UserRefreshCredentials.php +++ b/src/Credentials/UserRefreshCredentials.php @@ -20,6 +20,8 @@ use Google\Auth\CredentialsLoader; use Google\Auth\GetQuotaProjectInterface; use Google\Auth\OAuth2; +use InvalidArgumentException; +use LogicException; /** * Authenticates requests using User Refresh credentials. @@ -55,48 +57,67 @@ class UserRefreshCredentials extends CredentialsLoader implements GetQuotaProjec */ protected $quotaProject; + /** + * Whether this is an ID token request or an access token request. Used when + * building the metric header. + */ + private bool $isIdTokenRequest = false; + /** * Create a new UserRefreshCredentials. * - * @param string|string[] $scope the scope of the access request, expressed + * @param string|string[]|null $scope the scope of the access request, expressed * either as an Array or as a space-delimited String. * @param string|array $jsonKey JSON credential file path or JSON credentials * as an associative array + * @param string|null $targetAudience The audience for the ID token. */ public function __construct( $scope, - $jsonKey + $jsonKey, + string $targetAudience = null ) { if (is_string($jsonKey)) { if (!file_exists($jsonKey)) { - throw new \InvalidArgumentException('file does not exist'); + throw new InvalidArgumentException('file does not exist or is unreadable'); } $json = file_get_contents($jsonKey); if (!$jsonKey = json_decode((string) $json, true)) { - throw new \LogicException('invalid json for auth config'); + throw new LogicException('invalid json for auth config'); } } if (!array_key_exists('client_id', $jsonKey)) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'json key is missing the client_id field' ); } if (!array_key_exists('client_secret', $jsonKey)) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'json key is missing the client_secret field' ); } if (!array_key_exists('refresh_token', $jsonKey)) { - throw new \InvalidArgumentException( + throw new InvalidArgumentException( 'json key is missing the refresh_token field' ); } + if ($scope && $targetAudience) { + throw new InvalidArgumentException( + 'Scope and targetAudience cannot both be supplied' + ); + } + $additionalClaims = []; + if ($targetAudience) { + $additionalClaims = ['target_audience' => $targetAudience]; + $this->isIdTokenRequest = true; + } $this->auth = new OAuth2([ 'clientId' => $jsonKey['client_id'], 'clientSecret' => $jsonKey['client_secret'], 'refresh_token' => $jsonKey['refresh_token'], 'scope' => $scope, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI, + 'additionalClaims' => $additionalClaims, ]); if (array_key_exists('quota_project_id', $jsonKey)) { $this->quotaProject = (string) $jsonKey['quota_project_id']; @@ -104,7 +125,7 @@ public function __construct( } /** - * @param callable $httpHandler + * @param callable|null $httpHandler * @param array $metricsHeader [optional] Metrics headers to be inserted * into the token endpoint request present. * This could be passed from ImersonatedServiceAccountCredentials as it uses @@ -120,12 +141,11 @@ public function __construct( * @type string $id_token * } */ - public function fetchAuthToken(callable $httpHandler = null, array $metricsHeader = []) + public function fetchAuthToken(?callable $httpHandler = null, array $metricsHeader = []) { - // We don't support id token endpoint requests as of now for User Cred return $this->auth->fetchAuthToken( $httpHandler, - $this->applyTokenEndpointMetrics($metricsHeader, 'at') + $this->applyTokenEndpointMetrics($metricsHeader, $this->isIdTokenRequest ? 'it' : 'at') ); } diff --git a/src/CredentialsLoader.php b/src/CredentialsLoader.php index 746b957a9..9e612caca 100644 --- a/src/CredentialsLoader.php +++ b/src/CredentialsLoader.php @@ -165,15 +165,15 @@ public static function makeCredentials( * * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token * @param array $httpClientOptions (optional) Array of request options to apply. - * @param callable $httpHandler (optional) http client to fetch the token. - * @param callable $tokenCallback (optional) function to be called when a new token is fetched. + * @param callable|null $httpHandler (optional) http client to fetch the token. + * @param callable|null $tokenCallback (optional) function to be called when a new token is fetched. * @return \GuzzleHttp\Client */ public static function makeHttpClient( FetchAuthTokenInterface $fetcher, array $httpClientOptions = [], - callable $httpHandler = null, - callable $tokenCallback = null + ?callable $httpHandler = null, + ?callable $tokenCallback = null ) { $middleware = new Middleware\AuthTokenMiddleware( $fetcher, diff --git a/src/ExternalAccountCredentialSourceInterface.php b/src/ExternalAccountCredentialSourceInterface.php index 041b18d51..1492c6991 100644 --- a/src/ExternalAccountCredentialSourceInterface.php +++ b/src/ExternalAccountCredentialSourceInterface.php @@ -1,5 +1,5 @@ $cacheConfig Configuration for the cache + * @param array|null $cacheConfig Configuration for the cache * @param CacheItemPoolInterface $cache */ public function __construct( FetchAuthTokenInterface $fetcher, - array $cacheConfig = null, - CacheItemPoolInterface $cache + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $this->fetcher = $fetcher; $this->cache = $cache; @@ -76,11 +76,11 @@ public function getFetcher() * Checks the cache for a valid auth token and fetches the auth tokens * from the supplied fetcher. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array the response * @throws \Exception */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { if ($cached = $this->fetchAuthTokenFromCache()) { return $cached; @@ -112,10 +112,10 @@ public function getLastReceivedToken() /** * Get the client name from the fetcher. * - * @param callable $httpHandler An HTTP handler to deliver PSR7 requests. + * @param callable|null $httpHandler An HTTP handler to deliver PSR7 requests. * @return string */ - public function getClientName(callable $httpHandler = null) + public function getClientName(?callable $httpHandler = null) { if (!$this->fetcher instanceof SignBlobInterface) { throw new \RuntimeException( @@ -176,15 +176,15 @@ public function getQuotaProject() return null; } - /* + /** * Get the Project ID from the fetcher. * - * @param callable $httpHandler Callback which delivers psr7 request + * @param callable|null $httpHandler Callback which delivers psr7 request * @return string|null * @throws \RuntimeException If the fetcher does not implement * `Google\Auth\ProvidesProjectIdInterface`. */ - public function getProjectId(callable $httpHandler = null) + public function getProjectId(?callable $httpHandler = null) { if (!$this->fetcher instanceof ProjectIdProviderInterface) { throw new \RuntimeException( @@ -227,7 +227,7 @@ public function getUniverseDomain(): string * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap * @throws \RuntimeException If the fetcher does not implement * `Google\Auth\UpdateMetadataInterface`. @@ -235,7 +235,7 @@ public function getUniverseDomain(): string public function updateMetadata( $metadata, $authUri = null, - callable $httpHandler = null + ?callable $httpHandler = null ) { if (!$this->fetcher instanceof UpdateMetadataInterface) { throw new \RuntimeException( diff --git a/src/FetchAuthTokenInterface.php b/src/FetchAuthTokenInterface.php index 64659550b..fbbd8b0c9 100644 --- a/src/FetchAuthTokenInterface.php +++ b/src/FetchAuthTokenInterface.php @@ -25,10 +25,10 @@ interface FetchAuthTokenInterface /** * Fetches the auth tokens based on the current state. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array a hash of auth tokens */ - public function fetchAuthToken(callable $httpHandler = null); + public function fetchAuthToken(?callable $httpHandler = null); /** * Obtains a key that can used to cache the results of #fetchAuthToken. diff --git a/src/GCECache.php b/src/GCECache.php index 804abdbe2..d3dcd8c6c 100644 --- a/src/GCECache.php +++ b/src/GCECache.php @@ -46,8 +46,8 @@ class GCECache * @param CacheItemPoolInterface $cache */ public function __construct( - array $cacheConfig = null, - CacheItemPoolInterface $cache = null + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $this->cache = $cache; $this->cacheConfig = array_merge([ @@ -60,10 +60,10 @@ public function __construct( * Caches the result of onGce so the metadata server is not called multiple * times. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return bool True if this a GCEInstance, false otherwise */ - public function onGce(callable $httpHandler = null) + public function onGce(?callable $httpHandler = null) { if (is_null($this->cache)) { return GCECredentials::onGce($httpHandler); diff --git a/src/HttpHandler/HttpClientCache.php b/src/HttpHandler/HttpClientCache.php index f4a62b967..0159c8d09 100644 --- a/src/HttpHandler/HttpClientCache.php +++ b/src/HttpHandler/HttpClientCache.php @@ -37,7 +37,7 @@ class HttpClientCache * @param ClientInterface|null $client * @return void */ - public static function setHttpClient(ClientInterface $client = null) + public static function setHttpClient(?ClientInterface $client = null) { self::$httpClient = $client; } diff --git a/src/HttpHandler/HttpHandlerFactory.php b/src/HttpHandler/HttpHandlerFactory.php index f19f87443..3856022a2 100644 --- a/src/HttpHandler/HttpHandlerFactory.php +++ b/src/HttpHandler/HttpHandlerFactory.php @@ -27,11 +27,11 @@ class HttpHandlerFactory /** * Builds out a default http handler for the installed version of guzzle. * - * @param ClientInterface $client + * @param ClientInterface|null $client * @return Guzzle6HttpHandler|Guzzle7HttpHandler * @throws \Exception */ - public static function build(ClientInterface $client = null) + public static function build(?ClientInterface $client = null) { if (is_null($client)) { $stack = null; diff --git a/src/Iam.php b/src/Iam.php index 46bee30d2..b32ac6065 100644 --- a/src/Iam.php +++ b/src/Iam.php @@ -46,10 +46,10 @@ class Iam private string $universeDomain; /** - * @param callable $httpHandler [optional] The HTTP Handler to send requests. + * @param callable|null $httpHandler [optional] The HTTP Handler to send requests. */ public function __construct( - callable $httpHandler = null, + ?callable $httpHandler = null, string $universeDomain = GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN ) { $this->httpHandler = $httpHandler diff --git a/src/Middleware/AuthTokenMiddleware.php b/src/Middleware/AuthTokenMiddleware.php index 3bbda7a23..b8f2c514c 100644 --- a/src/Middleware/AuthTokenMiddleware.php +++ b/src/Middleware/AuthTokenMiddleware.php @@ -59,13 +59,13 @@ class AuthTokenMiddleware * Creates a new AuthTokenMiddleware. * * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token - * @param callable $httpHandler (optional) callback which delivers psr7 request - * @param callable $tokenCallback (optional) function to be called when a new token is fetched. + * @param callable|null $httpHandler (optional) callback which delivers psr7 request + * @param callable|null $tokenCallback (optional) function to be called when a new token is fetched. */ public function __construct( FetchAuthTokenInterface $fetcher, - callable $httpHandler = null, - callable $tokenCallback = null + ?callable $httpHandler = null, + ?callable $tokenCallback = null ) { $this->fetcher = $fetcher; $this->httpHandler = $httpHandler; diff --git a/src/Middleware/ProxyAuthTokenMiddleware.php b/src/Middleware/ProxyAuthTokenMiddleware.php index 0f9ee429f..2c44871f9 100644 --- a/src/Middleware/ProxyAuthTokenMiddleware.php +++ b/src/Middleware/ProxyAuthTokenMiddleware.php @@ -53,13 +53,13 @@ class ProxyAuthTokenMiddleware * Creates a new ProxyAuthTokenMiddleware. * * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token - * @param callable $httpHandler (optional) callback which delivers psr7 request - * @param callable $tokenCallback (optional) function to be called when a new token is fetched. + * @param callable|null $httpHandler (optional) callback which delivers psr7 request + * @param callable|null $tokenCallback (optional) function to be called when a new token is fetched. */ public function __construct( FetchAuthTokenInterface $fetcher, - callable $httpHandler = null, - callable $tokenCallback = null + ?callable $httpHandler = null, + ?callable $tokenCallback = null ) { $this->fetcher = $fetcher; $this->httpHandler = $httpHandler; diff --git a/src/Middleware/ScopedAccessTokenMiddleware.php b/src/Middleware/ScopedAccessTokenMiddleware.php index 8bb1d7a0b..f2f85cc16 100644 --- a/src/Middleware/ScopedAccessTokenMiddleware.php +++ b/src/Middleware/ScopedAccessTokenMiddleware.php @@ -54,14 +54,14 @@ class ScopedAccessTokenMiddleware * * @param callable $tokenFunc a token generator function * @param array|string $scopes the token authentication scopes - * @param array $cacheConfig configuration for the cache when it's present - * @param CacheItemPoolInterface $cache an implementation of CacheItemPoolInterface + * @param array|null $cacheConfig configuration for the cache when it's present + * @param CacheItemPoolInterface|null $cache an implementation of CacheItemPoolInterface */ public function __construct( callable $tokenFunc, $scopes, - array $cacheConfig = null, - CacheItemPoolInterface $cache = null + ?array $cacheConfig = null, + ?CacheItemPoolInterface $cache = null ) { $this->tokenFunc = $tokenFunc; if (!(is_string($scopes) || is_array($scopes))) { diff --git a/src/OAuth2.php b/src/OAuth2.php index 2463854e0..42b847e3d 100644 --- a/src/OAuth2.php +++ b/src/OAuth2.php @@ -581,12 +581,12 @@ public function toJwt(array $config = []) /** * Generates a request for token credentials. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @param array $headers [optional] Additional headers to pass to * the token endpoint request. * @return RequestInterface the authorization Url. */ - public function generateCredentialsRequest(callable $httpHandler = null, $headers = []) + public function generateCredentialsRequest(?callable $httpHandler = null, $headers = []) { $uri = $this->getTokenCredentialUri(); if (is_null($uri)) { @@ -611,6 +611,9 @@ public function generateCredentialsRequest(callable $httpHandler = null, $header break; case 'refresh_token': $params['refresh_token'] = $this->getRefreshToken(); + if (isset($this->getAdditionalClaims()['target_audience'])) { + $params['target_audience'] = $this->getAdditionalClaims()['target_audience']; + } $this->addClientCredentials($params); break; case self::JWT_URN: @@ -661,12 +664,12 @@ public function generateCredentialsRequest(callable $httpHandler = null, $header /** * Fetches the auth tokens based on the current state. * - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @param array $headers [optional] If present, add these headers to the token * endpoint request. * @return array the response */ - public function fetchAuthToken(callable $httpHandler = null, $headers = []) + public function fetchAuthToken(?callable $httpHandler = null, $headers = []) { if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); @@ -1683,11 +1686,11 @@ public function getLastReceivedToken() * * Alias of {@see Google\Auth\OAuth2::getClientId()}. * - * @param callable $httpHandler + * @param callable|null $httpHandler * @return string * @access private */ - public function getClientName(callable $httpHandler = null) + public function getClientName(?callable $httpHandler = null) { return $this->getClientId(); } diff --git a/src/ProjectIdProviderInterface.php b/src/ProjectIdProviderInterface.php index 0a41f7832..8d10c293a 100644 --- a/src/ProjectIdProviderInterface.php +++ b/src/ProjectIdProviderInterface.php @@ -25,8 +25,8 @@ interface ProjectIdProviderInterface /** * Get the project ID. * - * @param callable $httpHandler Callback which delivers psr7 request + * @param callable|null $httpHandler Callback which delivers psr7 request * @return string|null */ - public function getProjectId(callable $httpHandler = null); + public function getProjectId(?callable $httpHandler = null); } diff --git a/src/SignBlobInterface.php b/src/SignBlobInterface.php index 5f2c94414..b3c2b0505 100644 --- a/src/SignBlobInterface.php +++ b/src/SignBlobInterface.php @@ -36,9 +36,9 @@ public function signBlob($stringToSign, $forceOpenssl = false); /** * Returns the current Client Name. * - * @param callable $httpHandler callback which delivers psr7 request, if + * @param callable|null $httpHandler callback which delivers psr7 request, if * one is required to obtain a client name. * @return string */ - public function getClientName(callable $httpHandler = null); + public function getClientName(?callable $httpHandler = null); } diff --git a/src/UpdateMetadataInterface.php b/src/UpdateMetadataInterface.php index 6d2e7d5d5..5cf5b42cc 100644 --- a/src/UpdateMetadataInterface.php +++ b/src/UpdateMetadataInterface.php @@ -30,12 +30,12 @@ interface UpdateMetadataInterface * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, - callable $httpHandler = null + ?callable $httpHandler = null ); } diff --git a/src/UpdateMetadataTrait.php b/src/UpdateMetadataTrait.php index 30d4060cf..486ec72a5 100644 --- a/src/UpdateMetadataTrait.php +++ b/src/UpdateMetadataTrait.php @@ -44,13 +44,13 @@ public function getUpdateMetadataFunc() * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri - * @param callable $httpHandler callback which delivers psr7 request + * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, - callable $httpHandler = null + ?callable $httpHandler = null ) { $metadata_copy = $metadata; diff --git a/tests/ApplicationDefaultCredentialsTest.php b/tests/ApplicationDefaultCredentialsTest.php index c1583ed06..1e8a378ef 100644 --- a/tests/ApplicationDefaultCredentialsTest.php +++ b/tests/ApplicationDefaultCredentialsTest.php @@ -21,15 +21,19 @@ use Google\Auth\ApplicationDefaultCredentials; use Google\Auth\Credentials\ExternalAccountCredentials; use Google\Auth\Credentials\GCECredentials; +use Google\Auth\Credentials\ImpersonatedServiceAccountCredentials; use Google\Auth\Credentials\ServiceAccountCredentials; +use Google\Auth\Credentials\UserRefreshCredentials; use Google\Auth\CredentialsLoader; use Google\Auth\CredentialSource; +use Google\Auth\FetchAuthTokenCache; use Google\Auth\GCECache; use GuzzleHttp\Psr7; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Utils; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; +use Psr\Cache\CacheItemPoolInterface; use ReflectionClass; /** @@ -103,7 +107,7 @@ public function testSuccedsIfNoDefaultFilesButIsOnGCE() ]); $this->assertInstanceOf( - 'Google\Auth\Credentials\GCECredentials', + GCECredentials::class, ApplicationDefaultCredentials::getCredentials('a scope', $httpHandler) ); } @@ -126,10 +130,7 @@ public function testGceCredentials() 'a+default+scope' // $defaultScope ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\GCECredentials', - $creds - ); + $this->assertInstanceOf(GCECredentials::class, $creds); $uriProperty = (new ReflectionClass($creds))->getProperty('tokenUri'); $uriProperty->setAccessible(true); @@ -166,11 +167,8 @@ public function testImpersonatedServiceAccountCredentials() null, 'a default scope' ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\ImpersonatedServiceAccountCredentials', - $creds - ); + $this->assertInstanceOf(ImpersonatedServiceAccountCredentials::class, $creds); $this->assertEquals('service_account_name@namespace.iam.gserviceaccount.com', $creds->getClientName()); $sourceCredentialsProperty = (new ReflectionClass($creds))->getProperty('sourceCredentials'); @@ -178,10 +176,7 @@ public function testImpersonatedServiceAccountCredentials() // used default scope $sourceCredentials = $sourceCredentialsProperty->getValue($creds); - $this->assertInstanceOf( - 'Google\Auth\Credentials\UserRefreshCredentials', - $sourceCredentials - ); + $this->assertInstanceOf(UserRefreshCredentials::class, $sourceCredentials); } public function testUserRefreshCredentials() @@ -197,10 +192,7 @@ public function testUserRefreshCredentials() 'a default scope' // $defaultScope ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\UserRefreshCredentials', - $creds - ); + $this->assertInstanceOf(UserRefreshCredentials::class, $creds); $authProperty = (new ReflectionClass($creds))->getProperty('auth'); $authProperty->setAccessible(true); @@ -236,10 +228,7 @@ public function testServiceAccountCredentials() 'a default scope' // $defaultScope ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\ServiceAccountCredentials', - $creds - ); + $this->assertInstanceOf(ServiceAccountCredentials::class, $creds); $authProperty = (new ReflectionClass($creds))->getProperty('auth'); $authProperty->setAccessible(true); @@ -331,7 +320,7 @@ public function testGetMiddlewareWithCacheOptions() ]); $cacheOptions = []; - $cachePool = $this->prophesize('Psr\Cache\CacheItemPoolInterface'); + $cachePool = $this->prophesize(CacheItemPoolInterface::class); $middleware = ApplicationDefaultCredentials::getMiddleware( 'a scope', @@ -374,7 +363,7 @@ public function testOnGceCacheWithHit() ->shouldBeCalledTimes(1) ->willReturn(false); - $mockCache = $this->prophesize('Psr\Cache\CacheItemPoolInterface'); + $mockCache = $this->prophesize(CacheItemPoolInterface::class); $mockCache->getItem(GCECache::GCE_CACHE_KEY) ->shouldBeCalledTimes(1) ->willReturn($mockCacheItem->reveal()); @@ -406,7 +395,7 @@ public function testOnGceCacheWithoutHit() ->shouldBeCalledTimes(1) ->willReturn($mockCacheItem->reveal()); - $mockCache = $this->prophesize('Psr\Cache\CacheItemPoolInterface'); + $mockCache = $this->prophesize(CacheItemPoolInterface::class); $mockCache->getItem(GCECache::GCE_CACHE_KEY) ->shouldBeCalledTimes(2) ->willReturn($mockCacheItem->reveal()); @@ -445,7 +434,7 @@ public function testOnGceCacheWithOptions() ->shouldBeCalledTimes(1) ->willReturn($mockCacheItem->reveal()); - $mockCache = $this->prophesize('Psr\Cache\CacheItemPoolInterface'); + $mockCache = $this->prophesize(CacheItemPoolInterface::class); $mockCache->getItem($prefix . GCECache::GCE_CACHE_KEY) ->shouldBeCalledTimes(2) ->willReturn($mockCacheItem->reveal()); @@ -477,20 +466,20 @@ public function testGetIdTokenCredentialsLoadsOKIfEnvSpecifiedIsValid() putenv(ServiceAccountCredentials::ENV_VAR . '=' . $keyFile); $creds = ApplicationDefaultCredentials::getIdTokenCredentials($this->targetAudience); - - $this->assertNotNull($creds); + $this->assertInstanceOf(ServiceAccountCredentials::class, $creds); } public function testGetIdTokenCredentialsLoadsDefaultFileIfPresentAndEnvVarIsNotSet() { putenv('HOME=' . __DIR__ . '/fixtures'); $creds = ApplicationDefaultCredentials::getIdTokenCredentials($this->targetAudience); - $this->assertNotNull($creds); + $this->assertInstanceOf(ServiceAccountCredentials::class, $creds); } public function testGetIdTokenCredentialsFailsIfNotOnGceAndNoDefaultFileFound() { $this->expectException(DomainException::class); + $this->expectExceptionMessage('Your default credentials were not found'); putenv('HOME=' . __DIR__ . '/not_exist_fixtures'); @@ -501,12 +490,10 @@ public function testGetIdTokenCredentialsFailsIfNotOnGceAndNoDefaultFileFound() new Response(500) ]); - $creds = ApplicationDefaultCredentials::getIdTokenCredentials( + ApplicationDefaultCredentials::getIdTokenCredentials( $this->targetAudience, $httpHandler ); - - $this->assertNotNull($creds); } public function testGetIdTokenCredentialsWithCacheOptions() @@ -519,7 +506,7 @@ public function testGetIdTokenCredentialsWithCacheOptions() ]); $cacheOptions = []; - $cachePool = $this->prophesize('Psr\Cache\CacheItemPoolInterface'); + $cachePool = $this->prophesize(CacheItemPoolInterface::class); $credentials = ApplicationDefaultCredentials::getIdTokenCredentials( $this->targetAudience, @@ -528,7 +515,7 @@ public function testGetIdTokenCredentialsWithCacheOptions() $cachePool->reveal() ); - $this->assertInstanceOf('Google\Auth\FetchAuthTokenCache', $credentials); + $this->assertInstanceOf(FetchAuthTokenCache::class, $credentials); } public function testGetIdTokenCredentialsSuccedsIfNoDefaultFilesButIsOnGCE() @@ -552,10 +539,27 @@ public function testGetIdTokenCredentialsSuccedsIfNoDefaultFilesButIsOnGCE() $httpHandler ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\GCECredentials', - $credentials + $this->assertInstanceOf(GCECredentials::class, $credentials); + } + + public function testGetIdTokenCredentialsWithUserRefreshCredentials() + { + putenv('HOME=' . __DIR__ . '/fixtures2'); + + $creds = ApplicationDefaultCredentials::getIdTokenCredentials( + $this->targetAudience, ); + + $this->assertInstanceOf(UserRefreshCredentials::class, $creds); + + $authProperty = (new ReflectionClass($creds))->getProperty('auth'); + $authProperty->setAccessible(true); + + // used default scope + $auth = $authProperty->getValue($creds); + $additionalClaims = $auth->getAdditionalClaims(); + $this->assertArrayHasKey('target_audience', $additionalClaims); + $this->assertEquals($this->targetAudience, $additionalClaims['target_audience']); } public function testWithServiceAccountCredentialsAndExplicitQuotaProject() @@ -571,10 +575,7 @@ public function testWithServiceAccountCredentialsAndExplicitQuotaProject() $this->quotaProject ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\ServiceAccountCredentials', - $credentials - ); + $this->assertInstanceOf(ServiceAccountCredentials::class, $credentials); $this->assertEquals( $this->quotaProject, @@ -658,7 +659,7 @@ public function testWithFetchAuthTokenCacheAndExplicitQuotaProject() ]); $cacheOptions = []; - $cachePool = $this->prophesize('Psr\Cache\CacheItemPoolInterface'); + $cachePool = $this->prophesize(CacheItemPoolInterface::class); $credentials = ApplicationDefaultCredentials::getCredentials( null, @@ -668,7 +669,7 @@ public function testWithFetchAuthTokenCacheAndExplicitQuotaProject() $this->quotaProject ); - $this->assertInstanceOf('Google\Auth\FetchAuthTokenCache', $credentials); + $this->assertInstanceOf(FetchAuthTokenCache::class, $credentials); $this->assertEquals( $this->quotaProject, @@ -700,10 +701,7 @@ public function testWithGCECredentials() $this->quotaProject ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\GCECredentials', - $credentials - ); + $this->assertInstanceOf(GCECredentials::class, $credentials); $this->assertEquals( $this->quotaProject, @@ -730,7 +728,7 @@ public function testAppEngineFlexible() new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), ]); $this->assertInstanceOf( - 'Google\Auth\Credentials\GCECredentials', + GCECredentials::class, ApplicationDefaultCredentials::getCredentials(null, $httpHandler) ); } @@ -747,10 +745,7 @@ public function testAppEngineFlexibleIdToken() $this->targetAudience, $httpHandler ); - $this->assertInstanceOf( - 'Google\Auth\Credentials\GCECredentials', - $creds - ); + $this->assertInstanceOf(GCECredentials::class, $creds); } /** diff --git a/tests/CredentialSource/ExecutableSourceTest.php b/tests/CredentialSource/ExecutableSourceTest.php index 84c453a6a..533b96072 100644 --- a/tests/CredentialSource/ExecutableSourceTest.php +++ b/tests/CredentialSource/ExecutableSourceTest.php @@ -89,7 +89,7 @@ public function testFetchSubjectTokenWithError( int $returnCode, string $output, string $expectedExceptionMessage, - string $outputFile = null + ?string $outputFile = null ) { $this->expectException(ExecutableResponseError::class); $this->expectExceptionMessage($expectedExceptionMessage); diff --git a/tests/CredentialSource/FileSourceTest.php b/tests/CredentialSource/FileSourceTest.php index 9cdcbb9cc..919efa739 100644 --- a/tests/CredentialSource/FileSourceTest.php +++ b/tests/CredentialSource/FileSourceTest.php @@ -32,8 +32,8 @@ class FileSourceTest extends TestCase public function testFetchSubjectToken( string $filename, string $expectedToken, - string $format = null, - string $subjectTokenFieldName = null + ?string $format = null, + ?string $subjectTokenFieldName = null ) { $source = new FileSource($filename, $format, $subjectTokenFieldName); $subjectToken = $source->fetchSubjectToken(); diff --git a/tests/CredentialSource/UrlSourceTest.php b/tests/CredentialSource/UrlSourceTest.php index 5a07cc5e1..84c04f3f6 100644 --- a/tests/CredentialSource/UrlSourceTest.php +++ b/tests/CredentialSource/UrlSourceTest.php @@ -38,8 +38,8 @@ class UrlSourceTest extends TestCase public function testFetchSubjectToken( string $responseBody, string $expectedToken, - string $format = null, - string $subjectTokenFieldName = null + ?string $format = null, + ?string $subjectTokenFieldName = null ) { $handler = function (RequestInterface $request) use ($responseBody): ResponseInterface { $this->assertEquals('GET', $request->getMethod()); diff --git a/tests/Credentials/UserRefreshCredentialsTest.php b/tests/Credentials/UserRefreshCredentialsTest.php index b944dd40e..7a8f393b9 100644 --- a/tests/Credentials/UserRefreshCredentialsTest.php +++ b/tests/Credentials/UserRefreshCredentialsTest.php @@ -27,22 +27,37 @@ use LogicException; use PHPUnit\Framework\TestCase; -// Creates a standard JSON auth object for testing. -function createURCTestJson() +class UserRefreshCredentialsTest extends TestCase { - return [ - 'client_id' => 'client123', - 'client_secret' => 'clientSecret123', - 'refresh_token' => 'refreshToken123', - 'type' => 'authorized_user', - ]; -} + private $originalHome; + + protected function setUp(): void + { + $this->originalHome = getenv('HOME'); + } + + protected function tearDown(): void + { + putenv(UserRefreshCredentials::ENV_VAR); // removes it from + if ($this->originalHome != getenv('HOME')) { + putenv('HOME=' . $this->originalHome); + } + } + + // Creates a standard JSON auth object for testing. + private function createTestJson() + { + return [ + 'client_id' => 'client123', + 'client_secret' => 'clientSecret123', + 'refresh_token' => 'refreshToken123', + 'type' => 'authorized_user', + ]; + } -class URCGetCacheKeyTest extends TestCase -{ public function testShouldBeTheSameAsOAuth2WithTheSameScope() { - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; $sa = new UserRefreshCredentials( $scope, @@ -54,14 +69,11 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() $sa->getCacheKey() ); } -} -class URCConstructorTest extends TestCase -{ public function testShouldFailIfScopeIsNotAValidType() { $this->expectException(InvalidArgumentException::class); - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); $notAnArrayOrString = new \stdClass(); $sa = new UserRefreshCredentials( $notAnArrayOrString, @@ -72,7 +84,7 @@ public function testShouldFailIfScopeIsNotAValidType() public function testShouldFailIfJsonDoesNotHaveClientSecret() { $this->expectException(InvalidArgumentException::class); - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); unset($testJson['client_secret']); $scope = ['scope/1', 'scope/2']; $sa = new UserRefreshCredentials( @@ -84,7 +96,7 @@ public function testShouldFailIfJsonDoesNotHaveClientSecret() public function testShouldFailIfJsonDoesNotHaveRefreshToken() { $this->expectException(InvalidArgumentException::class); - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); unset($testJson['refresh_token']); $scope = ['scope/1', 'scope/2']; $sa = new UserRefreshCredentials( @@ -96,7 +108,7 @@ public function testShouldFailIfJsonDoesNotHaveRefreshToken() public function testShouldFailIfJsonDoesNotHaveClientId() { $this->expectException(InvalidArgumentException::class); - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); unset($testJson['client_id']); $scope = ['scope/1', 'scope/2']; $sa = new UserRefreshCredentials( @@ -144,14 +156,6 @@ public function testValid3LOauthCreds() new UserRefreshCredentials('scope/1', $keyFile) ); } -} - -class URCFromEnvTest extends TestCase -{ - protected function tearDown(): void - { - putenv(UserRefreshCredentials::ENV_VAR); // removes it from - } public function testIsNullIfEnvVarIsNotSet() { @@ -172,23 +176,6 @@ public function testSucceedIfFileExists() putenv(UserRefreshCredentials::ENV_VAR . '=' . $keyFile); $this->assertNotNull(ApplicationDefaultCredentials::getCredentials('a scope')); } -} - -class URCFromWellKnownFileTest extends TestCase -{ - private $originalHome; - - protected function setUp(): void - { - $this->originalHome = getenv('HOME'); - } - - protected function tearDown(): void - { - if ($this->originalHome != getenv('HOME')) { - putenv('HOME=' . $this->originalHome); - } - } public function testIsNullIfFileDoesNotExist() { @@ -205,14 +192,11 @@ public function testSucceedIfFileIsPresent() ApplicationDefaultCredentials::getCredentials('a scope') ); } -} -class URCFetchAuthTokenTest extends TestCase -{ public function testFailsOnClientErrors() { $this->expectException(\GuzzleHttp\Exception\ClientException::class); - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; $httpHandler = getHandler([ new Response(400), @@ -227,7 +211,7 @@ public function testFailsOnClientErrors() public function testFailsOnServerErrors() { $this->expectException(\GuzzleHttp\Exception\ServerException::class); - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; $httpHandler = getHandler([ new Response(500), @@ -241,7 +225,7 @@ public function testFailsOnServerErrors() public function testCanFetchCredsOK() { - $testJson = createURCTestJson(); + $testJson = $this->createTestJson(); $testJsonText = json_encode($testJson); $scope = ['scope/1', 'scope/2']; $httpHandler = getHandler([ @@ -263,15 +247,39 @@ public function testGetGrantedScope() ]); $sa = new UserRefreshCredentials( '', - createURCTestJson() + $this->createTestJson() ); $sa->fetchAuthToken($httpHandler); $this->assertEquals('scope/1 scope/2', $sa->getGrantedScope()); } -} -class URCGetQuotaProjectTest extends TestCase -{ + public function testShouldBeIdTokenWhenTargetAudienceIsSet() + { + $testJson = $this->createTestJson(); + $expectedToken = ['id_token' => 'idtoken12345']; + $timesCalled = 0; + $httpHandler = function ($request) use (&$timesCalled, $expectedToken) { + $timesCalled++; + parse_str($request->getBody(), $post); + + $this->assertArrayHasKey('target_audience', $post); + $this->assertEquals('a target audience', $post['target_audience']); + return new Response(200, [], Utils::streamFor(json_encode($expectedToken))); + }; + $sa = new UserRefreshCredentials(null, $testJson, 'a target audience'); + $this->assertEquals($expectedToken, $sa->fetchAuthToken($httpHandler)); + $this->assertEquals(1, $timesCalled); + } + + public function testSettingBothScopeAndTargetAudienceThrowsException() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Scope and targetAudience cannot both be supplied'); + + $testJson = $this->createTestJson(); + $sa = new UserRefreshCredentials('a-scope', $testJson, 'a-target-audience'); + } + public function testGetQuotaProject() { $keyFile = __DIR__ . '/../fixtures2' . '/private.json'; diff --git a/tests/CredentialsLoaderTest.php b/tests/CredentialsLoaderTest.php index 770d9195a..a0cf44584 100644 --- a/tests/CredentialsLoaderTest.php +++ b/tests/CredentialsLoaderTest.php @@ -163,7 +163,7 @@ public function getCacheKey() return 'test'; } - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(?callable $httpHandler = null) { return 'test'; } diff --git a/tests/ObservabilityMetricsTest.php b/tests/ObservabilityMetricsTest.php index 450bfa125..002abc15e 100644 --- a/tests/ObservabilityMetricsTest.php +++ b/tests/ObservabilityMetricsTest.php @@ -131,10 +131,6 @@ public function testImpersonatedServiceAccountCredentials() $this->assertUpdateMetadata($impersonatedCred, $handler, 'imp', $handlerCalled); } - /** - * UserRefreshCredentials haven't enabled identity token support hence - * they don't have 'auth-request-type/it' observability metric header check. - */ public function testUserRefreshCredentials() { $keyFile = __DIR__ . '/fixtures2/gcloud.json'; @@ -145,6 +141,16 @@ public function testUserRefreshCredentials() $this->assertUpdateMetadata($userRefreshCred, $handler, 'u', $handlerCalled); } + public function testUserRefreshCredentialsWithIdTokens() + { + $keyFile = __DIR__ . '/fixtures2/gcloud.json'; + $handlerCalled = false; + $handler = $this->getCustomHandler('u', 'auth-request-type/it', $handlerCalled); + + $userRefreshCred = new UserRefreshCredentials(null, $keyFile, 'test-target-audience'); + $this->assertUpdateMetadata($userRefreshCred, $handler, 'u', $handlerCalled); + } + /** * Invokes the 'updateMetadata' method of cred fetcher with empty metadata argument * and asserts for proper service api usage observability metrics header.