PluginProbe
Media Cloud Sync / 1.2.9
Media Cloud Sync v1.2.9
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
media-cloud-sync / includes / sdk / s3 / Aws / Credentials / AssumeRoleWithWebIdentityCredentialProvider.php

AssumeRoleWithWebIdentityCredentialProvider.php in Media Cloud Sync 1.2.9, at includes/sdk/s3/Aws/Credentials/AssumeRoleWithWebIdentityCredentialProvider.php

121 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS\s3\Aws\Credentials;
4
5 use Dudlewebs\WPMCS\s3\Aws\Exception\AwsException;
6 use Dudlewebs\WPMCS\s3\Aws\Exception\CredentialsException;
7 use Dudlewebs\WPMCS\s3\Aws\Result;
8 use Dudlewebs\WPMCS\s3\Aws\Sts\StsClient;
9 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise;
10 /**
11 * Credential provider that provides credentials via assuming a role with a web identity
12 * More Information, see: https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sts-2011-06-15.html#assumerolewithwebidentity
13 */
14 class AssumeRoleWithWebIdentityCredentialProvider
15 {
16 const ERROR_MSG = "Missing required 'AssumeRoleWithWebIdentityCredentialProvider' configuration option: ";
17 const ENV_RETRIES = 'AWS_METADATA_SERVICE_NUM_ATTEMPTS';
18 /** @var string */
19 private $tokenFile;
20 /** @var string */
21 private $arn;
22 /** @var string */
23 private $session;
24 /** @var StsClient */
25 private $client;
26 /** @var integer */
27 private $retries;
28 /** @var integer */
29 private $authenticationAttempts;
30 /** @var integer */
31 private $tokenFileReadAttempts;
32 /**
33 * The constructor attempts to load config from environment variables.
34 * If not set, the following config options are used:
35 * - WebIdentityTokenFile: full path of token filename
36 * - RoleArn: arn of role to be assumed
37 * - SessionName: (optional) set by SDK if not provided
38 *
39 * @param array $config Configuration options
40 * @throws \InvalidArgumentException
41 */
42 public function __construct(array $config = [])
43 {
44 if (!isset($config['RoleArn'])) {
45 throw new \InvalidArgumentException(self::ERROR_MSG . "'RoleArn'.");
46 }
47 $this->arn = $config['RoleArn'];
48 if (!isset($config['WebIdentityTokenFile'])) {
49 throw new \InvalidArgumentException(self::ERROR_MSG . "'WebIdentityTokenFile'.");
50 }
51 $this->tokenFile = $config['WebIdentityTokenFile'];
52 if (!\preg_match("/^\\w\\:|^\\/|^\\\\/", $this->tokenFile)) {
53 throw new \InvalidArgumentException("'WebIdentityTokenFile' must be an absolute path.");
54 }
55 $this->retries = (int) \getenv(self::ENV_RETRIES) ?: (isset($config['retries']) ? $config['retries'] : 3);
56 $this->authenticationAttempts = 0;
57 $this->tokenFileReadAttempts = 0;
58 $this->session = isset($config['SessionName']) ? $config['SessionName'] : 'aws-sdk-php-' . \round(\microtime(\true) * 1000);
59 $region = isset($config['region']) ? $config['region'] : 'us-east-1';
60 if (isset($config['client'])) {
61 $this->client = $config['client'];
62 } else {
63 $this->client = new StsClient(['credentials' => \false, 'region' => $region, 'version' => 'latest']);
64 }
65 }
66 /**
67 * Loads assume role with web identity credentials.
68 *
69 * @return Promise\PromiseInterface
70 */
71 public function __invoke()
72 {
73 return Promise\Coroutine::of(function () {
74 $client = $this->client;
75 $result = null;
76 while ($result == null) {
77 try {
78 $token = @\file_get_contents($this->tokenFile);
79 if (\false === $token) {
80 \clearstatcache(\true, \dirname($this->tokenFile) . "/" . \readlink($this->tokenFile));
81 \clearstatcache(\true, \dirname($this->tokenFile) . "/" . \dirname(\readlink($this->tokenFile)));
82 \clearstatcache(\true, $this->tokenFile);
83 if (!@\is_readable($this->tokenFile)) {
84 throw new CredentialsException("Unreadable tokenfile at location {$this->tokenFile}");
85 }
86 $token = @\file_get_contents($this->tokenFile);
87 }
88 if (empty($token)) {
89 if ($this->tokenFileReadAttempts < $this->retries) {
90 \sleep((int) \pow(1.2, $this->tokenFileReadAttempts));
91 $this->tokenFileReadAttempts++;
92 continue;
93 }
94 throw new CredentialsException("InvalidIdentityToken from file: {$this->tokenFile}");
95 }
96 } catch (\Exception $exception) {
97 throw new CredentialsException("Error reading WebIdentityTokenFile from " . $this->tokenFile, 0, $exception);
98 }
99 $assumeParams = ['RoleArn' => $this->arn, 'RoleSessionName' => $this->session, 'WebIdentityToken' => $token];
100 try {
101 $result = $client->assumeRoleWithWebIdentity($assumeParams);
102 } catch (AwsException $e) {
103 if ($e->getAwsErrorCode() == 'InvalidIdentityToken') {
104 if ($this->authenticationAttempts < $this->retries) {
105 \sleep((int) \pow(1.2, $this->authenticationAttempts));
106 } else {
107 throw new CredentialsException("InvalidIdentityToken, retries exhausted");
108 }
109 } else {
110 throw new CredentialsException("Error assuming role from web identity credentials", 0, $e);
111 }
112 } catch (\Exception $e) {
113 throw new CredentialsException("Error retrieving web identity credentials: " . $e->getMessage() . " (" . $e->getCode() . ")");
114 }
115 $this->authenticationAttempts++;
116 }
117 (yield $this->client->createCredentials($result));
118 });
119 }
120 }
121