Skip to content

Commit

Permalink
feat: universe domain for Iam (#531)
Browse files Browse the repository at this point in the history
  • Loading branch information
bshaffer authored Feb 20, 2024
1 parent 6e9c9fd commit b905a56
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/Credentials/ExternalAccountCredentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ExternalAccountCredentials implements
use UpdateMetadataTrait;

private const EXTERNAL_ACCOUNT_TYPE = 'external_account';
private const CLOUD_RESOURCE_MANAGER_URL='https://cloudresourcemanager.UNIVERSE_DOMAIN/v1/projects/%s';
private const CLOUD_RESOURCE_MANAGER_URL = 'https://cloudresourcemanager.UNIVERSE_DOMAIN/v1/projects/%s';

private OAuth2 $auth;
private ?string $quotaProject;
Expand Down
16 changes: 13 additions & 3 deletions src/Iam.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,31 @@
*/
class Iam
{
/**
* @deprecated
*/
const IAM_API_ROOT = 'https://iamcredentials.googleapis.com/v1';
const SIGN_BLOB_PATH = '%s:signBlob?alt=json';
const SERVICE_ACCOUNT_NAME = 'projects/-/serviceAccounts/%s';
private const IAM_API_ROOT_TEMPLATE = 'https://iamcredentials.UNIVERSE_DOMAIN/v1';

/**
* @var callable
*/
private $httpHandler;

private string $universeDomain;

/**
* @param callable $httpHandler [optional] The HTTP Handler to send requests.
*/
public function __construct(callable $httpHandler = null)
{
public function __construct(
callable $httpHandler = null,
string $universeDomain = GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN
) {
$this->httpHandler = $httpHandler
?: HttpHandlerFactory::build(HttpClientCache::getHttpClient());
$this->universeDomain = $universeDomain;
}

/**
Expand All @@ -66,7 +75,8 @@ public function signBlob($email, $accessToken, $stringToSign, array $delegates =
{
$httpHandler = $this->httpHandler;
$name = sprintf(self::SERVICE_ACCOUNT_NAME, $email);
$uri = self::IAM_API_ROOT . '/' . sprintf(self::SIGN_BLOB_PATH, $name);
$apiRoot = str_replace('UNIVERSE_DOMAIN', $this->universeDomain, self::IAM_API_ROOT_TEMPLATE);
$uri = $apiRoot . '/' . sprintf(self::SIGN_BLOB_PATH, $name);

if ($delegates) {
foreach ($delegates as &$delegate) {
Expand Down
7 changes: 6 additions & 1 deletion src/IamSignerTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ public function signBlob($stringToSign, $forceOpenSsl = false, $accessToken = nu

// Providing a signer is useful for testing, but it's undocumented
// because it's not something a user would generally need to do.
$signer = $this->iam ?: new Iam($httpHandler);
$signer = $this->iam;
if (!$signer) {
$signer = $this instanceof GetUniverseDomainInterface
? new Iam($httpHandler, $this->getUniverseDomain())
: new Iam($httpHandler);
}

$email = $this->getClientName($httpHandler);

Expand Down
39 changes: 39 additions & 0 deletions tests/Credentials/GCECredentialsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use Google\Auth\Tests\BaseTest;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Utils;
use InvalidArgumentException;
Expand Down Expand Up @@ -380,6 +381,44 @@ public function testSignBlobWithLastReceivedAccessToken()
$signature = $creds->signBlob($stringToSign);
}

public function testSignBlobWithUniverseDomain()
{
$token = [
'access_token' => 'token',
'expires_in' => '57',
'token_type' => 'Bearer',
];
$signedBlob = ['signedBlob' => 'abc123'];
$client = $this->prophesize('GuzzleHttp\ClientInterface');
$client->send(Argument::any(), Argument::any())
->willReturn(
new Response(200, [], Utils::streamFor('[email protected]')),
new Response(200, [], Utils::streamFor(json_encode($token)))
);
$client->send(
Argument::that(
fn (Request $request) => $request->getUri()->getHost() === 'iamcredentials.example-universe.com'
),
Argument::any()
)
->shouldBeCalledOnce()
->willReturn(new Response(200, [], Utils::streamFor(json_encode($signedBlob))));

HttpClientCache::setHttpClient($client->reveal());

$creds = new GCECredentials(
null,
null,
null,
null,
null,
'example-universe.com'
);
$creds->setIsOnGce(true);
$signature = $creds->signBlob('inputString');
$this->assertEquals('abc123', $signature);
}

public function testGetProjectId()
{
$expected = 'foobar';
Expand Down

0 comments on commit b905a56

Please sign in to comment.