Credential.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. namespace AlibabaCloud\Credentials;
  3. use AlibabaCloud\Credentials\Credential\Config;
  4. use InvalidArgumentException;
  5. use ReflectionClass;
  6. use ReflectionException;
  7. use ReflectionParameter;
  8. /**
  9. * Class Credential
  10. *
  11. * @package AlibabaCloud\Credentials
  12. *
  13. * @mixin AccessKeyCredential
  14. * @mixin BearerTokenCredential
  15. * @mixin EcsRamRoleCredential
  16. * @mixin RamRoleArnCredential
  17. * @mixin RsaKeyPairCredential
  18. */
  19. class Credential
  20. {
  21. /**
  22. * @var array
  23. */
  24. protected $config = [];
  25. /**
  26. * @var array
  27. */
  28. protected $types = [
  29. 'access_key' => AccessKeyCredential::class,
  30. 'sts' => StsCredential::class,
  31. 'ecs_ram_role' => EcsRamRoleCredential::class,
  32. 'ram_role_arn' => RamRoleArnCredential::class,
  33. 'rsa_key_pair' => RsaKeyPairCredential::class,
  34. 'bearer' => BearerTokenCredential::class,
  35. ];
  36. /**
  37. * @var AccessKeyCredential|BearerTokenCredential|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential
  38. */
  39. protected $credential;
  40. /**
  41. * @var string
  42. */
  43. protected $type;
  44. /**
  45. * Credential constructor.
  46. *
  47. * @param array|Config $config
  48. *
  49. * @throws ReflectionException
  50. */
  51. public function __construct($config = [])
  52. {
  53. if ($config instanceof Config) {
  54. $config = $this->parse($config);
  55. }
  56. if ($config !== []) {
  57. $this->config = array_change_key_case($config);
  58. $this->parseConfig();
  59. } else {
  60. $this->credential = Credentials::get()->getCredential();
  61. }
  62. }
  63. /**
  64. * @param Config $config
  65. *
  66. * @return array
  67. */
  68. private function parse($config)
  69. {
  70. $config = get_object_vars($config);
  71. $res = [];
  72. foreach ($config as $key => $value) {
  73. $res[$this->toUnderScore($key)] = $value;
  74. }
  75. return $res;
  76. }
  77. private function toUnderScore($str)
  78. {
  79. $dstr = preg_replace_callback('/([A-Z]+)/', function ($matchs) {
  80. return '_' . strtolower($matchs[0]);
  81. }, $str);
  82. return trim(preg_replace('/_{2,}/', '_', $dstr), '_');
  83. }
  84. /**
  85. * @throws ReflectionException
  86. */
  87. private function parseConfig()
  88. {
  89. if (!isset($this->config['type'])) {
  90. throw new InvalidArgumentException('Missing required type option');
  91. }
  92. $this->type = $this->config['type'];
  93. if (!isset($this->types[$this->type])) {
  94. throw new InvalidArgumentException(
  95. 'Invalid type option, support: ' .
  96. implode(', ', array_keys($this->types))
  97. );
  98. }
  99. $class = new ReflectionClass($this->types[$this->type]);
  100. $parameters = [];
  101. /**
  102. * @var $parameter ReflectionParameter
  103. */
  104. foreach ($class->getConstructor()->getParameters() as $parameter) {
  105. $parameters[] = $this->getValue($parameter);
  106. }
  107. $this->credential = $class->newInstance(...$parameters);
  108. }
  109. /**
  110. * @param ReflectionParameter $parameter
  111. *
  112. * @return string|array
  113. * @throws ReflectionException
  114. */
  115. protected function getValue(ReflectionParameter $parameter)
  116. {
  117. if ($parameter->name === 'config' || $parameter->name === 'credential') {
  118. return $this->config;
  119. }
  120. foreach ($this->config as $key => $value) {
  121. if (strtolower($parameter->name) === $key) {
  122. return $value;
  123. }
  124. }
  125. if ($parameter->isDefaultValueAvailable()) {
  126. return $parameter->getDefaultValue();
  127. }
  128. throw new InvalidArgumentException("Missing required {$parameter->name} option in config for {$this->type}");
  129. }
  130. /**
  131. * @return AccessKeyCredential|BearerTokenCredential|EcsRamRoleCredential|RamRoleArnCredential|RsaKeyPairCredential
  132. */
  133. public function getCredential()
  134. {
  135. return $this->credential;
  136. }
  137. /**
  138. * @return array
  139. */
  140. public function getConfig()
  141. {
  142. return $this->config;
  143. }
  144. /**
  145. * @return string
  146. */
  147. public function getType()
  148. {
  149. return $this->type;
  150. }
  151. /**
  152. * @param string $name
  153. * @param array $arguments
  154. *
  155. * @return mixed
  156. */
  157. public function __call($name, $arguments)
  158. {
  159. return $this->credential->$name($arguments);
  160. }
  161. }