Skip to content

Commit

Permalink
feat: allow ServiceAccountJwtAccessCredentials to sign scopes (#326)
Browse files Browse the repository at this point in the history
**TODO** 
- [x] Merge and tag googleapis/google-auth-library-php#341
- [x] Update minimum `google/auth` version in `composer.json` to the new tag ([v1.16.0](https://github.com/googleapis/google-auth-library-php/releases/tag/v1.16.0))
- [x] Add `'useJwtAccessWithScopes' => false` to `gapic-generator-php` for DIREGAPIC APIs (done in googleapis/gapic-generator-php#309)
- [x] Generate a new [Gapic Compute client](https://github.com/googleapis/google-cloud-php/tree/master/Compute) with the changes in googleapis/gapic-generator-php#309

_Note_: These steps are now optional because Compute does not need the exclusion for Self-Signed JWTs with Scopes

- [ ] Merge googleapis/google-cloud-php#4199
- [ ] Tag a new version of `google/cloud-compute`
- [ ] Merge _this PR_
- [ ] Tag a new version of _this library_ (`google/gax`)
- [ ] Update [Gapic Compute client](https://github.com/googleapis/google-cloud-php/tree/master/Compute) requires [the latest tag of google/gax](https://github.com/googleapis/google-cloud-php/blob/master/Compute/composer.json#L8)
  • Loading branch information
bshaffer committed Aug 20, 2021
1 parent 87ee2e2 commit 908e073
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 10 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5",
"google/auth": "^1.2.0",
"google/auth": "^1.17.0",
"google/grpc-gcp": "^0.1.0",
"grpc/grpc": "^1.13",
"google/protobuf": "^3.12.2",
Expand Down
11 changes: 11 additions & 0 deletions src/CredentialsWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use Exception;
use Google\Auth\ApplicationDefaultCredentials;
use Google\Auth\Cache\MemoryCacheItemPool;
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\CredentialsLoader;
use Google\Auth\FetchAuthTokenCache;
use Google\Auth\FetchAuthTokenInterface;
Expand Down Expand Up @@ -98,6 +99,9 @@ public function __construct(FetchAuthTokenInterface $credentialsFetcher, callabl
* @type string[] $defaultScopes
* A string array of default scopes to use when acquiring
* credentials.
* @type bool $useJwtAccessWithScope
* Ensures service account credentials use JWT Access (also known as self-signed
* JWTs), even when user-defined scopes are supplied.
* }
* @return CredentialsWrapper
* @throws ValidationException
Expand All @@ -113,6 +117,7 @@ public static function build(array $args = [])
'authCacheOptions' => [],
'quotaProject' => null,
'defaultScopes' => null,
'useJwtAccessWithScope' => true,
];
$keyFile = $args['keyFile'];
$authHttpHandler = $args['authHttpHandler'] ?: self::buildHttpHandlerFactory();
Expand Down Expand Up @@ -145,6 +150,12 @@ public static function build(array $args = [])
);
}

if ($loader instanceof ServiceAccountCredentials && $args['useJwtAccessWithScope']) {
// Ensures the ServiceAccountCredentials uses JWT Access, also known
// as self-signed JWTs, even when user-defined scopes are supplied.
$loader->useJwtAccessWithScope();
}

if ($args['enableCaching']) {
$authCache = $args['authCache'] ?: new MemoryCacheItemPool();
$loader = new FetchAuthTokenCache(
Expand Down
28 changes: 19 additions & 9 deletions src/GapicClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,22 +163,32 @@ private function buildClientOptions(array $options)
'libVersion' => null,
'apiEndpoint' => null,
];
$defaultOptions['transportConfig'] += [
'grpc' => ['stubOpts' => ['grpc.service_config_disable_resolution' => 1]],
'rest' => [],
'grpc-fallback' => [],
];

$supportedTransports = $this->supportedTransports();
foreach ($supportedTransports as $transportName) {
if (!array_key_exists($transportName, $defaultOptions['transportConfig'])) {
$defaultOptions['transportConfig'][$transportName] = [];
}
}
if (in_array('grpc', $supportedTransports)) {
$defaultOptions['transportConfig']['grpc'] = [
'stubOpts' => ['grpc.service_config_disable_resolution' => 1]
];
}

// Merge defaults into $options starting from top level
// variables, then going into deeper nesting, so that
// we will not encounter missing keys
$options += $defaultOptions;
$options['credentialsConfig'] += $defaultOptions['credentialsConfig'];
$options['transportConfig'] += $defaultOptions['transportConfig'];
$options['transportConfig']['grpc'] += $defaultOptions['transportConfig']['grpc'];
$options['transportConfig']['grpc']['stubOpts'] += $defaultOptions['transportConfig']['grpc']['stubOpts'];
$options['transportConfig']['rest'] += $defaultOptions['transportConfig']['rest'];
$options['transportConfig']['grpc-fallback'] += $defaultOptions['transportConfig']['grpc-fallback'];
if (isset($options['transportConfig']['grpc'])) {
$options['transportConfig']['grpc'] += $defaultOptions['transportConfig']['grpc'];
$options['transportConfig']['grpc']['stubOpts'] += $defaultOptions['transportConfig']['grpc']['stubOpts'];
}
if (isset($options['transportConfig']['rest'])) {
$options['transportConfig']['rest'] += $defaultOptions['transportConfig']['rest'];
}

$this->modifyClientOptions($options);

Expand Down
72 changes: 72 additions & 0 deletions tests/Tests/Unit/GapicClientTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,73 @@ public function buildClientOptionsProvider()
];
}

/**
* @dataProvider buildClientOptionsProviderRestOnly
*/
public function testBuildClientOptionsRestOnly($options, $expectedUpdatedOptions)
{
if (!extension_loaded('sysvshm')) {
$this->markTestSkipped('The sysvshm extension must be installed to execute this test.');
}
$client = new GapicClientTraitRestOnly();
$updatedOptions = $client->call('buildClientOptions', [$options]);
$this->assertEquals($expectedUpdatedOptions, $updatedOptions);
}

public function buildClientOptionsProviderRestOnly()
{
$defaultOptions = [
'apiEndpoint' => 'test.address.com:443',
'serviceName' => 'test.interface.v1.api',
'clientConfig' => __DIR__ . '/testdata/test_service_client_config.json',
'descriptorsConfigPath' => __DIR__.'/testdata/test_service_descriptor_config.php',
'disableRetries' => false,
'transport' => null,
'transportConfig' => [
'rest' => [
'restClientConfigPath' => __DIR__.'/testdata/test_service_rest_client_config.php',
],
'fake-transport' => []
],
'credentials' => null,
'credentialsConfig' => [],
'gapicVersion' => null,
'libName' => null,
'libVersion' => null,
];

$restConfigOptions = $defaultOptions;
$restConfigOptions['transportConfig']['rest'] += [
'customRestConfig' => 'value'
];

$fakeTransportConfigOptions = $defaultOptions;
$fakeTransportConfigOptions['transportConfig']['fake-transport'] += [
'customRestConfig' => 'value'
];
return [
[[], $defaultOptions],
[
[
'transportConfig' => [
'rest' => [
'customRestConfig' => 'value'
]
]
], $restConfigOptions
],
[
[
'transportConfig' => [
'fake-transport' => [
'customRestConfig' => 'value'
]
]
], $fakeTransportConfigOptions
],
];
}

public function testModifyClientOptions()
{
$options = [];
Expand Down Expand Up @@ -1110,6 +1177,11 @@ public static function getClientDefaults()
];
}

public function call($fn, array $args = [])
{
return call_user_func_array([$this, $fn], $args);
}

public function getTransport()
{
return $this->transport;
Expand Down

0 comments on commit 908e073

Please sign in to comment.