Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: universe domain for Iam #531

Merged
merged 4 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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