PluginProbe
Media Cloud Sync / 1.2.13
Media Cloud Sync v1.2.13
1.4.2 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 All 36 releases
media-cloud-sync / includes / sdk / s3 / Aws / Token / TokenProvider.php

TokenProvider.php in Media Cloud Sync 1.2.13, at includes/sdk/s3/Aws/Token/TokenProvider.php

212 lines 7.9 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\Token;
4
5 use Dudlewebs\WPMCS\s3\Aws;
6 use Dudlewebs\WPMCS\s3\Aws\Api\DateTimeResult;
7 use Dudlewebs\WPMCS\s3\Aws\CacheInterface;
8 use Dudlewebs\WPMCS\s3\Aws\Exception\TokenException;
9 use Dudlewebs\WPMCS\s3\GuzzleHttp\Promise;
10 /**
11 * Token providers are functions that accept no arguments and return a
12 * promise that is fulfilled with an {@see \Aws\Token\TokenInterface}
13 * or rejected with an {@see \Aws\Exception\TokenException}.
14 *
15 * <code>
16 * use Aws\Token\TokenProvider;
17 * $provider = TokenProvider::defaultProvider();
18 * // Returns a TokenInterface or throws.
19 * $token = $provider()->wait();
20 * </code>
21 *
22 * Token providers can be composed to create a token using conditional
23 * logic that can create different tokens in different environments. You
24 * can compose multiple providers into a single provider using
25 * {@see Aws\Token\TokenProvider::chain}. This function accepts
26 * providers as variadic arguments and returns a new function that will invoke
27 * each provider until a token is successfully returned.
28 */
29 class TokenProvider
30 {
31 use ParsesIniTrait;
32 const ENV_PROFILE = 'AWS_PROFILE';
33 /**
34 * Create a default token provider tha checks for cached a SSO token from
35 * the CLI
36 *
37 * This provider is automatically wrapped in a memoize function that caches
38 * previously provided tokens.
39 *
40 * @param array $config Optional array of token provider options.
41 *
42 * @return callable
43 */
44 public static function defaultProvider(array $config = [])
45 {
46 $cacheable = ['sso'];
47 $defaultChain = [];
48 if (!isset($config['use_aws_shared_config_files']) || $config['use_aws_shared_config_files'] !== \false) {
49 $profileName = \getenv(self::ENV_PROFILE) ?: 'default';
50 $defaultChain['sso'] = self::sso($profileName, self::getHomeDir() . '/.aws/config', $config);
51 }
52 if (isset($config['token']) && $config['token'] instanceof CacheInterface) {
53 foreach ($cacheable as $provider) {
54 if (isset($defaultChain[$provider])) {
55 $defaultChain[$provider] = self::cache($defaultChain[$provider], $config['token'], 'aws_cached_' . $provider . '_token');
56 }
57 }
58 }
59 return self::memoize(\call_user_func_array([TokenProvider::class, 'chain'], \array_values($defaultChain)));
60 }
61 /**
62 * Create a token provider function from a static token.
63 *
64 * @param TokenInterface $token
65 *
66 * @return callable
67 */
68 public static function fromToken(TokenInterface $token)
69 {
70 $promise = Promise\Create::promiseFor($token);
71 return function () use($promise) {
72 return $promise;
73 };
74 }
75 /**
76 * Creates an aggregate token provider that invokes the provided
77 * variadic providers one after the other until a provider returns
78 * a token.
79 *
80 * @return callable
81 */
82 public static function chain()
83 {
84 $links = \func_get_args();
85 //Common use case for when aws_shared_config_files is false
86 if (empty($links)) {
87 return function () {
88 return Promise\Create::promiseFor(\false);
89 };
90 }
91 return function () use($links) {
92 /** @var callable $parent */
93 $parent = \array_shift($links);
94 $promise = $parent();
95 while ($next = \array_shift($links)) {
96 $promise = $promise->otherwise($next);
97 }
98 return $promise;
99 };
100 }
101 /**
102 * Wraps a token provider and caches a previously provided token.
103 * Ensures that cached tokens are refreshed when they expire.
104 *
105 * @param callable $provider Token provider function to wrap.
106 * @return callable
107 */
108 public static function memoize(callable $provider)
109 {
110 return function () use($provider) {
111 static $result;
112 static $isConstant;
113 // Constant tokens will be returned constantly.
114 if ($isConstant) {
115 return $result;
116 }
117 // Create the initial promise that will be used as the cached value
118 // until it expires.
119 if (null === $result) {
120 $result = $provider();
121 }
122 // Return a token that could expire and refresh when needed.
123 return $result->then(function (TokenInterface $token) use($provider, &$isConstant, &$result) {
124 // Determine if the token is constant.
125 if (!$token->getExpiration()) {
126 $isConstant = \true;
127 return $token;
128 }
129 if (!$token->isExpired()) {
130 return $token;
131 }
132 return $result = $provider();
133 })->otherwise(function ($reason) use(&$result) {
134 // Cleanup rejected promise.
135 $result = null;
136 return Promise\Create::promiseFor(null);
137 });
138 };
139 }
140 /**
141 * Wraps a token provider and saves provided token in an
142 * instance of Aws\CacheInterface. Forwards calls when no token found
143 * in cache and updates cache with the results.
144 *
145 * @param callable $provider Token provider function to wrap
146 * @param CacheInterface $cache Cache to store the token
147 * @param string|null $cacheKey (optional) Cache key to use
148 *
149 * @return callable
150 */
151 public static function cache(callable $provider, CacheInterface $cache, $cacheKey = null)
152 {
153 $cacheKey = $cacheKey ?: 'aws_cached_token';
154 return function () use($provider, $cache, $cacheKey) {
155 $found = $cache->get($cacheKey);
156 if (\is_array($found) && isset($found['token'])) {
157 $foundToken = $found['token'];
158 if ($foundToken instanceof TokenInterface) {
159 if (!$foundToken->isExpired()) {
160 return Promise\Create::promiseFor($foundToken);
161 }
162 if (isset($found['refreshMethod']) && \is_callable($found['refreshMethod'])) {
163 return Promise\Create::promiseFor($found['refreshMethod']());
164 }
165 }
166 }
167 return $provider()->then(function (TokenInterface $token) use($cache, $cacheKey) {
168 $cache->set($cacheKey, $token, null === $token->getExpiration() ? 0 : $token->getExpiration() - \time());
169 return $token;
170 });
171 };
172 }
173 /**
174 * Gets profiles from the ~/.aws/config ini file
175 */
176 private static function loadDefaultProfiles()
177 {
178 $profiles = [];
179 $configFile = self::getHomeDir() . '/.aws/config';
180 if (\file_exists($configFile)) {
181 $configProfileData = \Dudlewebs\WPMCS\s3\Aws\parse_ini_file($configFile, \true, \INI_SCANNER_RAW);
182 foreach ($configProfileData as $name => $profile) {
183 // standardize config profile names
184 $name = \str_replace('profile ', '', $name);
185 if (!isset($profiles[$name])) {
186 $profiles[$name] = $profile;
187 }
188 }
189 }
190 return $profiles;
191 }
192 private static function reject($msg)
193 {
194 return new Promise\RejectedPromise(new TokenException($msg));
195 }
196 /**
197 * Token provider that creates a token from cached sso credentials
198 *
199 * @param string $profileName the name of the ini profile name
200 * @param string $filename the location of the ini file
201 * @param array $config configuration options
202 *
203 * @return SsoTokenProvider
204 * @see Aws\Token\SsoTokenProvider for $config details.
205 */
206 public static function sso($profileName, $filename, $config = [])
207 {
208 $ssoClient = isset($config['ssoClient']) ? $config['ssoClient'] : null;
209 return new SsoTokenProvider($profileName, $filename, $ssoClient);
210 }
211 }
212