Skip to content

Commit

Permalink
fix: Allow id token caching incase of gce cred
Browse files Browse the repository at this point in the history
* Implement logic
* Test logic
  • Loading branch information
yash30201 committed Dec 29, 2023
1 parent 21f9292 commit 6765476
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/Credentials/GCECredentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ public function fetchAuthToken(callable $httpHandler = null)
$response = $this->getFromMetadata($httpHandler, $this->tokenUri);

if ($this->targetAudience) {
return ['id_token' => $response];
$this->lastReceivedToken = ['id_token' => $response];
return $this->lastReceivedToken;
}

if (null === $json = json_decode($response, true)) {
Expand All @@ -448,14 +449,20 @@ public function getCacheKey()
}

/**
* @return array{access_token:string,expires_at:int}|null
* @return array<mixed>|null
*/
public function getLastReceivedToken()
{
if ($this->lastReceivedToken) {
if (array_key_exists('id_token', $this->lastReceivedToken)) {
return [
'id_token' => $this->lastReceivedToken['id_token']
];
}

return [
'access_token' => $this->lastReceivedToken['access_token'],
'expires_at' => $this->lastReceivedToken['expires_at'],
'expires_at' => $this->lastReceivedToken['expires_at']
];
}

Expand Down
4 changes: 4 additions & 0 deletions src/FetchAuthTokenCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ public function updateMetadata(
$metadata[self::AUTH_METADATA_KEY] = [
'Bearer ' . $cached['access_token']
];
} elseif (isset($cached['id_token'])) {
$metadata[self::AUTH_METADATA_KEY] = [
'Bearer ' . $cached['id_token']
];
}
}

Expand Down
15 changes: 15 additions & 0 deletions tests/Credentials/GCECredentialsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,21 @@ public function testGetLastReceivedTokenIsNullByDefault()
$this->assertNull($creds->getLastReceivedToken());
}

public function testGetLastReceivedTokenShouldWorkWithIdToken()
{
$idToken = '123asdfghjkl';
$httpHandler = getHandler([
new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']),
new Response(200, [], Utils::streamFor($idToken)),
]);
$g = new GCECredentials(null, null, 'https://example.test.com');
$g->fetchAuthToken($httpHandler);
$this->assertEquals(
$idToken,
$g->getLastReceivedToken()['id_token']
);
}

public function testGetClientName()
{
$expected = 'foobar';
Expand Down
49 changes: 49 additions & 0 deletions tests/FetchAuthTokenCacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
namespace Google\Auth\Tests;

use Google\Auth\Cache\MemoryCacheItemPool;
use Google\Auth\Credentials\GCECredentials;
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\CredentialsLoader;
use Google\Auth\FetchAuthTokenCache;
use Google\Auth\GetUniverseDomainInterface;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Utils;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use RuntimeException;
Expand Down Expand Up @@ -235,6 +238,52 @@ public function testUpdateMetadataWithJwtAccess()
$this->assertNotEquals($metadata, $metadata3);
}

public function testUpdateMetadataWithGceCredForIdToken()
{
$idToken = '123asdfghjkl';
$httpHandler = getHandler([
new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']),
new Response(200, [], Utils::streamFor($idToken)),
]);
$fetcher = new GCECredentials(null, null, 'https://example.test.com');
$cache = new MemoryCacheItemPool();

$cachedFetcher = new FetchAuthTokenCache(
$fetcher,
null,
$cache
);
$metadata = $cachedFetcher->updateMetadata(
[],
'http://test-auth-uri',
$httpHandler
);
$this->assertArrayHasKey(
CredentialsLoader::AUTH_METADATA_KEY,
$metadata
);

$authorization = $metadata[CredentialsLoader::AUTH_METADATA_KEY];
$this->assertTrue(is_array($authorization));

$bearerToken = current($authorization);
$this->assertTrue(is_string($bearerToken));
$this->assertEquals(0, strpos($bearerToken, 'Bearer '));
$token = str_replace('Bearer ', '', $bearerToken);

$lastReceivedToken = $cachedFetcher->getLastReceivedToken();
$this->assertArrayHasKey('id_token', $lastReceivedToken);
$this->assertEquals($idToken, $lastReceivedToken['id_token']);

// Ensure token is cached
$metadata2 = $cachedFetcher->updateMetadata([], 'http://test-auth-uri');
$this->assertEquals($metadata, $metadata2);

// Ensure token for different URI is NOT cached
$metadata3 = $cachedFetcher->updateMetadata([], 'http://test-auth-uri-2');
$this->assertNotEquals($metadata, $metadata3);
}

public function testUpdateMetadataWithInvalidFetcher()
{
$this->expectException(RuntimeException::class);
Expand Down

0 comments on commit 6765476

Please sign in to comment.