diff --git a/src/Credentials/ServiceAccountCredentials.php b/src/Credentials/ServiceAccountCredentials.php index 76aa0fc99..086417c07 100644 --- a/src/Credentials/ServiceAccountCredentials.php +++ b/src/Credentials/ServiceAccountCredentials.php @@ -99,6 +99,11 @@ class ServiceAccountCredentials extends CredentialsLoader implements */ private $jwtAccessCredentials; + /** + * @var string|null + */ + private ?string $universeDomain; + /** * Create a new ServiceAccountCredentials. * @@ -159,6 +164,7 @@ public function __construct( ]); $this->projectId = $jsonKey['project_id'] ?? null; + $this->universeDomain = $jsonKey['universe_domain'] ?? null; } /** @@ -328,6 +334,19 @@ public function getQuotaProject() return $this->quotaProject; } + /** + * Get the universe domain configured in the JSON credential. + * + * @return string + */ + public function getUniverseDomain(): string + { + if (null === $this->universeDomain) { + return self::DEFAULT_UNIVERSE_DOMAIN; + } + return $this->universeDomain; + } + /** * @return bool */ diff --git a/src/CredentialsLoader.php b/src/CredentialsLoader.php index 9e28701ed..746b957a9 100644 --- a/src/CredentialsLoader.php +++ b/src/CredentialsLoader.php @@ -30,6 +30,7 @@ * credentials files on the file system. */ abstract class CredentialsLoader implements + GetUniverseDomainInterface, FetchAuthTokenInterface, UpdateMetadataInterface { @@ -273,4 +274,15 @@ private static function loadDefaultClientCertSourceFile() } return $clientCertSourceJson; } + + /** + * Get the universe domain from the credential. Defaults to "googleapis.com" + * for all credential types which do not support universe domain. + * + * @return string + */ + public function getUniverseDomain(): string + { + return self::DEFAULT_UNIVERSE_DOMAIN; + } } diff --git a/src/FetchAuthTokenCache.php b/src/FetchAuthTokenCache.php index 47174a1b7..cac1984ab 100644 --- a/src/FetchAuthTokenCache.php +++ b/src/FetchAuthTokenCache.php @@ -26,6 +26,7 @@ class FetchAuthTokenCache implements FetchAuthTokenInterface, GetQuotaProjectInterface, + GetUniverseDomainInterface, SignBlobInterface, ProjectIdProviderInterface, UpdateMetadataInterface @@ -191,6 +192,20 @@ public function getProjectId(callable $httpHandler = null) return $this->fetcher->getProjectId($httpHandler); } + /* + * Get the Universe Domain from the fetcher. + * + * @return string + */ + public function getUniverseDomain(): string + { + if ($this->fetcher instanceof GetUniverseDomainInterface) { + return $this->fetcher->getUniverseDomain(); + } + + return GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; + } + /** * Updates metadata with the authorization token. * diff --git a/src/GetUniverseDomainInterface.php b/src/GetUniverseDomainInterface.php new file mode 100644 index 000000000..1656ddc2e --- /dev/null +++ b/src/GetUniverseDomainInterface.php @@ -0,0 +1,35 @@ +assertEquals(CredentialsLoader::DEFAULT_UNIVERSE_DOMAIN, $creds->getUniverseDomain()); + + // Test universe domain in "service_account" keyfile + $keyFile = __DIR__ . '/fixtures/private.json'; + putenv(ServiceAccountCredentials::ENV_VAR . '=' . $keyFile); + $creds = ApplicationDefaultCredentials::getCredentials(); + $this->assertEquals('example-universe.com', $creds->getUniverseDomain()); + + // Test universe domain in "authenticated_user" keyfile is not read. + $keyFile = __DIR__ . '/fixtures2/private.json'; + putenv(ServiceAccountCredentials::ENV_VAR . '=' . $keyFile); + $creds2 = ApplicationDefaultCredentials::getCredentials(); + $this->assertEquals(CredentialsLoader::DEFAULT_UNIVERSE_DOMAIN, $creds2->getUniverseDomain()); + } } diff --git a/tests/Credentials/GCECredentialsTest.php b/tests/Credentials/GCECredentialsTest.php index 0d36e6771..9369e40ac 100644 --- a/tests/Credentials/GCECredentialsTest.php +++ b/tests/Credentials/GCECredentialsTest.php @@ -512,4 +512,12 @@ public function testGetClientNameWithServiceAccountIdentity() $creds = new GCECredentials(null, null, null, null, 'foo'); $this->assertEquals($expected, $creds->getClientName($httpHandler)); } + + public function testGetUniverseDomain() + { + $creds = new GCECredentials(); + + // Universe domain should always be the default + $this->assertEquals(GCECredentials::DEFAULT_UNIVERSE_DOMAIN, $creds->getUniverseDomain()); + } } diff --git a/tests/FetchAuthTokenCacheTest.php b/tests/FetchAuthTokenCacheTest.php index f59c9295a..21a68e702 100644 --- a/tests/FetchAuthTokenCacheTest.php +++ b/tests/FetchAuthTokenCacheTest.php @@ -21,6 +21,7 @@ use Google\Auth\Credentials\ServiceAccountCredentials; use Google\Auth\CredentialsLoader; use Google\Auth\FetchAuthTokenCache; +use Google\Auth\GetUniverseDomainInterface; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use RuntimeException; @@ -603,6 +604,41 @@ public function testGetProjectIdInvalidFetcher() $fetcher->getProjectId(); } + public function testGetUniverseDomain() + { + $universeDomain = 'foobar'; + + $mockFetcher = $this->prophesize('Google\Auth\GetUniverseDomainInterface'); + $mockFetcher->willImplement('Google\Auth\FetchAuthTokenInterface'); + $mockFetcher->getUniverseDomain() + ->shouldBeCalled() + ->willReturn($universeDomain); + + $fetcher = new FetchAuthTokenCache( + $mockFetcher->reveal(), + [], + $this->mockCache->reveal() + ); + + $this->assertEquals($universeDomain, $fetcher->getUniverseDomain()); + } + + public function testGetUniverseDomainInvalidFetcher() + { + $mockFetcher = $this->prophesize('Google\Auth\FetchAuthTokenInterface'); + + $fetcher = new FetchAuthTokenCache( + $mockFetcher->reveal(), + [], + $this->mockCache->reveal() + ); + + $this->assertEquals( + GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN, + $fetcher->getUniverseDomain() + ); + } + public function testGetFetcher() { $mockFetcher = $this->prophesize('Google\Auth\FetchAuthTokenInterface') diff --git a/tests/fixtures/private.json b/tests/fixtures/private.json index 5d6d1ea64..ef1d49507 100644 --- a/tests/fixtures/private.json +++ b/tests/fixtures/private.json @@ -4,5 +4,6 @@ "client_email": "hello@youarecool.com", "client_id": "client123", "type": "service_account", - "quota_project_id": "test_quota_project" + "quota_project_id": "test_quota_project", + "universe_domain": "example-universe.com" } diff --git a/tests/fixtures2/private.json b/tests/fixtures2/private.json index 20bb61793..9ae0aae96 100644 --- a/tests/fixtures2/private.json +++ b/tests/fixtures2/private.json @@ -3,5 +3,6 @@ "client_secret": "clientSecret123", "refresh_token": "refreshToken123", "type": "authorized_user", - "quota_project_id": "test_quota_project" + "quota_project_id": "test_quota_project", + "universe_domain": "example-universe.com" }