From ef8ac52f22c7222f3208f6f71c96a0fdf3ccebd0 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Thu, 6 Jun 2024 18:07:49 +0000 Subject: [PATCH 01/16] Change getCacheKey implementation for more unique keys --- .../ExternalAccountCredentials.php | 22 ++++++++++++++++++- src/Credentials/GCECredentials.php | 2 +- src/Credentials/ServiceAccountCredentials.php | 3 ++- .../ServiceAccountJwtAccessCredentials.php | 2 +- src/Credentials/UserRefreshCredentials.php | 2 +- src/OAuth2.php | 20 +++++++++++++++++ .../ExternalAccountCredentialsTest.php | 12 ++++++++++ ...ServiceAccountJwtAccessCredentialsTest.php | 6 +++-- 8 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 98f427a33..ba427af9d 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -53,6 +53,7 @@ class ExternalAccountCredentials implements private ?string $workforcePoolUserProject; private ?string $projectId; private string $universeDomain; + private array $jsonKey; // We will need to take a look into this. PR draft. /** * @param string|string[] $scope The scope of the access request, expressed either as an array @@ -122,6 +123,8 @@ public function __construct( 'workforce_pool_user_project should not be set for non-workforce pool credentials.' ); } + + $this->jsonKey = $jsonKey; } /** @@ -278,7 +281,7 @@ public function fetchAuthToken(callable $httpHandler = null) public function getCacheKey() { - return $this->auth->getCacheKey(); + return implode(":", $this->flattenJsonKey($this->jsonKey)) . ':' . $this->auth->getFormattedScopeOrAudience(); } public function getLastReceivedToken() @@ -359,4 +362,21 @@ private function isWorkforcePool(): bool $regex = '#//iam\.googleapis\.com/locations/[^/]+/workforcePools/#'; return preg_match($regex, $this->auth->getAudience()) === 1; } + + private function flattenJsonKey($arr): array + { + $result = []; + + foreach($arr as $key => $val){ + if (is_array($val)) { + $result = array_merge($result, $this->flattenJsonKey($val)); + } elseif ($val === '') { + continue; + } else { + array_push($result, $val); + } + } + + return $result; + } } diff --git a/src/Credentials/GCECredentials.php b/src/Credentials/GCECredentials.php index 5fed54763..4740663c2 100644 --- a/src/Credentials/GCECredentials.php +++ b/src/Credentials/GCECredentials.php @@ -493,7 +493,7 @@ public function fetchAuthToken(callable $httpHandler = null) */ public function getCacheKey() { - return self::cacheKey; + return $this->tokenUri; } /** diff --git a/src/Credentials/ServiceAccountCredentials.php b/src/Credentials/ServiceAccountCredentials.php index 91238029d..56f05ff85 100644 --- a/src/Credentials/ServiceAccountCredentials.php +++ b/src/Credentials/ServiceAccountCredentials.php @@ -223,7 +223,8 @@ public function fetchAuthToken(callable $httpHandler = null) */ public function getCacheKey() { - $key = $this->auth->getIssuer() . ':' . $this->auth->getCacheKey(); + $key = $this->auth->getIssuer() . ':' . $this->auth->getFormattedScopeOrAudience(); + if ($sub = $this->auth->getSub()) { $key .= ':' . $sub; } diff --git a/src/Credentials/ServiceAccountJwtAccessCredentials.php b/src/Credentials/ServiceAccountJwtAccessCredentials.php index 87baa7500..a261ee52b 100644 --- a/src/Credentials/ServiceAccountJwtAccessCredentials.php +++ b/src/Credentials/ServiceAccountJwtAccessCredentials.php @@ -170,7 +170,7 @@ public function fetchAuthToken(callable $httpHandler = null) */ public function getCacheKey() { - return $this->auth->getCacheKey(); + return $this->auth->getIssuer() . ":" . $this->auth->getFormattedScopeOrAudience(); } /** diff --git a/src/Credentials/UserRefreshCredentials.php b/src/Credentials/UserRefreshCredentials.php index 69778f7c8..ddf3e4c42 100644 --- a/src/Credentials/UserRefreshCredentials.php +++ b/src/Credentials/UserRefreshCredentials.php @@ -134,7 +134,7 @@ public function fetchAuthToken(callable $httpHandler = null, array $metricsHeade */ public function getCacheKey() { - return $this->auth->getClientId() . ':' . $this->auth->getCacheKey(); + return $this->auth->getClientId() . ':' . $this->auth->getFormattedScopeOrAudience(); } /** diff --git a/src/OAuth2.php b/src/OAuth2.php index b1f9ae26d..6ca0f7b69 100644 --- a/src/OAuth2.php +++ b/src/OAuth2.php @@ -703,6 +703,26 @@ public function getCacheKey() return null; } + /** + * Obtains the scope or the Audience and formats it for external classes to use + * in generating a cache key. + * + * @return ?string a key that may be used to cache the auth token. + */ + public function getFormattedScopeOrAudience() + { + if (is_array($this->scope)) { + return implode(':', $this->scope); + } + + if ($this->audience) { + return $this->audience; + } + + // If scope has not set, return null to indicate no caching. + return null; + } + /** * Parses the fetched tokens. * diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index c658054ec..588a35a86 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -521,6 +521,18 @@ public function testFetchAuthTokenWithWorkforcePoolCredentials() $this->assertEquals(strtotime($expiry), $authToken['expires_at']); } + public function testCacheKeyFormat() + { + $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); + $cacheKey = $credentials->getCacheKey(); + + // I decided to hand craft this manually to avoid reusing the flattenJsonKey method + // inside the ExternalAccountCredentials class and make + // sure the flat function works properly + $expectedKey = 'external_account:token-url.com:sts-url.com:scope1'; + $this->assertEquals($expectedKey, $cacheKey); + } + /** * @runInSeparateProcess */ diff --git a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php index 510225dd7..3fb151e5e 100644 --- a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php +++ b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php @@ -480,8 +480,10 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() { $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; - $sa = new ServiceAccountJwtAccessCredentials($testJson); - $this->assertNull($sa->getCacheKey()); + $sa = new ServiceAccountJwtAccessCredentials($testJson, $scope); + + $expectedKey = $testJson['client_email'] . ':' . implode(':', $scope); + $this->assertEquals($expectedKey, $sa->getCacheKey()); } public function testReturnsClientEmail() From 98fce2644cbf675a91cfc7bb5168162d8b5be338 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Thu, 6 Jun 2024 18:17:39 +0000 Subject: [PATCH 02/16] Fix code style --- src/Credentials/ExternalAccountCredentials.php | 4 ++-- src/Credentials/ServiceAccountJwtAccessCredentials.php | 2 +- tests/Credentials/ExternalAccountCredentialsTest.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index ba427af9d..871f33f38 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -281,7 +281,7 @@ public function fetchAuthToken(callable $httpHandler = null) public function getCacheKey() { - return implode(":", $this->flattenJsonKey($this->jsonKey)) . ':' . $this->auth->getFormattedScopeOrAudience(); + return implode(':', $this->flattenJsonKey($this->jsonKey)) . ':' . $this->auth->getFormattedScopeOrAudience(); } public function getLastReceivedToken() @@ -367,7 +367,7 @@ private function flattenJsonKey($arr): array { $result = []; - foreach($arr as $key => $val){ + foreach($arr as $key => $val) { if (is_array($val)) { $result = array_merge($result, $this->flattenJsonKey($val)); } elseif ($val === '') { diff --git a/src/Credentials/ServiceAccountJwtAccessCredentials.php b/src/Credentials/ServiceAccountJwtAccessCredentials.php index a261ee52b..bdcbba61b 100644 --- a/src/Credentials/ServiceAccountJwtAccessCredentials.php +++ b/src/Credentials/ServiceAccountJwtAccessCredentials.php @@ -170,7 +170,7 @@ public function fetchAuthToken(callable $httpHandler = null) */ public function getCacheKey() { - return $this->auth->getIssuer() . ":" . $this->auth->getFormattedScopeOrAudience(); + return $this->auth->getIssuer() . ':' . $this->auth->getFormattedScopeOrAudience(); } /** diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index 588a35a86..d65709888 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -524,12 +524,12 @@ public function testFetchAuthTokenWithWorkforcePoolCredentials() public function testCacheKeyFormat() { $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); - $cacheKey = $credentials->getCacheKey(); + $cacheKey = $credentials->getCacheKey(); // I decided to hand craft this manually to avoid reusing the flattenJsonKey method - // inside the ExternalAccountCredentials class and make + // inside the ExternalAccountCredentials class and make // sure the flat function works properly - $expectedKey = 'external_account:token-url.com:sts-url.com:scope1'; + $expectedKey = 'external_account:token-url.com:sts-url.com:scope1'; $this->assertEquals($expectedKey, $cacheKey); } From 4317d4fcb845470214c4de0f3db238922e2a2f79 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Thu, 6 Jun 2024 18:20:57 +0000 Subject: [PATCH 03/16] Fix PHPstan annotations --- src/Credentials/ExternalAccountCredentials.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 871f33f38..221259455 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -53,7 +53,13 @@ class ExternalAccountCredentials implements private ?string $workforcePoolUserProject; private ?string $projectId; private string $universeDomain; - private array $jsonKey; // We will need to take a look into this. PR draft. + + /** + * Used to calculate the Cache Key for caching + * + * @var array + */ + private array $jsonKey; /** * @param string|string[] $scope The scope of the access request, expressed either as an array @@ -363,7 +369,12 @@ private function isWorkforcePool(): bool return preg_match($regex, $this->auth->getAudience()) === 1; } - private function flattenJsonKey($arr): array + /** + * @param array $arr + * + * @return array + */ + private function flattenJsonKey(array $arr): array { $result = []; From aabfa79534fc1cf8ba359a1b6cad6e1b021a79cb Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Fri, 7 Jun 2024 20:17:53 +0000 Subject: [PATCH 04/16] Change the implementation for the getCacheKey and add them to the source credential files --- src/CredentialSource/AwsNativeSource.php | 16 ++++++ src/CredentialSource/ExecutableSource.php | 11 ++++ src/CredentialSource/FileSource.php | 12 +++++ src/CredentialSource/UrlSource.php | 12 +++++ .../ExternalAccountCredentials.php | 11 +++- src/Credentials/GCECredentials.php | 3 ++ .../ImpersonatedServiceAccountCredentials.php | 3 ++ src/Credentials/ServiceAccountCredentials.php | 12 ++++- .../ServiceAccountJwtAccessCredentials.php | 11 +++- src/Credentials/UserRefreshCredentials.php | 11 +++- ...ternalAccountCredentialSourceInterface.php | 1 + src/OAuth2.php | 22 +++----- .../ExternalAccountCredentialsTest.php | 52 +++++++++++++++++-- .../ServiceAccountCredentialsTest.php | 6 +-- ...ServiceAccountJwtAccessCredentialsTest.php | 2 +- .../UserRefreshCredentialsTest.php | 2 +- 16 files changed, 156 insertions(+), 31 deletions(-) diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index 460d9e5ea..c80be30f5 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -328,6 +328,22 @@ public static function getSigningVarsFromEnv(): ?array return null; } + /** + * Gets the unique key for caching + * For AwsNativeSource the values are: + * imdsv2SessionTokenUrl:securityCredentialsUrl:regionUrl:regionalCredVerificationUrl:audience + * + * @return string + */ + public function getCacheKey(): string + { + return $this->imdsv2SessionTokenUrl . ':' + . $this->securityCredentialsUrl . ':' + . $this->regionUrl . ':' + . $this->regionalCredVerificationUrl . ':' + . $this->audience; + } + /** * Return HMAC hash in binary string */ diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index 7661fc9cc..1dbbb6fd4 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -100,6 +100,17 @@ public function __construct( $this->executableHandler = $executableHandler ?: new ExecutableHandler(); } + /** + * Gets the unique key for caching + * This source is considered non cacheable so returns null. + * + * @return null + */ + public function getCacheKey(): null + { + return null; + } + /** * @param callable $httpHandler unused. * @return string diff --git a/src/CredentialSource/FileSource.php b/src/CredentialSource/FileSource.php index e2afc6c58..5519bf76e 100644 --- a/src/CredentialSource/FileSource.php +++ b/src/CredentialSource/FileSource.php @@ -29,6 +29,7 @@ class FileSource implements ExternalAccountCredentialSourceInterface private string $file; private ?string $format; private ?string $subjectTokenFieldName; + private string $cacheKey; /** * @param string $file The file to read the subject token from. @@ -72,4 +73,15 @@ public function fetchSubjectToken(callable $httpHandler = null): string return $contents; } + + /** + * Gets the unique key for caching. + * The CacheKey is the File name provided on the constructor. + * + * @return string + */ + public function getCacheKey(): string + { + return $this->file; + } } diff --git a/src/CredentialSource/UrlSource.php b/src/CredentialSource/UrlSource.php index 0acb3c6ef..fbc8fc6e1 100644 --- a/src/CredentialSource/UrlSource.php +++ b/src/CredentialSource/UrlSource.php @@ -94,4 +94,16 @@ public function fetchSubjectToken(callable $httpHandler = null): string return $body; } + + /** + * Get the cache key for the credentials. + * The format for the cache key is: + * URL + subjectTokenFieldName + * + * @return string + */ + public function getCacheKey(): string + { + return $this->url . ":" . $this->subjectTokenFieldName; + } } diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 221259455..e99eba7ed 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -285,9 +285,16 @@ public function fetchAuthToken(callable $httpHandler = null) return $stsToken; } - public function getCacheKey() + /** + * Get the cache token key for the credentials. + * The cache token key format depends on the type of source + * was used to configure these credentials. + * + * @return null|string; + */ + public function getCacheKey(): null|string { - return implode(':', $this->flattenJsonKey($this->jsonKey)) . ':' . $this->auth->getFormattedScopeOrAudience(); + return $this->auth->getSubjectTokenFetcher()->getCacheKey(); } public function getLastReceivedToken() diff --git a/src/Credentials/GCECredentials.php b/src/Credentials/GCECredentials.php index 4740663c2..fdcbe84b5 100644 --- a/src/Credentials/GCECredentials.php +++ b/src/Credentials/GCECredentials.php @@ -489,6 +489,9 @@ public function fetchAuthToken(callable $httpHandler = null) } /** + * Returns the Cache Key for the credential token. + * The cache key is the TokenURI given to the constructor. + * * @return string */ public function getCacheKey() diff --git a/src/Credentials/ImpersonatedServiceAccountCredentials.php b/src/Credentials/ImpersonatedServiceAccountCredentials.php index 791fe985a..5d3522827 100644 --- a/src/Credentials/ImpersonatedServiceAccountCredentials.php +++ b/src/Credentials/ImpersonatedServiceAccountCredentials.php @@ -131,6 +131,9 @@ public function fetchAuthToken(callable $httpHandler = null) } /** + * Returns the Cache Key for the credentials + * The cache key is the same as the UserRefreshCredentials class + * * @return string */ public function getCacheKey() diff --git a/src/Credentials/ServiceAccountCredentials.php b/src/Credentials/ServiceAccountCredentials.php index 56f05ff85..ac77720a1 100644 --- a/src/Credentials/ServiceAccountCredentials.php +++ b/src/Credentials/ServiceAccountCredentials.php @@ -219,12 +219,20 @@ public function fetchAuthToken(callable $httpHandler = null) } /** + * Return the Cache Key for the credentials. + * For the cache key format is: + * ClientEmail:Scope | Audience:sub. + * * @return string */ public function getCacheKey() { - $key = $this->auth->getIssuer() . ':' . $this->auth->getFormattedScopeOrAudience(); - + $scopeOrAudience = $this->auth->getScope(); + if (!$scopeOrAudience) { + $scopeOrAudience = $this->auth->getAudience(); + } + + $key = $this->auth->getIssuer() . ':' . $scopeOrAudience; if ($sub = $this->auth->getSub()) { $key .= ':' . $sub; } diff --git a/src/Credentials/ServiceAccountJwtAccessCredentials.php b/src/Credentials/ServiceAccountJwtAccessCredentials.php index bdcbba61b..4f91c2ffd 100644 --- a/src/Credentials/ServiceAccountJwtAccessCredentials.php +++ b/src/Credentials/ServiceAccountJwtAccessCredentials.php @@ -166,11 +166,20 @@ public function fetchAuthToken(callable $httpHandler = null) } /** + * Return the cache key for the credentials. + * The format for the Cache Key is: + * ClientEmail:Scope | Audience + * * @return string */ public function getCacheKey() { - return $this->auth->getIssuer() . ':' . $this->auth->getFormattedScopeOrAudience(); + $scopeOrAudience = $this->auth->getScope(); + if (!$scopeOrAudience) { + $scopeOrAudience = $this->auth->getAudience(); + } + + return $this->auth->getIssuer() . ':' . $scopeOrAudience; } /** diff --git a/src/Credentials/UserRefreshCredentials.php b/src/Credentials/UserRefreshCredentials.php index ddf3e4c42..2ec3337ed 100644 --- a/src/Credentials/UserRefreshCredentials.php +++ b/src/Credentials/UserRefreshCredentials.php @@ -130,11 +130,20 @@ public function fetchAuthToken(callable $httpHandler = null, array $metricsHeade } /** + * Return the Cache Key for the credentials. + * The format for the Cache key is: + * ClientId:Scope | Audience + * * @return string */ public function getCacheKey() { - return $this->auth->getClientId() . ':' . $this->auth->getFormattedScopeOrAudience(); + $scopeOrAudience = $this->auth->getScope(); + if (!$scopeOrAudience) { + $scopeOrAudience = $this->auth->getAudience(); + } + + return $this->auth->getClientId() . ':' . $scopeOrAudience; } /** diff --git a/src/ExternalAccountCredentialSourceInterface.php b/src/ExternalAccountCredentialSourceInterface.php index b4d00f8b4..5d3e913fe 100644 --- a/src/ExternalAccountCredentialSourceInterface.php +++ b/src/ExternalAccountCredentialSourceInterface.php @@ -20,4 +20,5 @@ interface ExternalAccountCredentialSourceInterface { public function fetchSubjectToken(callable $httpHandler = null): string; + public function getCacheKey(): null|string; } diff --git a/src/OAuth2.php b/src/OAuth2.php index 6ca0f7b69..02a2a4f1f 100644 --- a/src/OAuth2.php +++ b/src/OAuth2.php @@ -683,6 +683,8 @@ public function fetchAuthToken(callable $httpHandler = null, $headers = []) } /** + * @deprecated + * * Obtains a key that can used to cache the results of #fetchAuthToken. * * The key is derived from the scopes. @@ -704,23 +706,13 @@ public function getCacheKey() } /** - * Obtains the scope or the Audience and formats it for external classes to use - * in generating a cache key. - * - * @return ?string a key that may be used to cache the auth token. + * Gets this instance's SubjectTokenFetcher + * + * @return null|ExternalAccountCredentialSourceInterface */ - public function getFormattedScopeOrAudience() + public function getSubjectTokenFetcher(): null|ExternalAccountCredentialSourceInterface { - if (is_array($this->scope)) { - return implode(':', $this->scope); - } - - if ($this->audience) { - return $this->audience; - } - - // If scope has not set, return null to indicate no caching. - return null; + return $this->subjectTokenFetcher; } /** diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index d65709888..04c720966 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -521,17 +521,59 @@ public function testFetchAuthTokenWithWorkforcePoolCredentials() $this->assertEquals(strtotime($expiry), $authToken['expires_at']); } - public function testCacheKeyFormat() + public function testFileSourceCacheKey() { + $this->baseCreds['credential_source'] = ['file' => 'fakeFile']; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); + $expectedKey = 'fakeFile'; + $this->assertEquals($expectedKey, $cacheKey); + } + + public function testAWSSourceCacheKey() + { + $this->baseCreds['credential_source'] = [ + 'environment_id' => 'aws1', + 'regional_cred_verification_url' => 'us-east', + 'region_url' => 'aws.us-east.com', + 'url' => 'aws.us-east.token.com', + 'imdsv2_session_token_url' => '12345' + ]; + $this->baseCreds['audience'] = 'audience1'; + $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); + $cacheKey = $credentials->getCacheKey(); + $expectedKey = '12345:aws.us-east.token.com:aws.us-east.com:us-east:audience1'; + $this->assertEquals($expectedKey, $cacheKey); + } + + public function testUrlSourceCacheKey() + { + $this->baseCreds['credential_source'] = [ + 'url' => 'fakeUrl', + 'format' => [ + 'type' => 'json', + 'subject_token_field_name' => 'keyShouldBeHere' + ] + ]; - // I decided to hand craft this manually to avoid reusing the flattenJsonKey method - // inside the ExternalAccountCredentials class and make - // sure the flat function works properly - $expectedKey = 'external_account:token-url.com:sts-url.com:scope1'; + $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); + $cacheKey = $credentials->getCacheKey(); + $expectedKey = 'fakeUrl:keyShouldBeHere'; $this->assertEquals($expectedKey, $cacheKey); } + + public function testExecutableSourceCacheKey() + { + $this->baseCreds['credential_source'] = [ + 'executable' => [ + 'command' => 'ls -al' + ] + ]; + + $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); + $cacheKey = $credentials->getCacheKey(); + $this->assertNull($cacheKey); + } /** * @runInSeparateProcess diff --git a/tests/Credentials/ServiceAccountCredentialsTest.php b/tests/Credentials/ServiceAccountCredentialsTest.php index a53f55158..0a3e57402 100644 --- a/tests/Credentials/ServiceAccountCredentialsTest.php +++ b/tests/Credentials/ServiceAccountCredentialsTest.php @@ -54,7 +54,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . ':' . $o->getCacheKey(), + $testJson['client_email'] . ':' . implode(' ', $scope), $sa->getCacheKey() ); } @@ -71,7 +71,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScopeWithSub() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . ':' . $o->getCacheKey() . ':' . $sub, + $testJson['client_email'] . ':' . implode(' ', $scope) . ':' . $sub, $sa->getCacheKey() ); } @@ -90,7 +90,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScopeWithSubAddedLater() $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . ':' . $o->getCacheKey() . ':' . $sub, + $testJson['client_email'] . ':' . implode(' ', $scope) . ':' . $sub, $sa->getCacheKey() ); } diff --git a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php index 3fb151e5e..73e4db821 100644 --- a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php +++ b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php @@ -482,7 +482,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() $scope = ['scope/1', 'scope/2']; $sa = new ServiceAccountJwtAccessCredentials($testJson, $scope); - $expectedKey = $testJson['client_email'] . ':' . implode(':', $scope); + $expectedKey = $testJson['client_email'] . ':' . implode(' ', $scope); $this->assertEquals($expectedKey, $sa->getCacheKey()); } diff --git a/tests/Credentials/UserRefreshCredentialsTest.php b/tests/Credentials/UserRefreshCredentialsTest.php index 420790a6f..4360354cf 100644 --- a/tests/Credentials/UserRefreshCredentialsTest.php +++ b/tests/Credentials/UserRefreshCredentialsTest.php @@ -50,7 +50,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_id'] . ':' . $o->getCacheKey(), + $testJson['client_id'] . ':' . implode(' ', $scope), $sa->getCacheKey() ); } From cb23ba936182def949ae09e3616fb24160082eb3 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Fri, 7 Jun 2024 20:20:08 +0000 Subject: [PATCH 05/16] Fix return type for getCacheKey --- src/CredentialSource/ExecutableSource.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index 1dbbb6fd4..5611fb26a 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -104,9 +104,9 @@ public function __construct( * Gets the unique key for caching * This source is considered non cacheable so returns null. * - * @return null + * @return null|string */ - public function getCacheKey(): null + public function getCacheKey(): null|string { return null; } From 8415d958d3d67ea9d2a4526087197c1edf568662 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Fri, 7 Jun 2024 20:23:21 +0000 Subject: [PATCH 06/16] Fix style issues --- src/CredentialSource/FileSource.php | 1 - src/CredentialSource/UrlSource.php | 2 +- .../ExternalAccountCredentials.php | 33 +------------------ src/OAuth2.php | 4 +-- 4 files changed, 4 insertions(+), 36 deletions(-) diff --git a/src/CredentialSource/FileSource.php b/src/CredentialSource/FileSource.php index 5519bf76e..628187d57 100644 --- a/src/CredentialSource/FileSource.php +++ b/src/CredentialSource/FileSource.php @@ -29,7 +29,6 @@ class FileSource implements ExternalAccountCredentialSourceInterface private string $file; private ?string $format; private ?string $subjectTokenFieldName; - private string $cacheKey; /** * @param string $file The file to read the subject token from. diff --git a/src/CredentialSource/UrlSource.php b/src/CredentialSource/UrlSource.php index fbc8fc6e1..02904d9a1 100644 --- a/src/CredentialSource/UrlSource.php +++ b/src/CredentialSource/UrlSource.php @@ -104,6 +104,6 @@ public function fetchSubjectToken(callable $httpHandler = null): string */ public function getCacheKey(): string { - return $this->url . ":" . $this->subjectTokenFieldName; + return $this->url . ':' . $this->subjectTokenFieldName; } } diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index e99eba7ed..b2223d8f1 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -54,13 +54,6 @@ class ExternalAccountCredentials implements private ?string $projectId; private string $universeDomain; - /** - * Used to calculate the Cache Key for caching - * - * @var array - */ - private array $jsonKey; - /** * @param string|string[] $scope The scope of the access request, expressed either as an array * or as a space-delimited string. @@ -129,8 +122,6 @@ public function __construct( 'workforce_pool_user_project should not be set for non-workforce pool credentials.' ); } - - $this->jsonKey = $jsonKey; } /** @@ -287,7 +278,7 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Get the cache token key for the credentials. - * The cache token key format depends on the type of source + * The cache token key format depends on the type of source * was used to configure these credentials. * * @return null|string; @@ -375,26 +366,4 @@ private function isWorkforcePool(): bool $regex = '#//iam\.googleapis\.com/locations/[^/]+/workforcePools/#'; return preg_match($regex, $this->auth->getAudience()) === 1; } - - /** - * @param array $arr - * - * @return array - */ - private function flattenJsonKey(array $arr): array - { - $result = []; - - foreach($arr as $key => $val) { - if (is_array($val)) { - $result = array_merge($result, $this->flattenJsonKey($val)); - } elseif ($val === '') { - continue; - } else { - array_push($result, $val); - } - } - - return $result; - } } diff --git a/src/OAuth2.php b/src/OAuth2.php index 02a2a4f1f..312cbcfde 100644 --- a/src/OAuth2.php +++ b/src/OAuth2.php @@ -684,7 +684,7 @@ public function fetchAuthToken(callable $httpHandler = null, $headers = []) /** * @deprecated - * + * * Obtains a key that can used to cache the results of #fetchAuthToken. * * The key is derived from the scopes. @@ -707,7 +707,7 @@ public function getCacheKey() /** * Gets this instance's SubjectTokenFetcher - * + * * @return null|ExternalAccountCredentialSourceInterface */ public function getSubjectTokenFetcher(): null|ExternalAccountCredentialSourceInterface From d15f2d5a2436cbad0a258e19bd3c9155a930459c Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Thu, 13 Jun 2024 19:47:11 +0000 Subject: [PATCH 07/16] Change the getCacheKey implementation for external account credentials --- src/CredentialSource/AwsNativeSource.php | 2 +- src/CredentialSource/ExecutableSource.php | 4 ++-- src/CredentialSource/FileSource.php | 2 +- src/CredentialSource/UrlSource.php | 6 +++--- src/Credentials/ExternalAccountCredentials.php | 15 ++++++++++++--- src/ExternalAccountCredentialSourceInterface.php | 2 +- src/OAuth2.php | 10 ++++++++++ 7 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index c80be30f5..8dcf802cf 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -335,7 +335,7 @@ public static function getSigningVarsFromEnv(): ?array * * @return string */ - public function getCacheKey(): string + public function getCacheKey(): ?string { return $this->imdsv2SessionTokenUrl . ':' . $this->securityCredentialsUrl . ':' diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index 5611fb26a..916d4cdab 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -104,9 +104,9 @@ public function __construct( * Gets the unique key for caching * This source is considered non cacheable so returns null. * - * @return null|string + * @return ?string */ - public function getCacheKey(): null|string + public function getCacheKey(): ?string { return null; } diff --git a/src/CredentialSource/FileSource.php b/src/CredentialSource/FileSource.php index 628187d57..0b7d49098 100644 --- a/src/CredentialSource/FileSource.php +++ b/src/CredentialSource/FileSource.php @@ -79,7 +79,7 @@ public function fetchSubjectToken(callable $httpHandler = null): string * * @return string */ - public function getCacheKey(): string + public function getCacheKey(): ?string { return $this->file; } diff --git a/src/CredentialSource/UrlSource.php b/src/CredentialSource/UrlSource.php index 02904d9a1..b5ba4f410 100644 --- a/src/CredentialSource/UrlSource.php +++ b/src/CredentialSource/UrlSource.php @@ -100,10 +100,10 @@ public function fetchSubjectToken(callable $httpHandler = null): string * The format for the cache key is: * URL + subjectTokenFieldName * - * @return string + * @return ?string */ - public function getCacheKey(): string + public function getCacheKey(): ?string { - return $this->url . ':' . $this->subjectTokenFieldName; + return $this->url; } } diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index b2223d8f1..36d5cef51 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -281,11 +281,20 @@ public function fetchAuthToken(callable $httpHandler = null) * The cache token key format depends on the type of source * was used to configure these credentials. * - * @return null|string; + * @return ?string; */ - public function getCacheKey(): null|string + public function getCacheKey(): ?string { - return $this->auth->getSubjectTokenFetcher()->getCacheKey(); + $scopeOrAudience = $this->auth->getAudience(); + if (!$scopeOrAudience) { + $scopeOrAudience = $this->auth->getScope(); + } + + return $this->auth->getSubjectTokenFetcher()->getCacheKey() . + $scopeOrAudience . + $this->serviceAccountImpersonationUrl . + $this->auth->getSubjectTokenType() . + $this->workforcePoolUserProject; } public function getLastReceivedToken() diff --git a/src/ExternalAccountCredentialSourceInterface.php b/src/ExternalAccountCredentialSourceInterface.php index 5d3e913fe..041b18d51 100644 --- a/src/ExternalAccountCredentialSourceInterface.php +++ b/src/ExternalAccountCredentialSourceInterface.php @@ -20,5 +20,5 @@ interface ExternalAccountCredentialSourceInterface { public function fetchSubjectToken(callable $httpHandler = null): string; - public function getCacheKey(): null|string; + public function getCacheKey(): ?string; } diff --git a/src/OAuth2.php b/src/OAuth2.php index 312cbcfde..02396a50e 100644 --- a/src/OAuth2.php +++ b/src/OAuth2.php @@ -1032,6 +1032,16 @@ public function getScope() return implode(' ', $this->scope); } + /** + * Gets the subject token type + * + * @return ?string + */ + public function getSubjectTokenType(): ?string + { + return $this->subjectTokenType; + } + /** * Sets the scope of the access request, expressed either as an Array or as * a space-delimited String. From c552aaa9a9dd0492f5da9903e89729656766283a Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Thu, 13 Jun 2024 20:09:36 +0000 Subject: [PATCH 08/16] Fix testing for ExternalAccountCredentials --- src/CredentialSource/AwsNativeSource.php | 11 +++++------ src/Credentials/ExternalAccountCredentials.php | 13 +++++++++++-- .../Credentials/ExternalAccountCredentialsTest.php | 6 +++--- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index 8dcf802cf..bc1c6ec8d 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -335,13 +335,12 @@ public static function getSigningVarsFromEnv(): ?array * * @return string */ - public function getCacheKey(): ?string + public function getCacheKey(): string { - return $this->imdsv2SessionTokenUrl . ':' - . $this->securityCredentialsUrl . ':' - . $this->regionUrl . ':' - . $this->regionalCredVerificationUrl . ':' - . $this->audience; + return $this->imdsv2SessionTokenUrl . + $this->securityCredentialsUrl . + $this->regionUrl . + $this->regionalCredVerificationUrl; } /** diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 36d5cef51..d8f8898a7 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -100,6 +100,9 @@ public function __construct( if (array_key_exists('service_account_impersonation_url', $jsonKey)) { $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url']; + } else { + //If we do not initalize this, getCacheKey throws an error. + $this->serviceAccountImpersonationUrl = null; } $this->quotaProject = $jsonKey['quota_project_id'] ?? null; @@ -284,13 +287,19 @@ public function fetchAuthToken(callable $httpHandler = null) * @return ?string; */ public function getCacheKey(): ?string - { + { + $cacheKey = $this->auth->getSubjectTokenFetcher()->getCacheKey(); + + if ($cacheKey === null) { + return null; + } + $scopeOrAudience = $this->auth->getAudience(); if (!$scopeOrAudience) { $scopeOrAudience = $this->auth->getScope(); } - return $this->auth->getSubjectTokenFetcher()->getCacheKey() . + return $cacheKey . $scopeOrAudience . $this->serviceAccountImpersonationUrl . $this->auth->getSubjectTokenType() . diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index 04c720966..bbf5522c4 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -526,7 +526,7 @@ public function testFileSourceCacheKey() $this->baseCreds['credential_source'] = ['file' => 'fakeFile']; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = 'fakeFile'; + $expectedKey = 'fakeFilescope1'; $this->assertEquals($expectedKey, $cacheKey); } @@ -542,7 +542,7 @@ public function testAWSSourceCacheKey() $this->baseCreds['audience'] = 'audience1'; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = '12345:aws.us-east.token.com:aws.us-east.com:us-east:audience1'; + $expectedKey = '12345aws.us-east.token.comaws.us-east.comus-eastaudience1'; $this->assertEquals($expectedKey, $cacheKey); } @@ -558,7 +558,7 @@ public function testUrlSourceCacheKey() $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = 'fakeUrl:keyShouldBeHere'; + $expectedKey = 'fakeUrlscope1'; $this->assertEquals($expectedKey, $cacheKey); } From 4fab0d50f7bbd872e262f97e662d09ceb97341fa Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Thu, 13 Jun 2024 20:11:50 +0000 Subject: [PATCH 09/16] Fix PHP style --- src/Credentials/ExternalAccountCredentials.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index d8f8898a7..16c254354 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -102,7 +102,7 @@ public function __construct( $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url']; } else { //If we do not initalize this, getCacheKey throws an error. - $this->serviceAccountImpersonationUrl = null; + $this->serviceAccountImpersonationUrl = null; } $this->quotaProject = $jsonKey['quota_project_id'] ?? null; @@ -287,7 +287,7 @@ public function fetchAuthToken(callable $httpHandler = null) * @return ?string; */ public function getCacheKey(): ?string - { + { $cacheKey = $this->auth->getSubjectTokenFetcher()->getCacheKey(); if ($cacheKey === null) { @@ -299,8 +299,8 @@ public function getCacheKey(): ?string $scopeOrAudience = $this->auth->getScope(); } - return $cacheKey . - $scopeOrAudience . + return $cacheKey . + $scopeOrAudience . $this->serviceAccountImpersonationUrl . $this->auth->getSubjectTokenType() . $this->workforcePoolUserProject; From 3b6557b263129643641e55d0b75532cbd14cf18f Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Thu, 13 Jun 2024 21:45:41 +0000 Subject: [PATCH 10/16] Change the getCacheKey implentation to not return null on executable source --- src/CredentialSource/ExecutableSource.php | 2 +- src/Credentials/ExternalAccountCredentials.php | 8 +------- tests/Credentials/ExternalAccountCredentialsTest.php | 7 +++++-- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index 916d4cdab..4624bc23e 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -108,7 +108,7 @@ public function __construct( */ public function getCacheKey(): ?string { - return null; + return $this->command . $this->outputFile; } /** diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 16c254354..991518e47 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -288,18 +288,12 @@ public function fetchAuthToken(callable $httpHandler = null) */ public function getCacheKey(): ?string { - $cacheKey = $this->auth->getSubjectTokenFetcher()->getCacheKey(); - - if ($cacheKey === null) { - return null; - } - $scopeOrAudience = $this->auth->getAudience(); if (!$scopeOrAudience) { $scopeOrAudience = $this->auth->getScope(); } - return $cacheKey . + return $this->auth->getSubjectTokenFetcher()->getCacheKey() . $scopeOrAudience . $this->serviceAccountImpersonationUrl . $this->auth->getSubjectTokenType() . diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index bbf5522c4..4617bdffb 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -566,13 +566,16 @@ public function testExecutableSourceCacheKey() { $this->baseCreds['credential_source'] = [ 'executable' => [ - 'command' => 'ls -al' + 'command' => 'ls -al', + 'output_file' => './output.txt' ] ]; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $this->assertNull($cacheKey); + + $expectedCacheKey = 'ls -al./output.txtscope1'; + $this->assertEquals($cacheKey, $expectedCacheKey); } /** From e208e193e7295fd573b3eaefb9829a2e756068bc Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Fri, 28 Jun 2024 22:25:41 +0000 Subject: [PATCH 11/16] Fix concatenation format and update getCacheKey docs --- src/CredentialSource/AwsNativeSource.php | 2 +- src/CredentialSource/ExecutableSource.php | 2 +- src/Credentials/ServiceAccountCredentials.php | 7 ++++--- src/Credentials/ServiceAccountJwtAccessCredentials.php | 7 ++++--- src/Credentials/UserRefreshCredentials.php | 7 ++++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index bc1c6ec8d..dd71d237b 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -331,7 +331,7 @@ public static function getSigningVarsFromEnv(): ?array /** * Gets the unique key for caching * For AwsNativeSource the values are: - * imdsv2SessionTokenUrl:securityCredentialsUrl:regionUrl:regionalCredVerificationUrl:audience + * * * @return string */ diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index 4624bc23e..1190014cd 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -102,7 +102,7 @@ public function __construct( /** * Gets the unique key for caching - * This source is considered non cacheable so returns null. + * The format for this source is * * @return ?string */ diff --git a/src/Credentials/ServiceAccountCredentials.php b/src/Credentials/ServiceAccountCredentials.php index ac77720a1..88928f393 100644 --- a/src/Credentials/ServiceAccountCredentials.php +++ b/src/Credentials/ServiceAccountCredentials.php @@ -220,8 +220,9 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Return the Cache Key for the credentials. - * For the cache key format is: - * ClientEmail:Scope | Audience:sub. + * For the cache key format is one of the following: + * + * * * @return string */ @@ -232,7 +233,7 @@ public function getCacheKey() $scopeOrAudience = $this->auth->getAudience(); } - $key = $this->auth->getIssuer() . ':' . $scopeOrAudience; + $key = $this->auth->getIssuer() . $scopeOrAudience; if ($sub = $this->auth->getSub()) { $key .= ':' . $sub; } diff --git a/src/Credentials/ServiceAccountJwtAccessCredentials.php b/src/Credentials/ServiceAccountJwtAccessCredentials.php index 4f91c2ffd..7c45bcdc2 100644 --- a/src/Credentials/ServiceAccountJwtAccessCredentials.php +++ b/src/Credentials/ServiceAccountJwtAccessCredentials.php @@ -167,8 +167,9 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Return the cache key for the credentials. - * The format for the Cache Key is: - * ClientEmail:Scope | Audience + * The format for the Cache Key one of the following: + * + * * * @return string */ @@ -179,7 +180,7 @@ public function getCacheKey() $scopeOrAudience = $this->auth->getAudience(); } - return $this->auth->getIssuer() . ':' . $scopeOrAudience; + return $this->auth->getIssuer() . $scopeOrAudience; } /** diff --git a/src/Credentials/UserRefreshCredentials.php b/src/Credentials/UserRefreshCredentials.php index 2ec3337ed..b7dac5999 100644 --- a/src/Credentials/UserRefreshCredentials.php +++ b/src/Credentials/UserRefreshCredentials.php @@ -131,8 +131,9 @@ public function fetchAuthToken(callable $httpHandler = null, array $metricsHeade /** * Return the Cache Key for the credentials. - * The format for the Cache key is: - * ClientId:Scope | Audience + * The format for the Cache key is one of the following: + * + * * * @return string */ @@ -143,7 +144,7 @@ public function getCacheKey() $scopeOrAudience = $this->auth->getAudience(); } - return $this->auth->getClientId() . ':' . $scopeOrAudience; + return $this->auth->getClientId() . $scopeOrAudience; } /** From 5bb22a8399d60840fea66af29bc21e080fed1aa0 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Fri, 28 Jun 2024 22:35:15 +0000 Subject: [PATCH 12/16] Fix tests for getCacheKey --- src/Credentials/ServiceAccountCredentials.php | 2 +- tests/Credentials/ServiceAccountCredentialsTest.php | 6 +++--- .../Credentials/ServiceAccountJwtAccessCredentialsTest.php | 2 +- tests/Credentials/UserRefreshCredentialsTest.php | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Credentials/ServiceAccountCredentials.php b/src/Credentials/ServiceAccountCredentials.php index 88928f393..5b1955624 100644 --- a/src/Credentials/ServiceAccountCredentials.php +++ b/src/Credentials/ServiceAccountCredentials.php @@ -235,7 +235,7 @@ public function getCacheKey() $key = $this->auth->getIssuer() . $scopeOrAudience; if ($sub = $this->auth->getSub()) { - $key .= ':' . $sub; + $key .= $sub; } return $key; diff --git a/tests/Credentials/ServiceAccountCredentialsTest.php b/tests/Credentials/ServiceAccountCredentialsTest.php index 0a3e57402..ee8fe9dc8 100644 --- a/tests/Credentials/ServiceAccountCredentialsTest.php +++ b/tests/Credentials/ServiceAccountCredentialsTest.php @@ -54,7 +54,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . ':' . implode(' ', $scope), + $testJson['client_email'] . implode(' ', $scope), $sa->getCacheKey() ); } @@ -71,7 +71,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScopeWithSub() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . ':' . implode(' ', $scope) . ':' . $sub, + $testJson['client_email'] . implode(' ', $scope) . $sub, $sa->getCacheKey() ); } @@ -90,7 +90,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScopeWithSubAddedLater() $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . ':' . implode(' ', $scope) . ':' . $sub, + $testJson['client_email'] . implode(' ', $scope) . $sub, $sa->getCacheKey() ); } diff --git a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php index 73e4db821..0096b6e82 100644 --- a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php +++ b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php @@ -482,7 +482,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() $scope = ['scope/1', 'scope/2']; $sa = new ServiceAccountJwtAccessCredentials($testJson, $scope); - $expectedKey = $testJson['client_email'] . ':' . implode(' ', $scope); + $expectedKey = $testJson['client_email'] . implode(' ', $scope); $this->assertEquals($expectedKey, $sa->getCacheKey()); } diff --git a/tests/Credentials/UserRefreshCredentialsTest.php b/tests/Credentials/UserRefreshCredentialsTest.php index 4360354cf..416dbf771 100644 --- a/tests/Credentials/UserRefreshCredentialsTest.php +++ b/tests/Credentials/UserRefreshCredentialsTest.php @@ -50,7 +50,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_id'] . ':' . implode(' ', $scope), + $testJson['client_id'] . implode(' ', $scope), $sa->getCacheKey() ); } From a1670727b50bda2dea6ca5f51759b87ab26983ac Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Wed, 3 Jul 2024 15:07:44 +0000 Subject: [PATCH 13/16] Change cache key formatting --- src/CredentialSource/AwsNativeSource.php | 10 ++++----- src/CredentialSource/ExecutableSource.php | 4 ++-- .../ExternalAccountCredentials.php | 21 ++++++++++++++----- src/Credentials/ServiceAccountCredentials.php | 8 +++---- .../ServiceAccountJwtAccessCredentials.php | 6 +++--- src/Credentials/UserRefreshCredentials.php | 6 +++--- .../ExternalAccountCredentialsTest.php | 8 +++---- .../ServiceAccountCredentialsTest.php | 6 +++--- ...ServiceAccountJwtAccessCredentialsTest.php | 2 +- .../UserRefreshCredentialsTest.php | 2 +- 10 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index dd71d237b..c05b9b555 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -331,16 +331,16 @@ public static function getSigningVarsFromEnv(): ?array /** * Gets the unique key for caching * For AwsNativeSource the values are: - * + * imdsv2SessionTokenUrl.securityCredentialsUrl.regionUrl.regionalCredVerificationUrl * * @return string */ public function getCacheKey(): string { - return $this->imdsv2SessionTokenUrl . - $this->securityCredentialsUrl . - $this->regionUrl . - $this->regionalCredVerificationUrl; + return ($this->imdsv2SessionTokenUrl ? $this->imdsv2SessionTokenUrl : '') . + '.' . ($this->securityCredentialsUrl ? $this->securityCredentialsUrl : '') . + '.' . $this->regionUrl . + '.' . $this->regionalCredVerificationUrl; } /** diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index 1190014cd..1746704bf 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -102,13 +102,13 @@ public function __construct( /** * Gets the unique key for caching - * The format for this source is + * The format for this source is command.outputFile * * @return ?string */ public function getCacheKey(): ?string { - return $this->command . $this->outputFile; + return $this->command . '.' . $this->outputFile; } /** diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 991518e47..55b13a94c 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -282,7 +282,9 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Get the cache token key for the credentials. * The cache token key format depends on the type of source - * was used to configure these credentials. + * The format for the Cache Key one of the following: + * FetcherCacheKey.scope.tokenType.workforcePoolUserProject + * FetcherCacheKey.audience.tokenType.workforcePoolUserProject * * @return ?string; */ @@ -294,10 +296,10 @@ public function getCacheKey(): ?string } return $this->auth->getSubjectTokenFetcher()->getCacheKey() . - $scopeOrAudience . - $this->serviceAccountImpersonationUrl . - $this->auth->getSubjectTokenType() . - $this->workforcePoolUserProject; + '.' . $scopeOrAudience . + $this->concatenateValueOrEmpty($this->serviceAccountImpersonationUrl) . + $this->concatenateValueOrEmpty($this->auth->getSubjectTokenType()) . + $this->concatenateValueOrEmpty($this->workforcePoolUserProject); } public function getLastReceivedToken() @@ -378,4 +380,13 @@ private function isWorkforcePool(): bool $regex = '#//iam\.googleapis\.com/locations/[^/]+/workforcePools/#'; return preg_match($regex, $this->auth->getAudience()) === 1; } + + private function concatenateValueOrEmpty(string|null $value): string + { + if (!$value) { + return ''; + } + + return '.' . $value; + } } diff --git a/src/Credentials/ServiceAccountCredentials.php b/src/Credentials/ServiceAccountCredentials.php index 5b1955624..4090b8931 100644 --- a/src/Credentials/ServiceAccountCredentials.php +++ b/src/Credentials/ServiceAccountCredentials.php @@ -221,8 +221,8 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Return the Cache Key for the credentials. * For the cache key format is one of the following: - * - * + * ClientEmail.Scope[.Sub] + * ClientEmail.Audience[.Sub] * * @return string */ @@ -233,9 +233,9 @@ public function getCacheKey() $scopeOrAudience = $this->auth->getAudience(); } - $key = $this->auth->getIssuer() . $scopeOrAudience; + $key = $this->auth->getIssuer() . '.' . $scopeOrAudience; if ($sub = $this->auth->getSub()) { - $key .= $sub; + $key .= '.' . $sub; } return $key; diff --git a/src/Credentials/ServiceAccountJwtAccessCredentials.php b/src/Credentials/ServiceAccountJwtAccessCredentials.php index 7c45bcdc2..6c582a830 100644 --- a/src/Credentials/ServiceAccountJwtAccessCredentials.php +++ b/src/Credentials/ServiceAccountJwtAccessCredentials.php @@ -168,8 +168,8 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Return the cache key for the credentials. * The format for the Cache Key one of the following: - * - * + * ClientEmail.Scope + * ClientEmail.Audience * * @return string */ @@ -180,7 +180,7 @@ public function getCacheKey() $scopeOrAudience = $this->auth->getAudience(); } - return $this->auth->getIssuer() . $scopeOrAudience; + return $this->auth->getIssuer() . '.' . $scopeOrAudience; } /** diff --git a/src/Credentials/UserRefreshCredentials.php b/src/Credentials/UserRefreshCredentials.php index b7dac5999..d40055562 100644 --- a/src/Credentials/UserRefreshCredentials.php +++ b/src/Credentials/UserRefreshCredentials.php @@ -132,8 +132,8 @@ public function fetchAuthToken(callable $httpHandler = null, array $metricsHeade /** * Return the Cache Key for the credentials. * The format for the Cache key is one of the following: - * - * + * ClientId.Scope + * ClientId.Audience * * @return string */ @@ -144,7 +144,7 @@ public function getCacheKey() $scopeOrAudience = $this->auth->getAudience(); } - return $this->auth->getClientId() . $scopeOrAudience; + return $this->auth->getClientId() . '.' . $scopeOrAudience; } /** diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index 4617bdffb..238beef32 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -526,7 +526,7 @@ public function testFileSourceCacheKey() $this->baseCreds['credential_source'] = ['file' => 'fakeFile']; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = 'fakeFilescope1'; + $expectedKey = 'fakeFile.scope1'; $this->assertEquals($expectedKey, $cacheKey); } @@ -542,7 +542,7 @@ public function testAWSSourceCacheKey() $this->baseCreds['audience'] = 'audience1'; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = '12345aws.us-east.token.comaws.us-east.comus-eastaudience1'; + $expectedKey = '12345.aws.us-east.token.com.aws.us-east.com.us-east.audience1'; $this->assertEquals($expectedKey, $cacheKey); } @@ -558,7 +558,7 @@ public function testUrlSourceCacheKey() $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = 'fakeUrlscope1'; + $expectedKey = 'fakeUrl.scope1'; $this->assertEquals($expectedKey, $cacheKey); } @@ -574,7 +574,7 @@ public function testExecutableSourceCacheKey() $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedCacheKey = 'ls -al./output.txtscope1'; + $expectedCacheKey = 'ls -al../output.txt.scope1'; $this->assertEquals($cacheKey, $expectedCacheKey); } diff --git a/tests/Credentials/ServiceAccountCredentialsTest.php b/tests/Credentials/ServiceAccountCredentialsTest.php index ee8fe9dc8..818f543ef 100644 --- a/tests/Credentials/ServiceAccountCredentialsTest.php +++ b/tests/Credentials/ServiceAccountCredentialsTest.php @@ -54,7 +54,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . implode(' ', $scope), + $testJson['client_email'] . '.' . implode(' ', $scope), $sa->getCacheKey() ); } @@ -71,7 +71,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScopeWithSub() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . implode(' ', $scope) . $sub, + $testJson['client_email'] . '.' . implode(' ', $scope) . '.' . $sub, $sa->getCacheKey() ); } @@ -90,7 +90,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScopeWithSubAddedLater() $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_email'] . implode(' ', $scope) . $sub, + $testJson['client_email'] . '.' . implode(' ', $scope) . '.' . $sub, $sa->getCacheKey() ); } diff --git a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php index 0096b6e82..2cac3dac1 100644 --- a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php +++ b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php @@ -482,7 +482,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() $scope = ['scope/1', 'scope/2']; $sa = new ServiceAccountJwtAccessCredentials($testJson, $scope); - $expectedKey = $testJson['client_email'] . implode(' ', $scope); + $expectedKey = $testJson['client_email'] . '.' . implode(' ', $scope); $this->assertEquals($expectedKey, $sa->getCacheKey()); } diff --git a/tests/Credentials/UserRefreshCredentialsTest.php b/tests/Credentials/UserRefreshCredentialsTest.php index 416dbf771..3825852c9 100644 --- a/tests/Credentials/UserRefreshCredentialsTest.php +++ b/tests/Credentials/UserRefreshCredentialsTest.php @@ -50,7 +50,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_id'] . implode(' ', $scope), + $testJson['client_id'] . '.'. implode(' ', $scope), $sa->getCacheKey() ); } From a90dc604a528a276311ff6b0d936f56420607c36 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Wed, 3 Jul 2024 15:09:29 +0000 Subject: [PATCH 14/16] Fix php style --- tests/Credentials/UserRefreshCredentialsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Credentials/UserRefreshCredentialsTest.php b/tests/Credentials/UserRefreshCredentialsTest.php index 3825852c9..b944dd40e 100644 --- a/tests/Credentials/UserRefreshCredentialsTest.php +++ b/tests/Credentials/UserRefreshCredentialsTest.php @@ -50,7 +50,7 @@ public function testShouldBeTheSameAsOAuth2WithTheSameScope() ); $o = new OAuth2(['scope' => $scope]); $this->assertSame( - $testJson['client_id'] . '.'. implode(' ', $scope), + $testJson['client_id'] . '.' . implode(' ', $scope), $sa->getCacheKey() ); } From 13a29e2d81f7d8248633424fe22f70967e147925 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Tue, 9 Jul 2024 18:29:54 +0000 Subject: [PATCH 15/16] Fix format documentation for the cache keys --- src/CredentialSource/AwsNativeSource.php | 2 +- src/CredentialSource/ExecutableSource.php | 3 ++- src/CredentialSource/FileSource.php | 3 ++- src/CredentialSource/UrlSource.php | 2 +- src/Credentials/ExternalAccountCredentials.php | 6 +++--- src/Credentials/GCECredentials.php | 3 ++- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index c05b9b555..96c096a2a 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -331,7 +331,7 @@ public static function getSigningVarsFromEnv(): ?array /** * Gets the unique key for caching * For AwsNativeSource the values are: - * imdsv2SessionTokenUrl.securityCredentialsUrl.regionUrl.regionalCredVerificationUrl + * Imdsv2SessionTokenUrl.SecurityCredentialsUrl.RegionUrl.RegionalCredVerificationUrl * * @return string */ diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index 1746704bf..ce3bd9fda 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -102,7 +102,8 @@ public function __construct( /** * Gets the unique key for caching - * The format for this source is command.outputFile + * The format for the cache key is: + * Command.OutputFile * * @return ?string */ diff --git a/src/CredentialSource/FileSource.php b/src/CredentialSource/FileSource.php index 0b7d49098..00ac835a8 100644 --- a/src/CredentialSource/FileSource.php +++ b/src/CredentialSource/FileSource.php @@ -75,7 +75,8 @@ public function fetchSubjectToken(callable $httpHandler = null): string /** * Gets the unique key for caching. - * The CacheKey is the File name provided on the constructor. + * The format for the cache key one of the following: + * Filename * * @return string */ diff --git a/src/CredentialSource/UrlSource.php b/src/CredentialSource/UrlSource.php index b5ba4f410..6046d52fa 100644 --- a/src/CredentialSource/UrlSource.php +++ b/src/CredentialSource/UrlSource.php @@ -98,7 +98,7 @@ public function fetchSubjectToken(callable $httpHandler = null): string /** * Get the cache key for the credentials. * The format for the cache key is: - * URL + subjectTokenFieldName + * URL * * @return ?string */ diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index 55b13a94c..c49d2d4de 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -282,9 +282,9 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Get the cache token key for the credentials. * The cache token key format depends on the type of source - * The format for the Cache Key one of the following: - * FetcherCacheKey.scope.tokenType.workforcePoolUserProject - * FetcherCacheKey.audience.tokenType.workforcePoolUserProject + * The format for the cache key one of the following: + * FetcherCacheKey.Scope.[ServiceAccount].[TokenType].[WorkforcePoolUserProject] + * FetcherCacheKey.Audience.[ServiceAccount].[TokenType].[WorkforcePoolUserProject] * * @return ?string; */ diff --git a/src/Credentials/GCECredentials.php b/src/Credentials/GCECredentials.php index fdcbe84b5..8b7547816 100644 --- a/src/Credentials/GCECredentials.php +++ b/src/Credentials/GCECredentials.php @@ -490,7 +490,8 @@ public function fetchAuthToken(callable $httpHandler = null) /** * Returns the Cache Key for the credential token. - * The cache key is the TokenURI given to the constructor. + * The format for the cache key is: + * TokenURI * * @return string */ From 850244d124e466d1a225ec3e28e64356fce3c713 Mon Sep 17 00:00:00 2001 From: Hector Mendoza Jacobo Date: Tue, 9 Jul 2024 22:43:37 +0000 Subject: [PATCH 16/16] Change logic for appending fields to the cache key --- src/CredentialSource/AwsNativeSource.php | 4 ++-- .../ExternalAccountCredentials.php | 22 ++++--------------- src/OAuth2.php | 2 +- .../ExternalAccountCredentialsTest.php | 8 +++---- 4 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index 96c096a2a..6d9244ba2 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -337,8 +337,8 @@ public static function getSigningVarsFromEnv(): ?array */ public function getCacheKey(): string { - return ($this->imdsv2SessionTokenUrl ? $this->imdsv2SessionTokenUrl : '') . - '.' . ($this->securityCredentialsUrl ? $this->securityCredentialsUrl : '') . + return ($this->imdsv2SessionTokenUrl ?? '') . + '.' . ($this->securityCredentialsUrl ?? '') . '.' . $this->regionUrl . '.' . $this->regionalCredVerificationUrl; } diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index c49d2d4de..3614d24d0 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -98,12 +98,7 @@ public function __construct( ); } - if (array_key_exists('service_account_impersonation_url', $jsonKey)) { - $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url']; - } else { - //If we do not initalize this, getCacheKey throws an error. - $this->serviceAccountImpersonationUrl = null; - } + $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url'] ?? null; $this->quotaProject = $jsonKey['quota_project_id'] ?? null; $this->workforcePoolUserProject = $jsonKey['workforce_pool_user_project'] ?? null; @@ -297,9 +292,9 @@ public function getCacheKey(): ?string return $this->auth->getSubjectTokenFetcher()->getCacheKey() . '.' . $scopeOrAudience . - $this->concatenateValueOrEmpty($this->serviceAccountImpersonationUrl) . - $this->concatenateValueOrEmpty($this->auth->getSubjectTokenType()) . - $this->concatenateValueOrEmpty($this->workforcePoolUserProject); + '.' . ($this->serviceAccountImpersonationUrl ?? '') . + '.' . ($this->auth->getSubjectTokenType() ?? '') . + '.' . ($this->workforcePoolUserProject ?? ''); } public function getLastReceivedToken() @@ -380,13 +375,4 @@ private function isWorkforcePool(): bool $regex = '#//iam\.googleapis\.com/locations/[^/]+/workforcePools/#'; return preg_match($regex, $this->auth->getAudience()) === 1; } - - private function concatenateValueOrEmpty(string|null $value): string - { - if (!$value) { - return ''; - } - - return '.' . $value; - } } diff --git a/src/OAuth2.php b/src/OAuth2.php index 02396a50e..4019e258a 100644 --- a/src/OAuth2.php +++ b/src/OAuth2.php @@ -710,7 +710,7 @@ public function getCacheKey() * * @return null|ExternalAccountCredentialSourceInterface */ - public function getSubjectTokenFetcher(): null|ExternalAccountCredentialSourceInterface + public function getSubjectTokenFetcher(): ?ExternalAccountCredentialSourceInterface { return $this->subjectTokenFetcher; } diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index 238beef32..09cac05db 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -526,7 +526,7 @@ public function testFileSourceCacheKey() $this->baseCreds['credential_source'] = ['file' => 'fakeFile']; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = 'fakeFile.scope1'; + $expectedKey = 'fakeFile.scope1...'; $this->assertEquals($expectedKey, $cacheKey); } @@ -542,7 +542,7 @@ public function testAWSSourceCacheKey() $this->baseCreds['audience'] = 'audience1'; $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = '12345.aws.us-east.token.com.aws.us-east.com.us-east.audience1'; + $expectedKey = '12345.aws.us-east.token.com.aws.us-east.com.us-east.audience1...'; $this->assertEquals($expectedKey, $cacheKey); } @@ -558,7 +558,7 @@ public function testUrlSourceCacheKey() $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedKey = 'fakeUrl.scope1'; + $expectedKey = 'fakeUrl.scope1...'; $this->assertEquals($expectedKey, $cacheKey); } @@ -574,7 +574,7 @@ public function testExecutableSourceCacheKey() $credentials = new ExternalAccountCredentials('scope1', $this->baseCreds); $cacheKey = $credentials->getCacheKey(); - $expectedCacheKey = 'ls -al../output.txt.scope1'; + $expectedCacheKey = 'ls -al../output.txt.scope1...'; $this->assertEquals($cacheKey, $expectedCacheKey); }