Credential.php 4.3 KB

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