Skip to content
This repository has been archived by the owner on Aug 7, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from php-istio/bug/array-prototype-config-alway…
Browse files Browse the repository at this point in the history
…s-add-empty-array

Fix bug array prototype config always add empty array.
  • Loading branch information
vuongxuongminh authored Jun 29, 2021
2 parents aac07ae + c7fbed5 commit 06f3d00
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 85 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.0.2

* Fix: add child node `rules` array config to avoid empty array when using arrayPrototype.

## 1.0.1

* Fix: auto add authenticator when not config.
93 changes: 50 additions & 43 deletions src/DependencyInjection/Security/AuthenticatorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function createAuthenticator(
) {
$authenticator = sprintf('security.authenticator.istio_jwt_authenticator.%s', $firewallName);
$definition = new ChildDefinition('istio.jwt_authentication.authenticator');
$definition->replaceArgument(0, $this->createUserIdentifierClaimMappings($container, $authenticator, $config));
$definition->replaceArgument(0, $this->createUserIdentifierClaimMappings($container, $authenticator, $config['rules']));
$definition->replaceArgument(1, new Reference($userProviderId));
$container->setDefinition($authenticator, $definition);

Expand Down Expand Up @@ -61,33 +61,40 @@ public function getKey()
public function addConfiguration(NodeDefinition $builder)
{
$builder
->fixXmlConfig('origin_token_header')
->fixXmlConfig('origin_token_query_param')
->fixXmlConfig('base64_header')
->arrayPrototype()
->addDefaultsIfNotSet()
->children()
->scalarNode('issuer')
->cannotBeEmpty()
->isRequired()
->end()
->scalarNode('user_identifier_claim')
->cannotBeEmpty()
->defaultValue('sub')
->end()
->arrayNode('origin_token_headers')
->scalarPrototype()
->cannotBeEmpty()
->end()
->end()
->arrayNode('origin_token_query_params')
->scalarPrototype()
->cannotBeEmpty()
->end()
->end()
->arrayNode('base64_headers')
->scalarPrototype()
->cannotBeEmpty()
->fixXmlConfig('rule')
->children()
->arrayNode('rules')
->isRequired()
->cannotBeEmpty()
->arrayPrototype()
->fixXmlConfig('origin_token_header')
->fixXmlConfig('origin_token_query_param')
->fixXmlConfig('base64_header')
->addDefaultsIfNotSet()
->children()
->scalarNode('issuer')
->isRequired()
->cannotBeEmpty()
->end()
->scalarNode('user_identifier_claim')
->cannotBeEmpty()
->defaultValue('sub')
->end()
->arrayNode('origin_token_headers')
->scalarPrototype()
->cannotBeEmpty()
->end()
->end()
->arrayNode('origin_token_query_params')
->scalarPrototype()
->cannotBeEmpty()
->end()
->end()
->arrayNode('base64_headers')
->scalarPrototype()
->cannotBeEmpty()
->end()
->end()
->end()
->end()
->end()
Expand All @@ -97,53 +104,53 @@ public function addConfiguration(NodeDefinition $builder)

private function createUserIdentifierClaimMappings(
ContainerBuilder $container,
string $authenticatorName,
array $config,
string $authenticatorId,
array $rules,
): IteratorArgument {
$extractorIdPrefix = sprintf('%s.payload_extractor', $authenticatorName);
$extractorIdPrefix = sprintf('%s.payload_extractor', $authenticatorId);
$mappings = [];

foreach ($config as $key => $item) {
foreach ($rules as $key => $rule) {
$extractor = null;

if (!empty($item['origin_token_headers'])) {
if (!empty($rule['origin_token_headers'])) {
$extractor = $this->createPayloadExtractor(
$container,
sprintf('%s.origin_token_headers.%s', $extractorIdPrefix, $key),
'istio.jwt_authentication.payload_extractor.origin_token.header',
$item['issuer'],
$item['origin_token_headers']
$rule['issuer'],
$rule['origin_token_headers']
);
}

if (!empty($item['origin_token_query_params'])) {
if (!empty($rule['origin_token_query_params'])) {
$extractor = $this->createPayloadExtractor(
$container,
sprintf('%s.origin_token_query_params.%s', $extractorIdPrefix, $key),
'istio.jwt_authentication.payload_extractor.origin_token.query_param',
$item['issuer'],
$item['origin_token_query_params']
$rule['issuer'],
$rule['origin_token_query_params']
);
}

if (!empty($item['base64_headers'])) {
if (!empty($rule['base64_headers'])) {
$extractor = $this->createPayloadExtractor(
$container,
sprintf('%s.base64_headers.%s', $extractorIdPrefix, $key),
'istio.jwt_authentication.payload_extractor.base64_header',
$item['issuer'],
$item['base64_headers']
$rule['issuer'],
$rule['base64_headers']
);
}

if (null === $extractor) {
throw new InvalidConfigurationException(sprintf('`%s`: at least once `origin_token_headers`, `origin_token_query_params`, `base64_headers` should be config when using', $this->getKey()));
}

$mappingId = sprintf('%s.user_identifier_claim_mapping.%s', $authenticatorName, $key);
$mappingId = sprintf('%s.user_identifier_claim_mapping.%s', $authenticatorId, $key);
$mappings[] = new Reference($mappingId);
$mappingDefinition = new Definition(UserIdentifierClaimMapping::class);
$mappingDefinition->setArgument(0, $item['user_identifier_claim']);
$mappingDefinition->setArgument(0, $rule['user_identifier_claim']);
$mappingDefinition->setArgument(1, $extractor);
$container->setDefinition($mappingId, $mappingDefinition);
}
Expand Down
38 changes: 25 additions & 13 deletions tests/TestKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,29 +68,41 @@ function (ContainerBuilder $container) {
'provider' => 'istio',
'stateless' => true,
'istio_jwt_authenticator' => [
[
'issuer' => 'issuer_1',
'user_identifier_claim' => 'id_1',
'origin_token_query_params' => ['token'],
],
[
'issuer' => 'issuer_2',
'user_identifier_claim' => 'id_2',
'base64_headers' => ['x-istio-jwt-payload'],
'rules' => [
[
'issuer' => 'issuer_1',
'user_identifier_claim' => 'id_1',
'origin_token_query_params' => ['token'],
],
[
'issuer' => 'issuer_2',
'user_identifier_claim' => 'id_2',
'base64_headers' => ['x-istio-jwt-payload'],
],
],
],
],
'test2' => [
'provider' => 'memory',
'stateless' => true,
'istio_jwt_authenticator' => [
[
'issuer' => 'issuer_2',
'user_identifier_claim' => 'id_2',
'origin_token_headers' => ['authorization'],
'rules' => [
[
'issuer' => 'issuer_2',
'user_identifier_claim' => 'id_2',
'origin_token_headers' => ['authorization'],
],
],
],
],
// Test not affect another authenticator
'test3' => [
'provider' => 'istio',
'stateless' => true,
'http_basic' => [
'realm' => 'Test',
],
],
],
'providers' => [
'istio' => [
Expand Down
122 changes: 93 additions & 29 deletions tests/Unit/DepdendencyInjection/Security/AuthenticatorFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ public function testExceptionWhenCallCreate()
public function testCreateAuthenticator()
{
$config = [
['issuer' => 'test', 'origin_token_headers' => ['authorization'], 'user_identifier_claim' => 'sub'],
['issuer' => 'test2', 'origin_token_query_params' => ['token'], 'user_identifier_claim' => 'sub'],
'rules' => [
['issuer' => 'test', 'origin_token_headers' => ['authorization'], 'user_identifier_claim' => 'sub'],
['issuer' => 'test2', 'origin_token_query_params' => ['token'], 'user_identifier_claim' => 'sub'],
],
];

$this->executeCreate($config);
Expand All @@ -84,7 +86,7 @@ public function testCreateAuthenticator()
public function testThrowExceptionWhenCreateAuthenticatorWithNoneExtractor()
{
$this->expectException(InvalidConfigurationException::class);
$this->executeCreate([['issuer' => 'test']]);
$this->executeCreate(['rules' => ['issuer' => 'test']]);
}

private function executeCreate(array $config)
Expand All @@ -98,37 +100,69 @@ public function validConfigurations(): array
return [
[
[
[
'issuer' => 'example',
'rules' => [
[
'issuer' => 'example',
],
],
],
[
[
'issuer' => 'example',
'user_identifier_claim' => 'sub',
'origin_token_headers' => [],
'origin_token_query_params' => [],
'base64_headers' => [],
'rules' => [
[
'issuer' => 'example',
'user_identifier_claim' => 'sub',
'origin_token_headers' => [],
'origin_token_query_params' => [],
'base64_headers' => [],
],
],
],
],
[
[
[
'issuer' => 'example',
'user_identifier_claim' => 'id',
'origin_token_headers' => ['authorization'],
'origin_token_query_params' => ['token'],
'base64_headers' => ['x-istio-jwt-payload'],
'rules' => [
[
'issuer' => 'example',
'user_identifier_claim' => 'id',
'origin_token_headers' => ['authorization'],
'origin_token_query_params' => ['token'],
'base64_headers' => ['x-istio-jwt-payload'],
],
],
],
[
[
'issuer' => 'example',
'user_identifier_claim' => 'id',
'origin_token_headers' => ['authorization'],
'origin_token_query_params' => ['token'],
'base64_headers' => ['x-istio-jwt-payload'],
'rules' => [
[
'issuer' => 'example',
'user_identifier_claim' => 'id',
'origin_token_headers' => ['authorization'],
'origin_token_query_params' => ['token'],
'base64_headers' => ['x-istio-jwt-payload'],
],
],
],
],
[
[
'rules' => [
[
'issuer' => 'example',
'user_identifier_claim' => 'id',
'origin_token_header' => ['authorization'],
'origin_token_query_param' => ['token'],
'base64_header' => ['x-istio-jwt-payload'],
],
],
],
[
'rules' => [
[
'issuer' => 'example',
'user_identifier_claim' => 'id',
'origin_token_headers' => ['authorization'],
'origin_token_query_params' => ['token'],
'base64_headers' => ['x-istio-jwt-payload'],
],
],
],
],
Expand All @@ -138,34 +172,64 @@ public function validConfigurations(): array
public function invalidConfigurations(): array
{
return [
[
[],
],
[
[
['issuer' => ''],
'rules' => [],
],
],
[
[
['issuer' => 'example', 'user_identifier_claim' => ''],
'rules' => [[]],
],
],
[
[
['issuer' => '', 'user_identifier_claim' => 'id'],
'rules' => ['issuer' => ''],
],
],
[
[
['issuer' => 'example', 'origin_token_headers' => ['']],
'rules' => [
['issuer' => ''],
],
],
],
[
[
['issuer' => 'example', 'origin_token_query_params' => ['']],
'rules' => [
['issuer' => 'example', 'user_identifier_claim' => ''],
],
],
],
[
[
['issuer' => 'example', 'base64_headers' => ['']],
'rules' => [
['issuer' => '', 'user_identifier_claim' => 'id'],
],
],
],
[
[
'rules' => [
['issuer' => 'example', 'origin_token_headers' => ['']],
],
],
],
[
[
'rules' => [
['issuer' => 'example', 'origin_token_query_params' => ['']],
],
],
],
[
[
'rules' => [
['issuer' => 'example', 'base64_headers' => ['']],
],
],
],
];
Expand Down

0 comments on commit 06f3d00

Please sign in to comment.