CLIProfileCredentialsProvider.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. namespace AlibabaCloud\Credentials\Providers;
  3. use AlibabaCloud\Credentials\Utils\Helper;
  4. use RuntimeException;
  5. /**
  6. * @internal This class is intended for internal use within the package.
  7. * Class CLIProfileCredentialsProvider
  8. *
  9. * @package AlibabaCloud\Credentials\Providers
  10. */
  11. class CLIProfileCredentialsProvider implements CredentialsProvider
  12. {
  13. /**
  14. * @var string
  15. */
  16. private $profileName;
  17. /**
  18. * @var CredentialsProvider
  19. */
  20. private $credentialsProvider;
  21. /**
  22. * CLIProfileCredentialsProvider constructor.
  23. *
  24. * @param array $params
  25. */
  26. public function __construct(array $params = [])
  27. {
  28. $this->filterProfileName($params);
  29. }
  30. private function filterProfileName(array $params)
  31. {
  32. if (Helper::envNotEmpty('ALIBABA_CLOUD_PROFILE')) {
  33. $this->profileName = Helper::env('ALIBABA_CLOUD_PROFILE');
  34. }
  35. if (isset($params['profileName'])) {
  36. $this->profileName = $params['profileName'];
  37. }
  38. }
  39. /**
  40. * @return bool
  41. */
  42. private function shouldReloadCredentialsProvider()
  43. {
  44. if (is_null($this->credentialsProvider)) {
  45. return true;
  46. }
  47. return false;
  48. }
  49. /**
  50. * @return CredentialsProvider
  51. */
  52. protected function reloadCredentialsProvider($profileFile, $profileName)
  53. {
  54. if (!Helper::inOpenBasedir($profileFile)) {
  55. throw new RuntimeException('Unable to open credentials file: ' . $profileFile);
  56. }
  57. if (!\is_readable($profileFile) || !\is_file($profileFile)) {
  58. throw new RuntimeException('Credentials file is not readable: ' . $profileFile);
  59. }
  60. $jsonContent = \file_get_contents($profileFile);
  61. $fileArray = json_decode($jsonContent, true);
  62. if (\is_array($fileArray) && !empty($fileArray)) {
  63. if (is_null($profileName) || $profileName === '') {
  64. $profileName = $fileArray['current'];
  65. }
  66. if (isset($fileArray['profiles'])) {
  67. foreach ($fileArray['profiles'] as $profile) {
  68. if (Helper::unsetReturnNull($profile, 'name') === $profileName) {
  69. switch (Helper::unsetReturnNull($profile, 'mode')) {
  70. case 'AK':
  71. return new StaticAKCredentialsProvider([
  72. 'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'),
  73. 'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'),
  74. ]);
  75. case 'RamRoleArn':
  76. $innerProvider = new StaticAKCredentialsProvider([
  77. 'accessKeyId' => Helper::unsetReturnNull($profile, 'access_key_id'),
  78. 'accessKeySecret' => Helper::unsetReturnNull($profile, 'access_key_secret'),
  79. ]);
  80. return new RamRoleArnCredentialsProvider([
  81. 'credentialsProvider' => $innerProvider,
  82. 'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
  83. 'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
  84. 'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
  85. 'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
  86. ]);
  87. case 'EcsRamRole':
  88. return new EcsRamRoleCredentialsProvider([
  89. 'roleName' => Helper::unsetReturnNull($profile, 'ram_role_name'),
  90. ]);
  91. case 'OIDC':
  92. return new OIDCRoleArnCredentialsProvider([
  93. 'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
  94. 'oidcProviderArn' => Helper::unsetReturnNull($profile, 'oidc_provider_arn'),
  95. 'oidcTokenFilePath' => Helper::unsetReturnNull($profile, 'oidc_token_file'),
  96. 'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
  97. 'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
  98. 'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
  99. ]);
  100. case 'ChainableRamRoleArn':
  101. $previousProvider = $this->reloadCredentialsProvider($profileFile, Helper::unsetReturnNull($profile, 'source_profile'));
  102. return new RamRoleArnCredentialsProvider([
  103. 'credentialsProvider' => $previousProvider,
  104. 'roleArn' => Helper::unsetReturnNull($profile, 'ram_role_arn'),
  105. 'roleSessionName' => Helper::unsetReturnNull($profile, 'ram_session_name'),
  106. 'durationSeconds' => Helper::unsetReturnNull($profile, 'expired_seconds'),
  107. 'stsRegionId' => Helper::unsetReturnNull($profile, 'sts_region'),
  108. ]);
  109. default:
  110. throw new RuntimeException('Unsupported credential mode from CLI credentials file: ' . Helper::unsetReturnNull($profile, 'mode'));
  111. }
  112. }
  113. }
  114. }
  115. }
  116. throw new RuntimeException('Failed to get credential from CLI credentials file: ' . $profileFile);
  117. }
  118. /**
  119. * Get credential.
  120. *
  121. * @return Credentials
  122. * @throws RuntimeException
  123. */
  124. public function getCredentials()
  125. {
  126. if (Helper::envNotEmpty('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') && Helper::env('ALIBABA_CLOUD_CLI_PROFILE_DISABLED') === true) {
  127. throw new RuntimeException('CLI credentials file is disabled');
  128. }
  129. $cliProfileFile = self::getDefaultFile();
  130. if ($this->shouldReloadCredentialsProvider()) {
  131. $this->credentialsProvider = $this->reloadCredentialsProvider($cliProfileFile, $this->profileName);
  132. }
  133. $credentials = $this->credentialsProvider->getCredentials();
  134. return new Credentials([
  135. 'accessKeyId' => $credentials->getAccessKeyId(),
  136. 'accessKeySecret' => $credentials->getAccessKeySecret(),
  137. 'securityToken' => $credentials->getSecurityToken(),
  138. 'providerName' => $this->getProviderName() . '/' . $this->credentialsProvider->getProviderName(),
  139. ]);
  140. }
  141. /**
  142. * Get the default credential file.
  143. *
  144. * @return string
  145. */
  146. private function getDefaultFile()
  147. {
  148. return Helper::getHomeDirectory() .
  149. DIRECTORY_SEPARATOR .
  150. '.aliyun' .
  151. DIRECTORY_SEPARATOR .
  152. 'config.json';
  153. }
  154. /**
  155. * @return string
  156. */
  157. public function getProviderName()
  158. {
  159. return 'cli_profile';
  160. }
  161. }