Skip to content

Commit ccf7c0a

Browse files
authored
Don't mix env variable with configuration keys (#281)
1 parent 52780a3 commit ccf7c0a

File tree

3 files changed

+71
-43
lines changed

3 files changed

+71
-43
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Change Log
22

3+
## 0.3.2
4+
5+
### Fixed
6+
7+
- `Configuration` don't mix anymore attributes injected by php array and env variables.
8+
39
## 0.3.1
410

511
### Added

src/Configuration.php

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,22 @@ class Configuration
3939
self::OPTION_ROLE_SESSION_NAME => true,
4040
];
4141

42+
// Put fallback options into groups to avoid mixing of provided config and environment variables
4243
private const FALLBACK_OPTIONS = [
43-
self::OPTION_REGION => ['AWS_REGION', 'AWS_DEFAULT_REGION'],
44-
self::OPTION_PROFILE => ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE'],
45-
self::OPTION_ACCESS_KEY_ID => ['AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY'],
46-
self::OPTION_SECRET_ACCESS_KEY => ['AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_KEY'],
47-
self::OPTION_SESSION_TOKEN => 'AWS_SESSION_TOKEN',
48-
self::OPTION_SHARED_CREDENTIALS_FILE => 'AWS_SHARED_CREDENTIALS_FILE',
49-
self::OPTION_SHARED_CONFIG_FILE => 'AWS_CONFIG_FILE',
50-
self::OPTION_ROLE_ARN => 'AWS_ROLE_ARN',
51-
self::OPTION_WEB_IDENTITY_TOKEN_FILE => 'AWS_WEB_IDENTITY_TOKEN_FILE',
52-
self::OPTION_ROLE_SESSION_NAME => 'AWS_ROLE_SESSION_NAME',
44+
[self::OPTION_REGION => ['AWS_REGION', 'AWS_DEFAULT_REGION']],
45+
[self::OPTION_PROFILE => ['AWS_PROFILE', 'AWS_DEFAULT_PROFILE']],
46+
[
47+
self::OPTION_ACCESS_KEY_ID => ['AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY'],
48+
self::OPTION_SECRET_ACCESS_KEY => ['AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_KEY'],
49+
self::OPTION_SESSION_TOKEN => 'AWS_SESSION_TOKEN',
50+
],
51+
[self::OPTION_SHARED_CREDENTIALS_FILE => 'AWS_SHARED_CREDENTIALS_FILE'],
52+
[self::OPTION_SHARED_CONFIG_FILE => 'AWS_CONFIG_FILE'],
53+
[
54+
self::OPTION_ROLE_ARN => 'AWS_ROLE_ARN',
55+
self::OPTION_WEB_IDENTITY_TOKEN_FILE => 'AWS_WEB_IDENTITY_TOKEN_FILE',
56+
self::OPTION_ROLE_SESSION_NAME => 'AWS_ROLE_SESSION_NAME',
57+
],
5358
];
5459

5560
private const DEFAULT_OPTIONS = [
@@ -69,26 +74,32 @@ public static function create(array $options)
6974
throw new InvalidArgument(\sprintf('Invalid option(s) "%s" passed to "%s::%s". ', \implode('", "', \array_keys($invalidOptions)), __CLASS__, __METHOD__));
7075
}
7176

72-
foreach (self::FALLBACK_OPTIONS as $option => $envVariableNames) {
73-
if (isset($options[$option])) {
74-
continue;
77+
foreach (self::FALLBACK_OPTIONS as $fallbackGroup) {
78+
// prevent mixing env variables with config keys
79+
foreach ($fallbackGroup as $option => $envVariableNames) {
80+
if (isset($options[$option])) {
81+
continue 2;
82+
}
7583
}
7684

77-
foreach ((array) $envVariableNames as $envVariableName) {
78-
if (false !== $value = \getenv($envVariableName)) {
79-
$options[$option] = $value;
85+
foreach ($fallbackGroup as $option => $envVariableNames) {
86+
$envVariableNames = (array) $envVariableNames;
87+
foreach ($envVariableNames as $envVariableName) {
88+
if (false !== $value = \getenv($envVariableName)) {
89+
$options[$option] = $value;
8090

81-
break;
91+
break;
92+
}
8293
}
8394
}
8495
}
8596

86-
foreach (self::DEFAULT_OPTIONS as $option => $defaultValue) {
87-
if (isset($options[$option])) {
97+
foreach (self::DEFAULT_OPTIONS as $optionTrigger => $defaultValue) {
98+
if (isset($options[$optionTrigger])) {
8899
continue;
89100
}
90101

91-
$options[$option] = $defaultValue;
102+
$options[$optionTrigger] = $defaultValue;
92103
}
93104

94105
$configuration = new Configuration();

tests/Unit/ConfigurationTest.php

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,41 @@
99

1010
class ConfigurationTest extends TestCase
1111
{
12-
public function testDefaultValues()
12+
/**
13+
* @dataProvider provideConfiguration
14+
*/
15+
public function testCreate($config, $env, $expected)
1316
{
14-
$config = Configuration::create(['endpoint' => 'foo']);
15-
self::assertEquals('foo', $config->get('endpoint'));
16-
17-
$config = Configuration::create(['endpoint' => '']);
18-
self::assertEquals('', $config->get('endpoint'));
19-
20-
$config = Configuration::create([]);
21-
self::assertEquals('https://%service%.%region%.amazonaws.com', $config->get('endpoint'));
22-
23-
// If a configuration value is set to null, we should use default value.
24-
$config = Configuration::create(['endpoint' => null]);
25-
self::assertEquals('https://%service%.%region%.amazonaws.com', $config->get('endpoint'));
26-
27-
$config = Configuration::create([]);
28-
self::assertEquals('default', $config->get('profile'));
29-
30-
putenv('AWS_PROFILE=foo');
31-
$config = Configuration::create([]);
32-
self::assertEquals('foo', $config->get('profile'));
17+
foreach ($env as $key => $value) {
18+
putenv("$key=$value");
19+
}
20+
21+
try {
22+
$config = Configuration::create($config);
23+
foreach ($expected as $key => $value) {
24+
self::assertEquals($value, $config->get($key));
25+
}
26+
} finally {
27+
foreach ($env as $key => $value) {
28+
putenv($key);
29+
}
30+
}
31+
}
3332

34-
putenv('AWS_PROFILE');
35-
$config = Configuration::create([]);
36-
self::assertEquals('default', $config->get('profile'));
33+
public function provideConfiguration(): iterable
34+
{
35+
yield 'simple config' => [['endpoint' => 'foo'], [], ['endpoint' => 'foo']];
36+
yield 'empty config' => [['endpoint' => ''], [], ['endpoint' => '']];
37+
yield 'default' => [[], [], ['endpoint' => 'https://%service%.%region%.amazonaws.com']];
38+
yield 'default when null' => [['endpoint' => null], [], ['endpoint' => 'https://%service%.%region%.amazonaws.com']];
39+
40+
yield 'default when env missing' => [[], [], ['profile' => 'default']];
41+
yield 'fallback env' => [[], ['AWS_PROFILE' => 'foo'], ['profile' => 'foo']];
42+
yield 'config priority on env' => [['profile' => 'bar'], ['AWS_PROFILE' => 'foo'], ['profile' => 'bar']];
43+
44+
yield 'config with env group' => [['accessKeyId' => 'key'], [], ['accessKeyId' => 'key', 'sessionToken' => null]];
45+
yield 'config with env group 2' => [['accessKeySecret' => 'secret'], [], ['accessKeySecret' => 'secret', 'accessKeyId' => null, 'sessionToken' => null]];
46+
yield 'mix config and env' => [['accessKeyId' => 'key'], ['AWS_SESSION_TOKEN' => 'token'], ['accessKeyId' => 'key', 'sessionToken' => null]];
47+
yield 'null config with env group' => [['accessKeyId' => null], ['AWS_SESSION_TOKEN' => 'token'], ['accessKeyId' => null, 'sessionToken' => 'token']];
3748
}
3849
}

0 commit comments

Comments
 (0)