IniCredential.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. namespace AlibabaCloud\Client\Credentials\Ini;
  3. use AlibabaCloud\Client\SDK;
  4. use AlibabaCloud\Client\Clients\Client;
  5. use AlibabaCloud\Client\Exception\ClientException;
  6. /**
  7. * Class IniCredential
  8. *
  9. * @package AlibabaCloud\Client\Credentials\Ini
  10. */
  11. class IniCredential
  12. {
  13. use CreateTrait;
  14. use OptionsTrait;
  15. /**
  16. * @var array
  17. */
  18. private static $hasLoaded;
  19. /**
  20. * @var string
  21. */
  22. protected $filename;
  23. /**
  24. * IniCredential constructor.
  25. *
  26. * @param string $filename
  27. */
  28. public function __construct($filename = '')
  29. {
  30. $this->filename = $filename ?: $this->getDefaultFile();
  31. }
  32. /**
  33. * Get the default credential file.
  34. *
  35. * @return string
  36. */
  37. public function getDefaultFile()
  38. {
  39. return self::getHomeDirectory() . DIRECTORY_SEPARATOR . '.alibabacloud' . DIRECTORY_SEPARATOR . 'credentials';
  40. }
  41. /**
  42. * Gets the environment's HOME directory.
  43. *
  44. * @return null|string
  45. */
  46. private static function getHomeDirectory()
  47. {
  48. if (getenv('HOME')) {
  49. return getenv('HOME');
  50. }
  51. return (getenv('HOMEDRIVE') && getenv('HOMEPATH'))
  52. ? getenv('HOMEDRIVE') . getenv('HOMEPATH')
  53. : null;
  54. }
  55. /**
  56. * Clear credential cache.
  57. *
  58. * @return void
  59. */
  60. public static function forgetLoadedCredentialsFile()
  61. {
  62. self::$hasLoaded = [];
  63. }
  64. /**
  65. * Get the credential file.
  66. *
  67. * @return string
  68. */
  69. public function getFilename()
  70. {
  71. return $this->filename;
  72. }
  73. /**
  74. * @param array $array
  75. * @param string $key
  76. *
  77. * @return bool
  78. */
  79. protected static function isNotEmpty(array $array, $key)
  80. {
  81. return isset($array[$key]) && !empty($array[$key]);
  82. }
  83. /**
  84. * @param string $key
  85. * @param string $clientName
  86. *
  87. * @throws ClientException
  88. */
  89. public function missingRequired($key, $clientName)
  90. {
  91. throw new ClientException(
  92. "Missing required '$key' option for '$clientName' in " . $this->getFilename(),
  93. SDK::INVALID_CREDENTIAL
  94. );
  95. }
  96. /**
  97. * @return array|mixed
  98. * @throws ClientException
  99. */
  100. public function load()
  101. {
  102. // If it has been loaded, assign the client directly.
  103. if (isset(self::$hasLoaded[$this->filename])) {
  104. /**
  105. * @var $client Client
  106. */
  107. foreach (self::$hasLoaded[$this->filename] as $projectName => $client) {
  108. $client->name($projectName);
  109. }
  110. return self::$hasLoaded[$this->filename];
  111. }
  112. return $this->loadFile();
  113. }
  114. /**
  115. * Exceptions will be thrown if the file is unreadable and not the default file.
  116. *
  117. * @return array|mixed
  118. * @throws ClientException
  119. */
  120. private function loadFile()
  121. {
  122. if (!\AlibabaCloud\Client\inOpenBasedir($this->filename)) {
  123. return [];
  124. }
  125. if (!\is_readable($this->filename) || !\is_file($this->filename)) {
  126. if ($this->filename === $this->getDefaultFile()) {
  127. // @codeCoverageIgnoreStart
  128. return [];
  129. // @codeCoverageIgnoreEnd
  130. }
  131. throw new ClientException(
  132. 'Credential file is not readable: ' . $this->getFilename(),
  133. SDK::INVALID_CREDENTIAL
  134. );
  135. }
  136. return $this->parseFile();
  137. }
  138. /**
  139. * Decode the ini file into an array.
  140. *
  141. * @return array|mixed
  142. * @throws ClientException
  143. */
  144. private function parseFile()
  145. {
  146. try {
  147. $file = \parse_ini_file($this->filename, true);
  148. if (\is_array($file) && $file !== []) {
  149. return $this->initClients($file);
  150. }
  151. throw new ClientException(
  152. 'Format error: ' . $this->getFilename(),
  153. SDK::INVALID_CREDENTIAL
  154. );
  155. } catch (\Exception $e) {
  156. throw new ClientException(
  157. $e->getMessage(),
  158. SDK::INVALID_CREDENTIAL,
  159. $e
  160. );
  161. }
  162. }
  163. /**
  164. * Initialize clients.
  165. *
  166. * @param array $array
  167. *
  168. * @return array|mixed
  169. * @throws ClientException
  170. */
  171. private function initClients($array)
  172. {
  173. foreach (\array_change_key_case($array) as $clientName => $configures) {
  174. $configures = \array_change_key_case($configures);
  175. $clientInstance = $this->createClient($clientName, $configures);
  176. if ($clientInstance instanceof Client) {
  177. self::$hasLoaded[$this->filename][$clientName] = $clientInstance;
  178. self::setClientAttributes($configures, $clientInstance);
  179. self::setCert($configures, $clientInstance);
  180. self::setProxy($configures, $clientInstance);
  181. }
  182. }
  183. return isset(self::$hasLoaded[$this->filename])
  184. ? self::$hasLoaded[$this->filename]
  185. : [];
  186. }
  187. }