1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace AlibabaCloud\Client\Credentials\Ini; |
4
|
|
|
|
5
|
|
|
use AlibabaCloud\Client\Clients\Client; |
6
|
|
|
use AlibabaCloud\Client\Exception\ClientException; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class IniCredential |
10
|
|
|
* |
11
|
|
|
* @package AlibabaCloud\Client\Credentials\Ini |
12
|
|
|
*/ |
13
|
|
|
class IniCredential |
14
|
|
|
{ |
15
|
|
|
use CreateTrait; |
16
|
|
|
use OptionsTrait; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* @var array |
20
|
|
|
*/ |
21
|
|
|
private static $hasLoaded; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @var string |
25
|
|
|
*/ |
26
|
|
|
protected $filename; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* IniCredential constructor. |
30
|
|
|
* |
31
|
|
|
* @param string $filename |
32
|
|
|
*/ |
33
|
68 |
|
public function __construct($filename = '') |
34
|
|
|
{ |
35
|
68 |
|
$this->filename = $filename ?: $this->getDefaultFile(); |
36
|
68 |
|
} |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* Get the default credential file. |
40
|
|
|
* |
41
|
|
|
* @return string |
42
|
|
|
*/ |
43
|
39 |
|
public function getDefaultFile() |
44
|
|
|
{ |
45
|
39 |
|
return self::getHomeDirectory() . '/.alibabacloud/credentials'; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Get the credential file. |
50
|
|
|
* |
51
|
|
|
* @return string |
52
|
|
|
*/ |
53
|
39 |
|
public function getFilename() |
54
|
|
|
{ |
55
|
39 |
|
return $this->filename; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* Gets the environment's HOME directory. |
60
|
|
|
* |
61
|
|
|
* @return null|string |
62
|
|
|
*/ |
63
|
40 |
|
private static function getHomeDirectory() |
64
|
|
|
{ |
65
|
40 |
|
if (getenv('HOME')) { |
66
|
39 |
|
return getenv('HOME'); |
67
|
|
|
} |
68
|
|
|
|
69
|
1 |
|
return (getenv('HOMEDRIVE') && getenv('HOMEPATH')) |
70
|
1 |
|
? getenv('HOMEDRIVE') . getenv('HOMEPATH') |
71
|
1 |
|
: null; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @param array $array |
76
|
|
|
* @param string $key |
77
|
|
|
* |
78
|
|
|
* @return bool |
79
|
|
|
*/ |
80
|
16 |
|
protected static function isNotEmpty(array $array, $key) |
81
|
|
|
{ |
82
|
16 |
|
return isset($array[$key]) && !empty($array[$key]); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* @param string $key |
87
|
|
|
* @param string $clientName |
88
|
|
|
* |
89
|
|
|
* @throws ClientException |
90
|
|
|
*/ |
91
|
28 |
|
public function missingRequired($key, $clientName) |
92
|
|
|
{ |
93
|
28 |
|
throw new ClientException( |
94
|
28 |
|
"Missing required '$key' option for '$clientName' in " . $this->getFilename(), |
95
|
|
|
\ALIBABA_CLOUD_INVALID_CREDENTIAL |
96
|
28 |
|
); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Clear credential cache. |
101
|
|
|
* |
102
|
|
|
* @return void |
103
|
|
|
*/ |
104
|
24 |
|
public static function forgetLoadedCredentialsFile() |
105
|
|
|
{ |
106
|
24 |
|
self::$hasLoaded = []; |
107
|
24 |
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @return array|mixed |
111
|
|
|
* @throws ClientException |
112
|
|
|
*/ |
113
|
28 |
|
public function load() |
114
|
|
|
{ |
115
|
|
|
// If it has been loaded, assign the client directly. |
116
|
28 |
|
if (isset(self::$hasLoaded[$this->filename])) { |
117
|
|
|
/** |
118
|
|
|
* @var $client Client |
119
|
|
|
*/ |
120
|
3 |
|
foreach (self::$hasLoaded[$this->filename] as $projectName => $client) { |
121
|
3 |
|
$client->name($projectName); |
122
|
3 |
|
} |
123
|
|
|
|
124
|
3 |
|
return self::$hasLoaded[$this->filename]; |
125
|
|
|
} |
126
|
|
|
|
127
|
27 |
|
return $this->loadFile(); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Exceptions will be thrown if the file is unreadable and not the default file. |
132
|
|
|
* |
133
|
|
|
* @return array|mixed |
134
|
|
|
* @throws ClientException |
135
|
|
|
*/ |
136
|
29 |
|
private function loadFile() |
137
|
|
|
{ |
138
|
29 |
|
if (!self::inOpenBasedir($this->filename)) { |
139
|
|
|
return []; |
140
|
|
|
} |
141
|
|
|
|
142
|
29 |
|
if (!\is_readable($this->filename) || !\is_file($this->filename)) { |
143
|
6 |
|
if ($this->filename === $this->getDefaultFile()) { |
144
|
|
|
// @codeCoverageIgnoreStart |
145
|
|
|
return []; |
146
|
|
|
// @codeCoverageIgnoreEnd |
147
|
|
|
} |
148
|
4 |
|
throw new ClientException( |
149
|
4 |
|
'Credential file is not readable: ' . $this->getFilename(), |
150
|
|
|
\ALIBABA_CLOUD_INVALID_CREDENTIAL |
151
|
4 |
|
); |
152
|
|
|
} |
153
|
|
|
|
154
|
23 |
|
return $this->parseFile(); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* @param $filename |
159
|
|
|
* |
160
|
|
|
* @return bool |
161
|
|
|
*/ |
162
|
29 |
|
public static function inOpenBasedir($filename) |
163
|
|
|
{ |
164
|
29 |
|
$dir = ini_get('open_basedir'); |
165
|
29 |
|
if (!$dir) { |
166
|
29 |
|
return true; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
$dirs = explode(':', $dir); |
170
|
|
|
if (!$dirs) { |
|
|
|
|
171
|
|
|
return true; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
foreach ($dirs as $dir) { |
175
|
|
|
if (false !== strpos($filename, $dir)) { |
176
|
|
|
return true; |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
return false; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Decode the ini file into an array. |
185
|
|
|
* |
186
|
|
|
* @return array|mixed |
187
|
|
|
* @throws ClientException |
188
|
|
|
*/ |
189
|
27 |
|
private function parseFile() |
190
|
|
|
{ |
191
|
|
|
try { |
192
|
27 |
|
$file = \parse_ini_file($this->filename, true); |
193
|
26 |
|
if (\is_array($file) && $file !== []) { |
194
|
23 |
|
return $this->initClients($file); |
195
|
|
|
} |
196
|
3 |
|
throw new ClientException( |
197
|
3 |
|
'Format error: ' . $this->getFilename(), |
198
|
|
|
\ALIBABA_CLOUD_INVALID_CREDENTIAL |
199
|
3 |
|
); |
200
|
17 |
|
} catch (\Exception $e) { |
201
|
17 |
|
throw new ClientException( |
202
|
17 |
|
$e->getMessage(), |
203
|
17 |
|
\ALIBABA_CLOUD_INVALID_CREDENTIAL, |
204
|
|
|
$e |
205
|
17 |
|
); |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Initialize clients. |
211
|
|
|
* |
212
|
|
|
* @param array $array |
213
|
|
|
* |
214
|
|
|
* @return array|mixed |
215
|
|
|
* @throws ClientException |
216
|
|
|
*/ |
217
|
23 |
|
private function initClients($array) |
218
|
|
|
{ |
219
|
23 |
|
foreach (\array_change_key_case($array) as $clientName => $configures) { |
220
|
23 |
|
$configures = \array_change_key_case($configures); |
221
|
23 |
|
$clientInstance = $this->createClient($clientName, $configures); |
222
|
10 |
|
if ($clientInstance instanceof Client) { |
223
|
9 |
|
self::$hasLoaded[$this->filename][$clientName] = $clientInstance; |
224
|
9 |
|
self::setClientAttributes($configures, $clientInstance); |
225
|
9 |
|
self::setCert($configures, $clientInstance); |
226
|
9 |
|
self::setProxy($configures, $clientInstance); |
227
|
9 |
|
} |
228
|
10 |
|
} |
229
|
|
|
|
230
|
10 |
|
return isset(self::$hasLoaded[$this->filename]) |
231
|
10 |
|
? self::$hasLoaded[$this->filename] |
232
|
10 |
|
: []; |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.