| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 | 
							- <?php
 
- namespace Aws\Credentials;
 
- use Aws\Exception\AwsException;
 
- use Aws\Exception\CredentialsException;
 
- use Aws\Result;
 
- use Aws\Sts\StsClient;
 
- use GuzzleHttp\Promise;
 
- /**
 
-  * Credential provider that provides credentials via assuming a role with a web identity
 
-  * More Information, see: https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sts-2011-06-15.html#assumerolewithwebidentity
 
-  */
 
- class AssumeRoleWithWebIdentityCredentialProvider
 
- {
 
-     const ERROR_MSG = "Missing required 'AssumeRoleWithWebIdentityCredentialProvider' configuration option: ";
 
-     const ENV_RETRIES = 'AWS_METADATA_SERVICE_NUM_ATTEMPTS';
 
-     /** @var string */
 
-     private $tokenFile;
 
-     /** @var string */
 
-     private $arn;
 
-     /** @var string */
 
-     private $session;
 
-     /** @var StsClient */
 
-     private $client;
 
-     /** @var integer */
 
-     private $retries;
 
-     /** @var integer */
 
-     private $authenticationAttempts;
 
-     /** @var integer */
 
-     private $tokenFileReadAttempts;
 
-     /**
 
-      * The constructor attempts to load config from environment variables.
 
-      * If not set, the following config options are used:
 
-      *  - WebIdentityTokenFile: full path of token filename
 
-      *  - RoleArn: arn of role to be assumed
 
-      *  - SessionName: (optional) set by SDK if not provided
 
-      *
 
-      * @param array $config Configuration options
 
-      * @throws \InvalidArgumentException
 
-      */
 
-     public function __construct(array $config = [])
 
-     {
 
-         if (!isset($config['RoleArn'])) {
 
-             throw new \InvalidArgumentException(self::ERROR_MSG . "'RoleArn'.");
 
-         }
 
-         $this->arn = $config['RoleArn'];
 
-         if (!isset($config['WebIdentityTokenFile'])) {
 
-             throw new \InvalidArgumentException(self::ERROR_MSG . "'WebIdentityTokenFile'.");
 
-         }
 
-         $this->tokenFile = $config['WebIdentityTokenFile'];
 
-         if (!preg_match("/^\w\:|^\/|^\\\/", $this->tokenFile)) {
 
-             throw new \InvalidArgumentException("'WebIdentityTokenFile' must be an absolute path.");
 
-         }
 
-         $this->retries = (int) getenv(self::ENV_RETRIES) ?: (isset($config['retries']) ? $config['retries'] : 3);
 
-         $this->authenticationAttempts = 0;
 
-         $this->tokenFileReadAttempts = 0;
 
-         $this->session = isset($config['SessionName'])
 
-             ? $config['SessionName']
 
-             : 'aws-sdk-php-' . round(microtime(true) * 1000);
 
-         $region = isset($config['region'])
 
-             ? $config['region']
 
-             : 'us-east-1';
 
-         if (isset($config['client'])) {
 
-             $this->client = $config['client'];
 
-         } else {
 
-             $this->client = new StsClient([
 
-                 'credentials' => false,
 
-                 'region' => $region,
 
-                 'version' => 'latest'
 
-             ]);
 
-         }
 
-     }
 
-     /**
 
-      * Loads assume role with web identity credentials.
 
-      *
 
-      * @return Promise\PromiseInterface
 
-      */
 
-     public function __invoke()
 
-     {
 
-         return Promise\Coroutine::of(function () {
 
-             $client = $this->client;
 
-             $result = null;
 
-             while ($result == null) {
 
-                 try {
 
-                     $token = @file_get_contents($this->tokenFile);
 
-                     if (false === $token) {
 
-                         clearstatcache(true, dirname($this->tokenFile) . "/" . readlink($this->tokenFile));
 
-                         clearstatcache(true, dirname($this->tokenFile) . "/" . dirname(readlink($this->tokenFile)));
 
-                         clearstatcache(true, $this->tokenFile);
 
-                         if (!@is_readable($this->tokenFile)) {
 
-                             throw new CredentialsException(
 
-                                 "Unreadable tokenfile at location {$this->tokenFile}"
 
-                             );
 
-                         }
 
-                         $token = @file_get_contents($this->tokenFile);
 
-                     }
 
-                     if (empty($token)) {
 
-                         if ($this->tokenFileReadAttempts < $this->retries) {
 
-                             sleep((int) pow(1.2, $this->tokenFileReadAttempts));
 
-                             $this->tokenFileReadAttempts++;
 
-                             continue;
 
-                         }
 
-                         throw new CredentialsException("InvalidIdentityToken from file: {$this->tokenFile}");
 
-                     }
 
-                 } catch (\Exception $exception) {
 
-                     throw new CredentialsException(
 
-                         "Error reading WebIdentityTokenFile from " . $this->tokenFile,
 
-                         0,
 
-                         $exception
 
-                     );
 
-                 }
 
-                 $assumeParams = [
 
-                     'RoleArn' => $this->arn,
 
-                     'RoleSessionName' => $this->session,
 
-                     'WebIdentityToken' => $token
 
-                 ];
 
-                 try {
 
-                     $result = $client->assumeRoleWithWebIdentity($assumeParams);
 
-                 } catch (AwsException $e) {
 
-                     if ($e->getAwsErrorCode() == 'InvalidIdentityToken') {
 
-                         if ($this->authenticationAttempts < $this->retries) {
 
-                             sleep((int) pow(1.2, $this->authenticationAttempts));
 
-                         } else {
 
-                             throw new CredentialsException(
 
-                                 "InvalidIdentityToken, retries exhausted"
 
-                             );
 
-                         }
 
-                     } else {
 
-                         throw new CredentialsException(
 
-                             "Error assuming role from web identity credentials",
 
-                             0,
 
-                             $e
 
-                         );
 
-                     }
 
-                 } catch (\Exception $e) {
 
-                     throw new CredentialsException(
 
-                         "Error retrieving web identity credentials: " . $e->getMessage()
 
-                         . " (" . $e->getCode() . ")"
 
-                     );
 
-                 }
 
-                 $this->authenticationAttempts++;
 
-             }
 
-             yield $this->client->createCredentials($result);
 
-         });
 
-     }
 
- }
 
 
  |