diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be563a1..cf32efc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,8 @@ jobs: strategy: matrix: operating-system: [ubuntu-latest] - php-versions: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4'] + php-versions: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + fail-fast: false name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} steps: @@ -38,7 +39,18 @@ jobs: run: composer install --prefer-dist --no-progress --no-suggest - name: Run test case - run: composer test + run: composer test4LowVersion + if: ${{ matrix.php-versions }} < '7.2' + env: + ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }} + ACCESS_KEY_SECRET: ${{ secrets.ACCESS_KEY_SECRET }} + ROLE_ARN: ${{ secrets.ROLE_ARN }} + PUBLIC_KEY_ID: ${{ secrets.PUBLIC_KEY_ID }} + PRIVATE_KEY_LINE_1: ${{ secrets.PRIVATE_KEY_LINE_1 }} + + - name: Run test case + run: composer test4HighVersion + if: ${{ matrix.php-versions }} >= '7.2' env: ACCESS_KEY_ID: ${{ secrets.ACCESS_KEY_ID }} ACCESS_KEY_SECRET: ${{ secrets.ACCESS_KEY_SECRET }} diff --git a/README-zh-CN.md b/README-zh-CN.md index ad127c4..bd2a695 100644 --- a/README-zh-CN.md +++ b/README-zh-CN.md @@ -113,12 +113,15 @@ $ramRoleArn->getPolicy(); use AlibabaCloud\Credentials\Credential; -$ecsRamRole = new Credential([ - 'type' => 'ecs_ram_role', - 'role_name' => '', +$config = new Credential\Config([ + 'type' => 'ecs_ram_role', + 'roleName' => '', + 'enableIMDSv2' => true, ]); +$ecsRamRole = new Credential($config); $ecsRamRole->getRoleName(); -// Note: `role_name` is optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. +// Note: `roleName` is optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. +// Note: `enableIMDSv2` is optional and is recommended to be turned on. It can be replaced by setting environment variable: ALIBABA_CLOUD_ECS_IMDSV2_ENABLE ``` #### RsaKeyPair diff --git a/README.md b/README.md index 86939cd..bcb4bb0 100644 --- a/README.md +++ b/README.md @@ -113,12 +113,15 @@ By specifying the role name, the credential will be able to automatically reques use AlibabaCloud\Credentials\Credential; -$ecsRamRole = new Credential([ - 'type' => 'ecs_ram_role', - 'role_name' => '', +$config = new Credential\Config([ + 'type' => 'ecs_ram_role', + 'roleName' => '', + 'enableIMDSv2' => true, ]); +$ecsRamRole = new Credential($config); $ecsRamRole->getRoleName(); -// Note: `role_name` is optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. +// Note: `roleName` is optional. It will be retrieved automatically if not set. It is highly recommended to set it up to reduce requests. +// Note: `enableIMDSv2` is optional and is recommended to be turned on. It can be replaced by setting environment variable: ALIBABA_CLOUD_ECS_IMDSV2_ENABLE ``` #### RsaKeyPair diff --git a/composer.json b/composer.json index 513e8a1..c6b3d8c 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ "ext-sockets": "*", "drupal/coder": "^8.3", "symfony/dotenv": "^3.4", - "phpunit/phpunit": "^5.7|^6.6|^7.5", + "phpunit/phpunit": "^5.7|^6.6|^7.5|^9.5", "monolog/monolog": "^1.24", "composer/composer": "^1.8", "mikey179/vfsstream": "^1.6", @@ -93,6 +93,12 @@ "test": [ "phpunit --colors=always" ], + "test4HighVersion": [ + "phpunit -c phpunit.xml.72 --colors=always" + ], + "test4LowVersion": [ + "phpunit -c phpunit.xml.56 --colors=always" + ], "unit": [ "@clearCache", "phpunit --testsuite=Unit --colors=always" diff --git a/phpunit.xml b/phpunit.xml.56 similarity index 52% rename from phpunit.xml rename to phpunit.xml.56 index 6b14449..83c506f 100755 --- a/phpunit.xml +++ b/phpunit.xml.56 @@ -13,14 +13,14 @@ - tests + tests/LowerthanVersion7_2 - ./tests/Unit + ./tests/LowerthanVersion7_2/Unit - ./tests/Feature + ./tests/LowerthanVersion7_2/Feature @@ -34,21 +34,4 @@ - - - - ./src - - ./src/Profile/DefaultProfile.php - ./src/DefaultAcsClient.php - ./src/Release.php - ./src/SDK.php - ./src/Functions.php - ./src/Constants/Business.php - ./src/Constants/ErrorCode.php - ./src/Signature/Signature.php - ./src/Credentials/CredentialsInterface.php - - - diff --git a/phpunit.xml.72 b/phpunit.xml.72 new file mode 100755 index 0000000..31c52ad --- /dev/null +++ b/phpunit.xml.72 @@ -0,0 +1,37 @@ + + + + + + tests/HigherthanorEqualtoVersion7_2 + + + ./tests/HigherthanorEqualtoVersion7_2/Unit + + + + ./tests/HigherthanorEqualtoVersion7_2/Feature + + + + + + integration + + + + + + + + diff --git a/src/EcsRamRoleCredential.php b/src/EcsRamRoleCredential.php index fb19c26..508dec8 100644 --- a/src/EcsRamRoleCredential.php +++ b/src/EcsRamRoleCredential.php @@ -37,15 +37,15 @@ class EcsRamRoleCredential implements CredentialsInterface * * @param $role_name */ - public function __construct($role_name = null, $enable_IMDS_v2 = false, $metadata_token_duration = 21600 ) + public function __construct($role_name = null, $enable_imdsv2 = false, $metadata_token_duration = 21600 ) { Filter::roleName($role_name); $this->roleName = $role_name; - Filter::enableIMDSv2($enable_IMDS_v2); + Filter::enableIMDSv2($enable_imdsv2); - $this->enableIMDSv2 = $enable_IMDS_v2; + $this->enableIMDSv2 = $enable_imdsv2; Filter::metadataTokenDuration($metadata_token_duration); @@ -102,6 +102,16 @@ public function getRoleNameFromMeta() return $role_name; } + /** + * @return bool + * @throws GuzzleException + * @throws Exception + */ + public function isEnableIMDSv2() + { + return $this->enableIMDSv2; + } + /** * @return string */ diff --git a/src/Filter.php b/src/Filter.php index 215695d..0b1b2d2 100644 --- a/src/Filter.php +++ b/src/Filter.php @@ -102,10 +102,10 @@ public static function roleName($role_name) /** * @param boolean|null $enable_IMDS_v2 */ - public static function enableIMDSv2($enable_IMDS_v2) + public static function enableIMDSv2($enable_imds_v2) { - if (!is_bool($enable_IMDS_v2)) { - throw new InvalidArgumentException('enable_IMDS_v2 must be a string'); + if (!is_bool($enable_imds_v2)) { + throw new InvalidArgumentException('enable_imds_v2 must be a string'); } } diff --git a/tests/HigherthanorEqualtoVersion7_2/Feature/CredentialTest.php b/tests/HigherthanorEqualtoVersion7_2/Feature/CredentialTest.php new file mode 100644 index 0000000..9641abe --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Feature/CredentialTest.php @@ -0,0 +1,148 @@ + 'access_key', + 'accessKeyId' => 'foo', + 'accessKeySecret' => 'bar', + ]); + $credential = new Credential($config); + + // Assert + $this->assertEquals('foo', $credential->getAccessKeyId()); + $this->assertEquals('bar', $credential->getAccessKeySecret()); + $this->assertEquals('access_key', $credential->getType()); + } + + /** + * @throws GuzzleException + * @throws ReflectionException + * @expectedException \GuzzleHttp\Exception\ConnectException + * @expectedExceptionMessageRegExp /timed/ + */ + public function testEcsRamRoleCredential() + { + $config = new Credential\Config([ + 'type' => 'ecs_ram_role', + 'roleName' => 'foo', + 'enableIMDSv2' => true, + ]); + $credential = new Credential($config); + + // Assert + $this->assertEquals('foo', $credential->getRoleName()); + $this->assertEquals('ecs_ram_role', $credential->getType()); + $this->assertTrue($credential->isEnableIMDSv2()); + $credential->getAccessKeySecret(); + } + + /** + * @throws GuzzleException + * @throws ReflectionException + */ + public function testRamRoleArnCredential() + { + Credentials::cancelMock(); + $config = new Credential\Config([ + 'type' => 'ram_role_arn', + 'accessKeyId' => Helper::envNotEmpty('ACCESS_KEY_ID'), + 'accessKeySecret' => Helper::envNotEmpty('ACCESS_KEY_SECRET'), + 'roleArn' => Helper::envNotEmpty('ROLE_ARN'), + 'roleSessionName' => 'role_session_name', + 'policy' => '', + ]); + + $credential = new Credential($config); + + // Assert + $this->assertTrue(null !== $credential->getAccessKeyId()); + $this->assertTrue(null !== $credential->getAccessKeySecret()); + $this->assertEquals('ram_role_arn', $credential->getType()); + } + + /** + * @throws GuzzleException + * @throws ReflectionException + * @expectedException \RuntimeException + * @expectedExceptionMessage Specified access key type is not match with signature type. + */ + public function testRsaKeyPairCredential() + { + Credentials::cancelMock(); + $publicKeyId = Helper::envNotEmpty('PUBLIC_KEY_ID'); + $privateKeyFile = VirtualRsaKeyPairCredential::privateKeyFileUrl(); + $config = new Credential\Config([ + 'type' => 'rsa_key_pair', + 'publicKeyId' => $publicKeyId, + 'privateKeyFile' => $privateKeyFile, + ]); + $credential = new Credential($config); + + // Assert + $this->assertTrue(null !== $credential->getAccessKeyId()); + $this->assertTrue(null !== $credential->getAccessKeySecret()); + $this->assertEquals('rsa_key_pair', $credential->getType()); + $credential->getAccessKeySecret(); + } + + /** + * @throws GuzzleException + * @throws ReflectionException + */ + public function testSTS() + { + $config = new Credential\Config([ + 'type' => 'sts', + 'accessKeyId' => 'foo', + 'accessKeySecret' => 'bar', + 'securityToken' => 'token', + ]); + $credential = new Credential($config); + + // Assert + $this->assertEquals('foo', $credential->getAccessKeyId()); + $this->assertEquals('bar', $credential->getAccessKeySecret()); + $this->assertEquals('token', $credential->getSecurityToken()); + $this->assertEquals('sts', $credential->getType()); + } + + /** + * @throws GuzzleException + * @throws ReflectionException + */ + public function testBearerToken() + { + $config = new Credential\Config([ + 'type' => 'bearer', + 'bearerToken' => 'token', + ]); + $credential = new Credential($config); + + // Assert + $this->assertEquals('token', $credential->getBearerToken()); + $this->assertEquals('bearer', $credential->getType()); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/AccessKeyCredentialTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/AccessKeyCredentialTest.php new file mode 100644 index 0000000..7036bc3 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/AccessKeyCredentialTest.php @@ -0,0 +1,85 @@ +assertEquals($accessKeyId, $credential->getAccessKeyId()); + $this->assertEquals($accessKeySecret, $credential->getAccessKeySecret()); + $this->assertInstanceOf(ShaHmac1Signature::class, $credential->getSignature()); + $this->assertEquals("$accessKeyId#$accessKeySecret", (string)$credential); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_id cannot be empty + */ + public function testAccessKeyIdEmpty() + { + // Setup + $accessKeyId = ''; + $accessKeySecret = 'bar'; + + new AccessKeyCredential($accessKeyId, $accessKeySecret); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_id must be a string + */ + public function testAccessKeyIdFormat() + { + // Setup + $accessKeyId = null; + $accessKeySecret = 'bar'; + + new AccessKeyCredential($accessKeyId, $accessKeySecret); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_secret cannot be empty + */ + public function testAccessKeySecretEmpty() + { + // Setup + $accessKeyId = 'foo'; + $accessKeySecret = ''; + + // Test + new AccessKeyCredential($accessKeyId, $accessKeySecret); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_secret must be a string + */ + public function testAccessKeySecretFormat() + { + // Setup + $accessKeyId = 'foo'; + $accessKeySecret = null; + + // Test + new AccessKeyCredential($accessKeyId, $accessKeySecret); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/BearerTokenCredentialTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/BearerTokenCredentialTest.php new file mode 100644 index 0000000..8d97d49 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/BearerTokenCredentialTest.php @@ -0,0 +1,58 @@ +assertEquals($bearerToken, $credential->getBearerToken()); + $this->assertEquals($expected, (string)$credential); + $this->assertInstanceOf(BearerTokenSignature::class, $credential->getSignature()); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/ChainProviderTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/ChainProviderTest.php new file mode 100644 index 0000000..0c144f3 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/ChainProviderTest.php @@ -0,0 +1,136 @@ +getMessage()); + } + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Credentials file is not readable: /a/c + */ + public function testSetIniWithDIYFile() + { + putenv('ALIBABA_CLOUD_CREDENTIALS_FILE=/a/c'); + ChainProvider::set( + ChainProvider::ini() + ); + self::assertTrue(ChainProvider::hasCustomChain()); + ChainProvider::customProvider(ChainProvider::getDefaultName()); + } + + public function testInOpenBaseDir() + { + if (!Helper::isWindows()) { + $dirs = 'vfs://AlibabaCloud:/home:/Users:/private:/a/b:/d'; + } else { + $dirs = 'C:\\projects;C:\\Users'; + } + + putenv('ALIBABA_CLOUD_CREDENTIALS_FILE=/a/c'); + ini_set('open_basedir', $dirs); + self::assertEquals($dirs, ini_get('open_basedir')); + ChainProvider::set( + ChainProvider::ini() + ); + self::assertTrue(ChainProvider::hasCustomChain()); + ChainProvider::customProvider(ChainProvider::getDefaultName()); + } + + public function testDefaultProvider() + { + ChainProvider::defaultProvider(ChainProvider::getDefaultName()); + } + + public function testSetEnv() + { + ChainProvider::set( + ChainProvider::env() + ); + self::assertTrue(ChainProvider::hasCustomChain()); + } + + public function testSetInstance() + { + putenv('ALIBABA_CLOUD_ECS_METADATA=role_arn'); + ChainProvider::set( + ChainProvider::instance() + ); + self::assertTrue(ChainProvider::hasCustomChain()); + ChainProvider::customProvider(ChainProvider::getDefaultName()); + } + + public function testDefaultFile() + { + self::assertStringEndsWith( + 'credentials', + ChainProvider::getDefaultFile() + ); + putenv('ALIBABA_CLOUD_PROFILE=default'); + } + + public function testDefaultName() + { + putenv('ALIBABA_CLOUD_PROFILE=default1'); + self::assertEquals( + 'default1', + ChainProvider::getDefaultName() + ); + + putenv('ALIBABA_CLOUD_PROFILE=null'); + self::assertEquals( + 'default', + ChainProvider::getDefaultName() + ); + } + + protected function setUp(): void + { + parent::setUp(); + putenv('ALIBABA_CLOUD_ACCESS_KEY_ID=foo'); + putenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET=bar'); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/CredentialTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/CredentialTest.php new file mode 100644 index 0000000..f55a46d --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/CredentialTest.php @@ -0,0 +1,304 @@ +getMessage(), "Credential 'default' not found"); + } + } + + /** + * @dataProvider exceptionCases + * + * @param array $config + * @param string $message + */ + public function testException(array $config, $message) + { + try { + new Credential($config); + } catch (Exception $e) { + self::assertEquals($message, $e->getMessage()); + } + } + + /** + * @return array + */ + public function exceptionCases() + { + return [ + + [ + [ + 'access_key_id' => 'access_key_id', + ], + 'Missing required type option', + ], + + [ + [ + 'type' => 'none', + ], + 'Invalid type option, support: access_key, sts, ecs_ram_role, ram_role_arn, rsa_key_pair, bearer', + ], + + [ + [ + 'type' => 'access_key', + ], + 'Missing required access_key_id option in config for access_key', + ], + + [ + [ + 'type' => 'access_key', + 'access_key_id' => 'foo', + ], + 'Missing required access_key_secret option in config for access_key', + ], + + [ + [ + 'type' => 'access_key', + 'access_key_id' => '', + 'access_key_secret' => 'bar', + ], + 'access_key_id cannot be empty', + ], + + [ + [ + 'type' => 'access_key', + 'access_key_id' => 'foo', + 'access_key_secret' => '', + ], + 'access_key_secret cannot be empty', + ], + + [ + [ + 'type' => 'sts', + ], + 'Missing required access_key_id option in config for sts', + ], + + [ + [ + 'type' => 'sts', + 'access_key_id' => 'foo', + ], + 'Missing required access_key_secret option in config for sts', + ], + + [ + [ + 'type' => 'sts', + 'access_key_id' => 'foo', + 'access_key_secret' => 'bar', + ], + 'Missing required expiration option in config for sts', + ], + + [ + [ + 'type' => 'sts', + 'access_key_id' => '', + 'access_key_secret' => 'bar', + 'expiration' => 3600, + ], + 'access_key_id cannot be empty', + ], + + [ + [ + 'type' => 'sts', + 'access_key_id' => 'foo', + 'access_key_secret' => '', + 'expiration' => 3600, + ], + 'access_key_secret cannot be empty', + ], + + [ + [ + 'type' => 'sts', + 'access_key_id' => 'foo', + 'access_key_secret' => 'bar', + 'expiration' => 'string', + ], + 'expiration must be a int', + ], + + [ + [ + 'type' => 'ecs_ram_role', + ], + 'Missing required role_name option in config for ecs_ram_role', + ], + + [ + [ + 'type' => 'ecs_ram_role', + 'role_name' => '', + ], + 'role_name cannot be empty', + ], + + [ + [ + 'type' => 'ecs_ram_role', + 'role_name' => 123456, + ], + 'role_name must be a string', + ], + + [ + [ + 'type' => 'ecs_ram_role', + 'role_name' => 'test', + 'enableIMDSv2' => 'false', + ], + 'enable_imds_v2 must be a string', + ], + + [ + [ + 'type' => 'ecs_ram_role', + 'role_name' => 'test', + 'enableIMDSv2' => false, + 'metadataTokenDuration' => 3600, + ], + 'metadata_token_duration must be a int', + ], + + [ + [ + 'type' => 'ram_role_arn', + ], + 'Missing required access_key_id option in config for ram_role_arn', + ], + + [ + [ + 'type' => 'ram_role_arn', + 'access_key_id' => 'foo', + ], + 'Missing required access_key_secret option in config for ram_role_arn', + ], + + [ + [ + 'type' => 'ram_role_arn', + 'access_key_id' => 'foo', + 'access_key_secret' => 'bar', + ], + 'Missing required role_arn option in config for ram_role_arn', + ], + + [ + [ + 'type' => 'ram_role_arn', + 'access_key_id' => 'foo', + 'access_key_secret' => 'bar', + 'role_arn' => 'role_arn', + ], + 'Missing required role_session_name option in config for ram_role_arn', + ], + + [ + [ + 'type' => 'rsa_key_pair', + ], + 'Missing required public_key_id option in config for rsa_key_pair', + ], + + [ + [ + 'type' => 'rsa_key_pair', + 'public_key_id' => 'public_key_id', + ], + 'Missing required private_key_file option in config for rsa_key_pair', + ], + + [ + [ + 'type' => 'rsa_key_pair', + 'public_key_id' => 'public_key_id', + 'private_key_file' => '', + ], + 'private_key_file cannot be empty', + ], + + [ + [ + 'type' => 'rsa_key_pair', + 'public_key_id' => 'public_key_id', + 'private_key_file' => 'invalid_path', + ], + 'file_get_contents(invalid_path): failed to open stream: No such file or directory', + ], + + ]; + } + + /** + * @throws ReflectionException + * @throws Exception + */ + public function testRamRoleArnCredential() + { + $config = [ + 'type' => 'ram_role_arn', + 'access_key_id' => 'foo', + 'access_key_secret' => 'bar', + 'role_arn' => 'role_arn', + 'role_session_name' => 'role_session_name', + 'timeout' => 1, + ]; + $credential = new Credential($config); + + self::assertEquals('foo', $credential->getOriginalAccessKeyId()); + self::assertEquals('bar', $credential->getOriginalAccessKeySecret()); + self::assertEquals($config, $credential->getConfig()); + self::assertInstanceOf(RamRoleArnCredential::class, $credential->getCredential()); + } + + /** + * @throws ReflectionException + * @throws Exception + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function testAccessKey() + { + $config = [ + 'type' => 'access_key', + 'access_key_id' => 'foo', + 'access_key_secret' => 'bar', + ]; + $credential = new Credential($config); + + self::assertEquals('foo', $credential->getAccessKeyId()); + self::assertEquals('bar', $credential->getAccessKeySecret()); + self::assertEquals($config, $credential->getConfig()); + self::assertInstanceOf(ShaHmac1Signature::class, $credential->getSignature()); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/CredentialsTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/CredentialsTest.php new file mode 100644 index 0000000..2c7e645 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/CredentialsTest.php @@ -0,0 +1,53 @@ +credential = new EcsRamRoleCredential('EcsRamRoleTest'); + Credentials::cancelMock(); + } + + /** + * @throws GuzzleException + */ + public function testConstruct() + { + // Setup + $roleName = 'role_arn'; + $expected = "roleName#$roleName"; + + // Test + $credential = new EcsRamRoleCredential($roleName); + + // Assert + $this->assertEquals($roleName, $credential->getRoleName()); + $this->assertInstanceOf(ShaHmac1Signature::class, $credential->getSignature()); + $this->assertEquals($expected, (string)$credential); + } + + private function getPrivateField($instance, $field) { + $reflection = new ReflectionClass(EcsRamRoleCredential::class); + $privateProperty = $reflection->getProperty($field); + $privateProperty->setAccessible(true); + return $privateProperty->getValue($instance); + } + + /** + * @throws GuzzleException + */ + public function testConstructWithIMDSv2() + { + // Setup + $roleName = 'role_arn'; + $enableIMDSv2 = true; + $metadataTokenDuration = 3600; + $credential = new EcsRamRoleCredential($roleName, $enableIMDSv2, $metadataTokenDuration); + + self::assertEquals(true, $this->getPrivateField($credential, 'enableIMDSv2')); + self::assertEquals(3600, $this->getPrivateField($credential, 'metadataTokenDuration')); + + $credential = new EcsRamRoleCredential($roleName); + + self::assertEquals(false, $this->getPrivateField($credential, 'enableIMDSv2')); + self::assertEquals(21600, $this->getPrivateField($credential, 'metadataTokenDuration')); + } + + /** + * @throws GuzzleException + */ + public function testDefault() + { + $this->credential = new EcsRamRoleCredential(); + $result = [ + 'Expiration' => '2049-10-01 00:00:00', + 'AccessKeyId' => 'foo', + 'AccessKeySecret' => 'bar', + 'SecurityToken' => 'token', + ]; + Credentials::mockResponse(200, [], 'RoleName'); + Credentials::mockResponse(200, [], $result); + + self::assertEquals('foo', $this->credential->getAccessKeyId()); + self::assertEquals('bar', $this->credential->getAccessKeySecret()); + self::assertEquals('token', $this->credential->getSecurityToken()); + self::assertEquals(strtotime('2049-10-01 00:00:00'), $this->credential->getExpiration()); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessageRegExp /The role name was not found in the instance/ + * @throws GuzzleException + */ + public function testDefault404() + { + $this->credential = new EcsRamRoleCredential(); + + Credentials::mockResponse(404, [], 'RoleName'); + + self::assertEquals('foo', $this->credential->getAccessKeyId()); + } + + /** + * @expectedException RuntimeException + * @expectedExceptionMessageRegExp /Error retrieving credentials from result: RoleName/ + * @throws GuzzleException + */ + public function testDefault500() + { + $this->credential = new EcsRamRoleCredential(); + + Credentials::mockResponse(500, [], 'RoleName'); + + self::assertEquals('foo', $this->credential->getAccessKeyId()); + } + + /** + * @expectedException RuntimeException + * @expectedExceptionMessageRegExp /Error retrieving credentials from result is empty/ + * @throws GuzzleException + */ + public function testDefaultEmpty() + { + $this->credential = new EcsRamRoleCredential(); + + Credentials::mockResponse(200, [], ''); + + self::assertEquals('foo', $this->credential->getAccessKeyId()); + } + + /** + * Tears down the fixture, for example, close a network connection. + * This method is called after a test is executed. + * + * @throws GuzzleException + */ + public function testSts() + { + $result = [ + 'Expiration' => '2049-10-01 00:00:00', + 'AccessKeyId' => 'foo', + 'AccessKeySecret' => 'bar', + 'SecurityToken' => 'token', + ]; + Credentials::mockResponse(200, [], $result); + + self::assertEquals('foo', $this->credential->getAccessKeyId()); + self::assertEquals('bar', $this->credential->getAccessKeySecret()); + self::assertEquals('token', $this->credential->getSecurityToken()); + self::assertEquals(strtotime('2049-10-01 00:00:00'), $this->credential->getExpiration()); + } + + /** + * @throws Exception + * @throws \GuzzleHttp\Exception\GuzzleException + * @expectedException \RuntimeException + * @expectedExceptionMessage Result contains no credentials + */ + public function testStsIncomplete() + { + $result = [ + 'Expiration' => '2049-10-01 00:00:00', + 'AccessKeyId' => 'foo', + ]; + $credential = new EcsRamRoleCredential('EcsRamRoleTest2'); + Credentials::mockResponse(200, [], $result); + + // Test + self::assertEquals('foo', $credential->getAccessKeyId()); + } + + /** + * @throws Exception + * @throws \GuzzleHttp\Exception\GuzzleException + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The role was not found in the instance + */ + public function testSts404() + { + $result = [ + 'Expiration' => '2049-10-01 00:00:00', + 'AccessKeyId' => 'foo', + ]; + $credential = new EcsRamRoleCredential('EcsRamRoleTest3'); + Credentials::mockResponse(404, [], $result); + + // Test + self::assertEquals('foo', $credential->getAccessKeyId()); + } + + /** + * @throws Exception + * @throws \GuzzleHttp\Exception\GuzzleException + * @expectedException \RuntimeException + * @expectedExceptionMessageRegExp /Error retrieving credentials from result/ + */ + public function testSts500() + { + $result = [ + 'Expiration' => '2049-10-01 00:00:00', + 'AccessKeyId' => 'foo', + ]; + + $credential = new EcsRamRoleCredential('EcsRamRoleTest3'); + Credentials::mockResponse(500, [], $result); + + // Test + self::assertEquals('foo', $credential->getAccessKeyId()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage role_name cannot be empty + */ + public function testRoleNameEmpty() + { + // Setup + $roleName = ''; + + // Test + new EcsRamRoleCredential($roleName); + } + + /** + * @throws Exception + * @throws \GuzzleHttp\Exception\GuzzleException + * @expectedException \RuntimeException + * @expectedExceptionMessageRegExp /timed/ + */ + public function testStsWithoutMock() + { + Credentials::cancelMock(); + + $credential = new EcsRamRoleCredential('EcsRamRoleTest4'); + + // Test + self::assertEquals('foo', $credential->getAccessKeyId()); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/EcsRamRoleProviderTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/EcsRamRoleProviderTest.php new file mode 100644 index 0000000..f1e477a --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/EcsRamRoleProviderTest.php @@ -0,0 +1,208 @@ + true, + 'metadataTokenDuration' => 3600, + ]; + + // Test + $credential = new EcsRamRoleCredential($roleName); + + $sessionCredential = new EcsRamRoleProvider($credential, $config); + + $sessionConfig = $this->getPrivateField($sessionCredential, 'config'); + + self::assertEquals(true, $sessionConfig['enableIMDSv2']); + self::assertEquals(3600, $sessionConfig['metadataTokenDuration']); + } + + + /** + * @throws Exception + */ + private function invokeProtectedFunc($instance, $method) { + $reflection = new ReflectionClass(EcsRamRoleProvider::class); + $method = $reflection->getMethod($method); + $method->setAccessible(true); + + $result = $method->invoke($instance); + return $result; + } + + /** + * @throws GuzzleException + */ + public function testGetEnableECSIMDSv2() + { + // Setup + $roleName = 'test'; + $config = [ + 'enableIMDSv2' => true, + 'metadataTokenDuration' => 3600, + ]; + + // Test + $credential = new EcsRamRoleCredential($roleName); + + $sessionCredential = new EcsRamRoleProvider($credential, $config); + + self::assertEquals(true, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + + $config = [ + 'metadataTokenDuration' => 3600, + ]; + + $sessionCredential = new EcsRamRoleProvider($credential, $config); + + self::assertEquals(false, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + + putenv('ALIBABA_CLOUD_ECS_IMDSV2_ENABLE=true'); + + self::assertEquals(true, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + + putenv('ALIBABA_CLOUD_ECS_IMDSV2_ENABLE=TRUE'); + + self::assertEquals(true, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + + putenv('ALIBABA_CLOUD_ECS_IMDSV2_ENABLE=ok'); + + self::assertEquals(false, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + + putenv('ALIBABA_CLOUD_ECS_IMDSV2_ENABLE=1'); + + self::assertEquals(false, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + + putenv('ALIBABA_CLOUD_ECS_IMDSV2_ENABLE=false'); + + self::assertEquals(false, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + + putenv('ALIBABA_CLOUD_ECS_IMDSV2_ENABLE='); + + self::assertEquals(false, $this->invokeProtectedFunc($sessionCredential, 'getEnableECSIMDSv2')); + } + + private function getPrivateField($instance, $field) { + $reflection = new ReflectionClass(EcsRamRoleProvider::class); + $privateProperty = $reflection->getProperty($field); + $privateProperty->setAccessible(true); + return $privateProperty->getValue($instance); + } + + /** + * @throws GuzzleException + */ + public function testRefreshMetadataTokenDefault() + { + // Setup + $roleName = 'test'; + $config = [ + 'enableIMDSv2' => true, + 'metadataTokenDuration' => 3600, + ]; + + // Test + $credential = new EcsRamRoleCredential($roleName); + + $sessionCredential = new EcsRamRoleProvider($credential, $config); + + Credentials::mockResponse(200, [], 'Token'); + + $this->invokeProtectedFunc($sessionCredential, 'refreshMetadataToken'); + + $histroy = Credentials::getHistroy(); + + $request = end($histroy)['request']; + $headers = $request->getHeaders(); + self::assertEquals('Token', $this->getPrivateField($sessionCredential, 'metadataToken')); + self::assertEquals('3600', $headers['X-aliyun-ecs-metadata-token-ttl-seconds'][0]); + } + + /** + * @expectedException RuntimeException + * @expectedExceptionMessage Failed to get token from ECS Metadata Service. HttpCode= 404 + * @throws GuzzleException + */ + public function testDefault404() + { + // Setup + $roleName = 'test'; + $config = [ + 'enableIMDSv2' => true, + 'metadataTokenDuration' => 3600, + ]; + + // Test + $credential = new EcsRamRoleCredential($roleName); + + $sessionCredential = new EcsRamRoleProvider($credential, $config); + + Credentials::mockResponse(404, [], 'Error'); + $this->invokeProtectedFunc($sessionCredential, 'refreshMetadataToken'); + + } + + /** + * @throws GuzzleException + */ + public function testNeedToRefresh() + { + // Setup + $roleName = 'test'; + $config = [ + 'enableIMDSv2' => true, + 'metadataTokenDuration' => 5, + ]; + + // Test + $credential = new EcsRamRoleCredential($roleName); + + $sessionCredential = new EcsRamRoleProvider($credential, $config); + + + + self::assertEquals(true, $this->invokeProtectedFunc($sessionCredential, 'needToRefresh')); + + Credentials::mockResponse(200, [], 'Token'); + + $this->invokeProtectedFunc($sessionCredential, 'refreshMetadataToken'); + + self::assertEquals(false, $this->invokeProtectedFunc($sessionCredential, 'needToRefresh')); + + sleep(3); + + self::assertEquals(false, $this->invokeProtectedFunc($sessionCredential, 'needToRefresh')); + + sleep(3); + + self::assertEquals(true, $this->invokeProtectedFunc($sessionCredential, 'needToRefresh')); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/FilterTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/FilterTest.php new file mode 100644 index 0000000..4b12762 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/FilterTest.php @@ -0,0 +1,55 @@ +getMessage()); + } + } + + /** + * @return array + */ + public function accessKey() + { + return [ + [ + ' ', + 'AccessKeySecret', + 'access_key_secret is invalid', + ], + [ + 'AccessKey', + 1, + 'access_key_secret must be a string', + ], + [ + 'AccessKey', + 'AccessKey Secret ', + 'access_key_secret format is invalid', + ], + ]; + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/HelperTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/HelperTest.php new file mode 100644 index 0000000..267f809 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/HelperTest.php @@ -0,0 +1,164 @@ + 'abc'], + ['a', 'b'], + [['c', 'd']], + ['e' => ['a', 'b']], + ['e' => ['c', 'd']], + ] + ); + + self::assertEquals( + [ + 0 => 'abc', + 1 => 'a', + 2 => 'b', + 3 => [ + 0 => 'c', + 1 => 'd', + ], + 'e' => [ + 0 => 'a', + 1 => 'b', + 2 => 'c', + 3 => 'd', + ], + ], + $params + ); + } + + /** + * @throws ReflectionException + */ + public function testGetsHomeDirectoryForWindowsUser() + { + putenv('HOME='); + putenv('HOMEDRIVE=C:'); + putenv('HOMEPATH=\\Users\\Alibaba'); + $ref = new ReflectionClass(Helper::class); + $method = $ref->getMethod('getHomeDirectory'); + $method->setAccessible(true); + $this->assertEquals('C:\\Users\\Alibaba', $method->invoke(null)); + } + + /** + * @depends testGetsHomeDirectoryForWindowsUser + * @throws ReflectionException + */ + public function testGetsHomeDirectoryForLinuxUser() + { + putenv('HOME=/root'); + putenv('HOMEDRIVE='); + putenv('HOMEPATH='); + $ref = new ReflectionClass(Helper::class); + $method = $ref->getMethod('getHomeDirectory'); + $method->setAccessible(true); + $this->assertEquals('/root', $method->invoke(null)); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualAccessKeyCredential.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualAccessKeyCredential.php new file mode 100644 index 0000000..456be51 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualAccessKeyCredential.php @@ -0,0 +1,226 @@ +content = $content; + $this->fileName = $fileName; + } + + /** + * @param string $clineName + * + * @return string + */ + public static function akClientWithAttributes($clineName = 'phpunit') + { + $content = <<url(); + } + + /** + * @return string Virtual Credentials Filename + */ + public function url() + { + $fileName = 'credentials'; + if ($this->fileName) { + $fileName .= "-$this->fileName"; + } + + return vfsStream::newFile($fileName) + ->withContent($this->content) + ->at(vfsStream::setup('AlibabaCloud')) + ->url(); + } + + /** + * @param string $clineName + * + * @return string + */ + public static function akClientWithAttributesNoCertPassword($clineName = 'phpunit') + { + $content = <<url(); + } + + /** + * @return string + */ + public static function noType() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function noSecret() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function badFormat() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function disable() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function invalidType() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function noKey() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function ok() + { + $content = <<url(); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualBearerTokenCredential.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualBearerTokenCredential.php new file mode 100644 index 0000000..f2549c6 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualBearerTokenCredential.php @@ -0,0 +1,52 @@ +url(); + } + + /** + * @return string + */ + public static function client() + { + $content = <<url(); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualEcsRamRoleCredential.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualEcsRamRoleCredential.php new file mode 100644 index 0000000..43e0122 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualEcsRamRoleCredential.php @@ -0,0 +1,41 @@ +url(); + } + + /** + * @return string + */ + public static function client() + { + $content = <<url(); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualRamRoleArnCredential.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualRamRoleArnCredential.php new file mode 100644 index 0000000..4d88eef --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualRamRoleArnCredential.php @@ -0,0 +1,97 @@ +url(); + } + + /** + * @return string + */ + public static function noSecret() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function noRoleArn() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function noRoleSessionName() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function client() + { + $content = <<url(); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualRsaKeyPairCredential.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualRsaKeyPairCredential.php new file mode 100644 index 0000000..3106003 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Ini/VirtualRsaKeyPairCredential.php @@ -0,0 +1,122 @@ +url(); + } + + /** + * @return string + */ + public static function noPrivateKeyFile() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function badPrivateKeyFilePath() + { + $content = <<url(); + } + + /** + * @return string + */ + public static function privateKeyFileUrl() + { + $line1 = Helper::env('PRIVATE_KEY_LINE_1'); + $content = <<url(); + } + + /** + * @return string + */ + public static function badPrivateKey() + { + $content = <<url(); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/MockTraitTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/MockTraitTest.php new file mode 100644 index 0000000..e64f948 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/MockTraitTest.php @@ -0,0 +1,40 @@ + 'access_key_id', + 'access_key_secret' => 'access_key_secret', + 'role_arn' => 'role_arn', + 'role_session_name' => 'role_session_name', + 'policy' => [], + ]); + + self::assertEquals('STS.**************', $credential->getAccessKeyId()); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/RamRoleArnCredentialTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/RamRoleArnCredentialTest.php new file mode 100644 index 0000000..89a1c7e --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/RamRoleArnCredentialTest.php @@ -0,0 +1,172 @@ + 'access_key_id', + 'access_key_secret' => 'access_key_secret', + 'role_arn' => 'role_arn', + 'role_session_name' => 'role_session_name', + 'policy' => '', + ]); + + // Assert + $this->assertEquals($arn, $credential->getRoleArn()); + $this->assertEquals($sessionName, $credential->getRoleSessionName()); + $this->assertEquals($policy, $credential->getPolicy()); + $this->assertInstanceOf(ShaHmac1Signature::class, $credential->getSignature()); + $this->assertEquals( + "$accessKeyId#$accessKeySecret#$arn#$sessionName", + (string)$credential + ); + + $this->assertEquals( + [], + $credential->getConfig() + ); + } + + /** + * @throws Exception + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function testSts() + { + $result = '{ + "RequestId": "88FEA385-EF5D-4A8A-8C00-A07DAE3BFD44", + "AssumedRoleUser": { + "AssumedRoleId": "********************", + "Arn": "********************" + }, + "Credentials": { + "AccessKeySecret": "********************", + "AccessKeyId": "STS.**************", + "Expiration": "2020-02-25T03:56:19Z", + "SecurityToken": "**************" + } +}'; + Credentials::mockResponse(200, [], $result); + Credentials::mockResponse(200, [], $result); + Credentials::mockResponse(200, [], $result); + Credentials::mockResponse(200, [], $result); + $credential = new RamRoleArnCredential([ + 'access_key_id' => 'access_key_id', + 'access_key_secret' => 'access_key_secret', + 'role_arn' => 'role_arn', + 'role_session_name' => 'role_session_name', + 'policy' => [], + ]); + + self::assertEquals('STS.**************', $credential->getAccessKeyId()); + self::assertEquals('********************', $credential->getAccessKeySecret()); + self::assertEquals('**************', $credential->getSecurityToken()); + self::assertEquals(strtotime('2020-02-25T03:56:19Z'), $credential->getExpiration()); + } + + /** + * @throws Exception + * @throws \GuzzleHttp\Exception\GuzzleException + * @expectedException \RuntimeException + * @expectedExceptionMessage Result contains no credentials + */ + public function testStsIncomplete() + { + // Setup + Credentials::cancelMock(); + $result = '{ + "RequestId": "88FEA385-EF5D-4A8A-8C00-A07DAE3BFD44", + "AssumedRoleUser": { + "AssumedRoleId": "********************", + "Arn": "********************" + }, + "Credentials": { + "AccessKeyId": "STS.**************", + "Expiration": "2020-02-25T03:56:19Z", + "SecurityToken": "**************" + } +}'; + Credentials::mockResponse(200, [], $result); + $credential = new RamRoleArnCredential([ + 'access_key_id' => 'access_key_id2', + 'access_key_secret' => 'access_key_secret2', + 'role_arn' => 'role_arn2', + 'role_session_name' => 'role_session_name2', + 'policy' => '', + ]); + + // Test + self::assertEquals('TMPSK.**************', $credential->getAccessKeyId()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_id cannot be empty + */ + public function testAccessKeyIdEmpty() + { + + // Test + new RamRoleArnCredential([ + 'access_key_id' => '', + 'access_key_secret' => 'access_key_secret', + 'role_arn' => 'role_arn', + 'role_session_name' => 'role_session_name', + 'policy' => '', + ]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Missing required access_key_secret option in config for ram_role_arn + */ + public function testAccessKeyIdFormat() + { + // Test + new RamRoleArnCredential([ + 'access_key_id' => 'access_key_id', + 'access_key_secret' => null, + 'role_arn' => 'role_arn', + 'role_session_name' => 'role_session_name', + 'policy' => '', + ]); + } + + protected function setUp(): void + { + // Setup + Credentials::cancelMock(); + $this->credential = new RamRoleArnCredential([ + 'access_key_id' => 'access_key_id', + 'access_key_secret' => 'access_key_secret', + 'role_arn' => 'role_arn', + 'role_session_name' => 'role_session_name', + 'policy' => '', + ]); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/RsaKeyPairCredentialTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/RsaKeyPairCredentialTest.php new file mode 100644 index 0000000..bf1b1a7 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/RsaKeyPairCredentialTest.php @@ -0,0 +1,212 @@ +getMessage() + ); + } + } + + public static function testOpenBasedirException() + { + // Setup + $publicKeyId = 'PUBLIC_KEY_ID'; + if (Helper::isWindows()) { + $dirs = 'C:\\projects;C:\\Users'; + $privateKeyFile = 'C:\\AlibabaCloud\\no.no'; + } else { + $dirs = 'vfs://AlibabaCloud:/home:/Users:/private:/a/b'; + $privateKeyFile = '/dev/no.no'; + } + + // Test + ini_set('open_basedir', $dirs); + try { + new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + } catch (Exception $e) { + self::assertEquals( + "file_get_contents(): open_basedir restriction in effect. File($privateKeyFile) is not within the allowed path(s): ($dirs)", + $e->getMessage() + ); + } + } + + public function testConstruct() + { + // Setup + $publicKeyId = 'public_key_id'; + $privateKeyFile = VirtualRsaKeyPairCredential::privateKeyFileUrl(); + + // Test + $credential = new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + + // Assert + $this->assertEquals($publicKeyId, $credential->getPublicKeyId()); + $this->assertStringEqualsFile($privateKeyFile, $credential->getPrivateKey()); + $this->assertEquals( + "publicKeyId#$publicKeyId", + (string)$credential + ); + $this->assertEquals([], $credential->getConfig()); + $this->assertInstanceOf(ShaHmac1Signature::class, $credential->getSignature()); + $this->assertEquals($publicKeyId, $credential->getOriginalAccessKeyId()); + } + + /** + * @throws Exception + * @throws GuzzleException + */ + public function testSts() + { + $publicKeyId = 'public_key_id'; + $privateKeyFile = VirtualRsaKeyPairCredential::privateKeyFileUrl(); + $result = '{ + "RequestId": "F702286E-F231-4F40-BB86-XXXXXX", + "SessionAccessKey": { + "SessionAccessKeyId": "TMPSK.**************", + "Expiration": "2023-02-19T07:02:36.225Z", + "SessionAccessKeySecret": "**************" + } +}'; + Credentials::mockResponse(200, [], $result); + Credentials::mockResponse(200, [], $result); + Credentials::mockResponse(200, [], $result); + Credentials::mockResponse(200, [], $result); + + // Test + $credential = new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + + self::assertEquals('TMPSK.**************', $credential->getAccessKeyId()); + self::assertEquals('**************', $credential->getAccessKeySecret()); + self::assertEquals('', $credential->getSecurityToken()); + self::assertEquals(strtotime('2023-02-19T07:02:36.225Z'), $credential->getExpiration()); + } + + /** + * @throws Exception + * @throws GuzzleException + * @expectedException \RuntimeException + * @expectedExceptionMessage Result contains no credentials + */ + public function testStsIncomplete() + { + // Setup + $publicKeyId = 'public_key_id_new'; + $privateKeyFile = VirtualRsaKeyPairCredential::privateKeyFileUrl(); + Credentials::cancelMock(); + $result = '{ + "RequestId": "F702286E-F231-4F40-BB86-XXXXXX", + "SessionAccessKey": { + "SessionAccessKeyId": "TMPSK.**************", + "Expiration": "2023-02-19T07:02:36.225Z" + } +}'; + Credentials::mockResponse(200, [], $result); + $credential = new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + + // Test + self::assertEquals('TMPSK.**************', $credential->getAccessKeyId()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage public_key_id cannot be empty + */ + public function testPublicKeyIdEmpty() + { + // Setup + $publicKeyId = ''; + $privateKeyFile = VirtualRsaKeyPairCredential::privateKeyFileUrl(); + + // Test + new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage public_key_id must be a string + */ + public function testPublicKeyIdFormat() + { + // Setup + $publicKeyId = null; + $privateKeyFile = VirtualRsaKeyPairCredential::privateKeyFileUrl(); + + // Test + new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage private_key_file cannot be empty + */ + public function testPrivateKeyFileEmpty() + { + // Setup + $publicKeyId = 'publicKeyId'; + $privateKeyFile = ''; + + // Test + new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage private_key_file must be a string + */ + public function testPrivateKeyFileFormat() + { + // Setup + $publicKeyId = 'publicKeyId'; + $privateKeyFile = null; + + // Test + new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + } + + protected function setUp(): void + { + // Setup + Credentials::cancelMock(); + + // Setup + $publicKeyId = 'public_key_id'; + $privateKeyFile = VirtualRsaKeyPairCredential::privateKeyFileUrl(); + + // Test + $this->credential = new RsaKeyPairCredential($publicKeyId, $privateKeyFile); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/BearerTokenSignatureTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/BearerTokenSignatureTest.php new file mode 100644 index 0000000..e225025 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/BearerTokenSignatureTest.php @@ -0,0 +1,32 @@ +sign($string, $accessKeySecret)); + static::assertEquals('', $signature->getMethod()); + static::assertEquals('1.0', $signature->getVersion()); + static::assertEquals('BEARERTOKEN', $signature->getType()); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac1SignatureTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac1SignatureTest.php new file mode 100644 index 0000000..bc0753e --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac1SignatureTest.php @@ -0,0 +1,32 @@ +getMethod()); + static::assertEquals('1.0', $signature->getVersion()); + static::assertEquals('', $signature->getType()); + static::assertEquals($expected, $signature->sign($string, $accessKeySecret)); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac256SignatureTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac256SignatureTest.php new file mode 100644 index 0000000..78984ac --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac256SignatureTest.php @@ -0,0 +1,35 @@ +getMethod()); + static::assertEquals('1.0', $signature->getVersion()); + static::assertEquals('', $signature->getType()); + static::assertEquals( + $expected, + $signature->sign($string, $accessKeySecret) + ); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac256WithRsaSignatureTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac256WithRsaSignatureTest.php new file mode 100644 index 0000000..d7ea0e9 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/Signature/ShaHmac256WithRsaSignatureTest.php @@ -0,0 +1,55 @@ +getMethod()); + static::assertEquals('1.0', $signature->getVersion()); + static::assertEquals('PRIVATEKEY', $signature->getType()); + static::assertEquals( + $expected, + $signature->sign($string, \file_get_contents($privateKeyFile)) + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionCode 0 + * @expectedExceptionMessage openssl_sign(): supplied key param cannot be coerced into a private key + */ + public function testShaHmac256SignatureBadPrivateKey() + { + // Setup + $string = 'string'; + $privateKeyFile = VirtualRsaKeyPairCredential::badPrivateKey(); + + // Test + $signature = new ShaHmac256WithRsaSignature(); + + // Assert + $signature->sign($string, \file_get_contents($privateKeyFile)); + } +} diff --git a/tests/HigherthanorEqualtoVersion7_2/Unit/StsCredentialTest.php b/tests/HigherthanorEqualtoVersion7_2/Unit/StsCredentialTest.php new file mode 100644 index 0000000..e32ca36 --- /dev/null +++ b/tests/HigherthanorEqualtoVersion7_2/Unit/StsCredentialTest.php @@ -0,0 +1,89 @@ +assertEquals($accessKeyId, $credential->getAccessKeyId()); + $this->assertEquals($accessKeySecret, $credential->getAccessKeySecret()); + $this->assertEquals($securityToken, $credential->getSecurityToken()); + $this->assertEquals($expiration, $credential->getExpiration()); + $this->assertInstanceOf(ShaHmac1Signature::class, $credential->getSignature()); + $this->assertEquals( + "$accessKeyId#$accessKeySecret#$securityToken", + (string)$credential + ); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_id cannot be empty + */ + public function testAccessKeyIdEmpty() + { + // Setup + $accessKeyId = ''; + $accessKeySecret = 'accessKeySecret'; + $securityToken = 'securityToken'; + + new StsCredential($accessKeyId, $accessKeySecret, $securityToken); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_id must be a string + */ + public function testAccessKeyIdFormat() + { + // Setup + $accessKeyId = null; + $accessKeySecret = 'accessKeySecret'; + $securityToken = 'securityToken'; + + new StsCredential($accessKeyId, $accessKeySecret, $securityToken); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_secret cannot be empty + */ + public function testAccessKeySecretEmpty() + { + // Setup + $accessKeyId = 'accessKeyId'; + $accessKeySecret = ''; + $securityToken = 'securityToken'; + + new StsCredential($accessKeyId, $accessKeySecret, $securityToken); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage access_key_secret must be a string + */ + public function testAccessKeySecretFormat() + { + // Setup + $accessKeyId = 'accessKeyId'; + $accessKeySecret = null; + $securityToken = 'securityToken'; + + new StsCredential($accessKeyId, $accessKeySecret, $securityToken); + } +} diff --git a/tests/Feature/CredentialTest.php b/tests/LowerthanVersion7_2/Feature/CredentialTest.php similarity index 91% rename from tests/Feature/CredentialTest.php rename to tests/LowerthanVersion7_2/Feature/CredentialTest.php index a797fe8..14fd5b3 100644 --- a/tests/Feature/CredentialTest.php +++ b/tests/LowerthanVersion7_2/Feature/CredentialTest.php @@ -1,11 +1,11 @@ 'ecs_ram_role', - 'roleName' => 'foo', + 'type' => 'ecs_ram_role', + 'roleName' => 'foo', + 'enableIMDSv2' => true, ]); $credential = new Credential($config); // Assert $this->assertEquals('foo', $credential->getRoleName()); $this->assertEquals('ecs_ram_role', $credential->getType()); + $this->assertTrue($credential->isEnableIMDSv2()); $credential->getAccessKeySecret(); } diff --git a/tests/Unit/AccessKeyCredentialTest.php b/tests/LowerthanVersion7_2/Unit/AccessKeyCredentialTest.php similarity index 94% rename from tests/Unit/AccessKeyCredentialTest.php rename to tests/LowerthanVersion7_2/Unit/AccessKeyCredentialTest.php index a066674..41d1bfc 100644 --- a/tests/Unit/AccessKeyCredentialTest.php +++ b/tests/LowerthanVersion7_2/Unit/AccessKeyCredentialTest.php @@ -1,6 +1,6 @@ 'test', 'enableIMDSv2' => 'false', ], - 'enable_IMDS_v2 must be a string', + 'enable_imds_v2 must be a string', ], [ diff --git a/tests/Unit/CredentialsTest.php b/tests/LowerthanVersion7_2/Unit/CredentialsTest.php similarity index 88% rename from tests/Unit/CredentialsTest.php rename to tests/LowerthanVersion7_2/Unit/CredentialsTest.php index 16a7764..37b93cc 100644 --- a/tests/Unit/CredentialsTest.php +++ b/tests/LowerthanVersion7_2/Unit/CredentialsTest.php @@ -1,6 +1,6 @@