/usr/share/php/Aws/Credentials/CredentialProvider.php is in php-aws-sdk 3.15.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | <?php
namespace Aws\Credentials;
use Aws;
use Aws\CacheInterface;
use Aws\Exception\CredentialsException;
use GuzzleHttp\Promise;
/**
* Credential providers are functions that accept no arguments and return a
* promise that is fulfilled with an {@see \Aws\Credentials\CredentialsInterface}
* or rejected with an {@see \Aws\Exception\CredentialsException}.
*
* <code>
* use Aws\Credentials\CredentialProvider;
* $provider = CredentialProvider::defaultProvider();
* // Returns a CredentialsInterface or throws.
* $creds = $provider()->wait();
* </code>
*
* Credential providers can be composed to create credentials using conditional
* logic that can create different credentials in different environments. You
* can compose multiple providers into a single provider using
* {@see Aws\Credentials\CredentialProvider::chain}. This function accepts
* providers as variadic arguments and returns a new function that will invoke
* each provider until a successful set of credentials is returned.
*
* <code>
* // First try an INI file at this location.
* $a = CredentialProvider::ini(null, '/path/to/file.ini');
* // Then try an INI file at this location.
* $b = CredentialProvider::ini(null, '/path/to/other-file.ini');
* // Then try loading from envrionment variables.
* $c = CredentialProvider::env();
* // Combine the three providers together.
* $composed = CredentialProvider::chain($a, $b, $c);
* // Returns a promise that is fulfilled with credentials or throws.
* $promise = $composed();
* // Wait on the credentials to resolve.
* $creds = $promise->wait();
* </code>
*/
class CredentialProvider
{
const ENV_KEY = 'AWS_ACCESS_KEY_ID';
const ENV_SECRET = 'AWS_SECRET_ACCESS_KEY';
const ENV_SESSION = 'AWS_SESSION_TOKEN';
const ENV_PROFILE = 'AWS_PROFILE';
/**
* Create a default credential provider that first checks for environment
* variables, then checks for the "default" profile in ~/.aws/credentials,
* and finally checks for credentials using EC2 instance profile
* credentials.
*
* This provider is automatically wrapped in a memoize function that caches
* previously provided credentials.
*
* @param array $config Optional array of instance profile credentials
* provider options.
* @return callable
*/
public static function defaultProvider(array $config = [])
{
$instanceProfileProvider = self::instanceProfile($config);
if (isset($config['credentials'])
&& $config['credentials'] instanceof CacheInterface
) {
$instanceProfileProvider = self::cache(
$instanceProfileProvider,
$config['credentials']
);
}
return self::memoize(
self::chain(
self::env(),
self::ini(),
$instanceProfileProvider
)
);
}
/**
* Create a credential provider function from a set of static credentials.
*
* @param CredentialsInterface $creds
*
* @return callable
*/
public static function fromCredentials(CredentialsInterface $creds)
{
$promise = Promise\promise_for($creds);
return function () use ($promise) {
return $promise;
};
}
/**
* Creates an aggregate credentials provider that invokes the provided
* variadic providers one after the other until a provider returns
* credentials.
*
* @return callable
*/
public static function chain()
{
$links = func_get_args();
if (empty($links)) {
throw new \InvalidArgumentException('No providers in chain');
}
return function () use ($links) {
/** @var callable $parent */
$parent = array_shift($links);
$promise = $parent();
while ($next = array_shift($links)) {
$promise = $promise->otherwise($next);
}
return $promise;
};
}
/**
* Wraps a credential provider and caches previously provided credentials.
*
* Ensures that cached credentials are refreshed when they expire.
*
* @param callable $provider Credentials provider function to wrap.
*
* @return callable
*/
public static function memoize(callable $provider)
{
return function () use ($provider) {
static $result;
static $isConstant;
// Constant credentials will be returned constantly.
if ($isConstant) {
return $result;
}
// Create the initial promise that will be used as the cached value
// until it expires.
if (null === $result) {
$result = $provider();
}
// Return credentials that could expire and refresh when needed.
return $result
->then(function (CredentialsInterface $creds) use ($provider, &$isConstant, &$result) {
// Determine if these are constant credentials.
if (!$creds->getExpiration()) {
$isConstant = true;
return $creds;
}
// Refresh expired credentials.
if (!$creds->isExpired()) {
return $creds;
}
// Refresh the result and forward the promise.
return $result = $provider();
});
};
}
/**
* Wraps a credential provider and saves provided credentials in an
* instance of Aws\CacheInterface. Forwards calls when no credentials found
* in cache and updates cache with the results.
*
* Defaults to using a simple file-based cache when none provided.
*
* @param callable $provider Credentials provider function to wrap
* @param CacheInterface $cache (optional) Cache to store credentials
* @param string|null $cacheKey (optional) Cache key to use
*
* @return callable
*/
public static function cache(
callable $provider,
CacheInterface $cache,
$cacheKey = null
) {
$cacheKey = $cacheKey ?: 'aws_cached_credentials';
return function () use ($provider, $cache, $cacheKey) {
$found = $cache->get($cacheKey);
if ($found instanceof CredentialsInterface && !$found->isExpired()) {
return Promise\promise_for($found);
}
return $provider()
->then(function (CredentialsInterface $creds) use (
$cache,
$cacheKey
) {
$cache->set(
$cacheKey,
$creds,
null === $creds->getExpiration() ?
0 : $creds->getExpiration() - time()
);
return $creds;
});
};
}
/**
* Provider that creates credentials from environment variables
* AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN.
*
* @return callable
*/
public static function env()
{
return function () {
// Use credentials from environment variables, if available
$key = getenv(self::ENV_KEY);
$secret = getenv(self::ENV_SECRET);
if ($key && $secret) {
return Promise\promise_for(
new Credentials($key, $secret, getenv(self::ENV_SESSION))
);
}
return self::reject('Could not find environment variable '
. 'credentials in ' . self::ENV_KEY . '/' . self::ENV_SECRET);
};
}
/**
* Credential provider that creates credentials using instance profile
* credentials.
*
* @param array $config Array of configuration data.
*
* @return InstanceProfileProvider
* @see Aws\Credentials\InstanceProfileProvider for $config details.
*/
public static function instanceProfile(array $config = [])
{
return new InstanceProfileProvider($config);
}
/**
* Credentials provider that creates credentials using an ini file stored
* in the current user's home directory.
*
* @param string|null $profile Profile to use. If not specified will use
* the "default" profile.
* @param string|null $filename If provided, uses a custom filename rather
* than looking in the home directory for the
*
* @return callable
*/
public static function ini($profile = null, $filename = null)
{
$filename = $filename ?: (self::getHomeDir() . '/.aws/credentials');
$profile = $profile ?: (getenv(self::ENV_PROFILE) ?: 'default');
return function () use ($profile, $filename) {
if (!is_readable($filename)) {
return self::reject("Cannot read credentials from $filename");
}
$data = parse_ini_file($filename, true);
if ($data === false) {
return self::reject("Invalid credentials file: $filename");
}
if (!isset($data[$profile])) {
return self::reject("'$profile' not found in credentials file");
}
if (!isset($data[$profile]['aws_access_key_id'])
|| !isset($data[$profile]['aws_secret_access_key'])
) {
return self::reject("No credentials present in INI profile "
. "'$profile' ($filename)");
}
if (empty($data[$profile]['aws_session_token'])) {
$data[$profile]['aws_session_token']
= isset($data[$profile]['aws_security_token'])
? $data[$profile]['aws_security_token']
: null;
}
return Promise\promise_for(
new Credentials(
$data[$profile]['aws_access_key_id'],
$data[$profile]['aws_secret_access_key'],
$data[$profile]['aws_session_token']
)
);
};
}
/**
* Gets the environment's HOME directory if available.
*
* @return null|string
*/
private static function getHomeDir()
{
// On Linux/Unix-like systems, use the HOME environment variable
if ($homeDir = getenv('HOME')) {
return $homeDir;
}
// Get the HOMEDRIVE and HOMEPATH values for Windows hosts
$homeDrive = getenv('HOMEDRIVE');
$homePath = getenv('HOMEPATH');
return ($homeDrive && $homePath) ? $homeDrive . $homePath : null;
}
private static function reject($msg)
{
return new Promise\RejectedPromise(new CredentialsException($msg));
}
}
|