PluginProbe
Authorizer / 3.8.3
Authorizer v3.8.3
3.15.3 3.15.2 3.15.1 3.15.0 3.14.3 3.14.4 3.14.2 3.14.1 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.9.0 2.9.1 2.9.10 2.9.11 2.9.12 2.9.13 2.9.2 2.9.3 2.9.6 All 126 releases
authorizer / vendor / google / auth / src / FetchAuthTokenCache.php

FetchAuthTokenCache.php in Authorizer 3.8.3, at vendor/google/auth/src/FetchAuthTokenCache.php

293 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Copyright 2010 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 namespace Google\Auth;
19
20 use Psr\Cache\CacheItemPoolInterface;
21
22 /**
23 * A class to implement caching for any object implementing
24 * FetchAuthTokenInterface
25 */
26 class FetchAuthTokenCache implements
27 FetchAuthTokenInterface,
28 GetQuotaProjectInterface,
29 SignBlobInterface,
30 ProjectIdProviderInterface,
31 UpdateMetadataInterface
32 {
33 use CacheTrait;
34
35 /**
36 * @var FetchAuthTokenInterface
37 */
38 private $fetcher;
39
40 /**
41 * @var int
42 */
43 private $eagerRefreshThresholdSeconds = 10;
44
45 /**
46 * @param FetchAuthTokenInterface $fetcher A credentials fetcher
47 * @param array<mixed> $cacheConfig Configuration for the cache
48 * @param CacheItemPoolInterface $cache
49 */
50 public function __construct(
51 FetchAuthTokenInterface $fetcher,
52 array $cacheConfig = null,
53 CacheItemPoolInterface $cache
54 ) {
55 $this->fetcher = $fetcher;
56 $this->cache = $cache;
57 $this->cacheConfig = array_merge([
58 'lifetime' => 1500,
59 'prefix' => '',
60 ], (array) $cacheConfig);
61 }
62
63 /**
64 * @return FetchAuthTokenInterface
65 */
66 public function getFetcher()
67 {
68 return $this->fetcher;
69 }
70
71 /**
72 * Implements FetchAuthTokenInterface#fetchAuthToken.
73 *
74 * Checks the cache for a valid auth token and fetches the auth tokens
75 * from the supplied fetcher.
76 *
77 * @param callable $httpHandler callback which delivers psr7 request
78 * @return array<mixed> the response
79 * @throws \Exception
80 */
81 public function fetchAuthToken(callable $httpHandler = null)
82 {
83 if ($cached = $this->fetchAuthTokenFromCache()) {
84 return $cached;
85 }
86
87 $auth_token = $this->fetcher->fetchAuthToken($httpHandler);
88
89 $this->saveAuthTokenInCache($auth_token);
90
91 return $auth_token;
92 }
93
94 /**
95 * @return string
96 */
97 public function getCacheKey()
98 {
99 return $this->getFullCacheKey($this->fetcher->getCacheKey());
100 }
101
102 /**
103 * @return array<mixed>|null
104 */
105 public function getLastReceivedToken()
106 {
107 return $this->fetcher->getLastReceivedToken();
108 }
109
110 /**
111 * Get the client name from the fetcher.
112 *
113 * @param callable $httpHandler An HTTP handler to deliver PSR7 requests.
114 * @return string
115 */
116 public function getClientName(callable $httpHandler = null)
117 {
118 if (!$this->fetcher instanceof SignBlobInterface) {
119 throw new \RuntimeException(
120 'Credentials fetcher does not implement ' .
121 'Google\Auth\SignBlobInterface'
122 );
123 }
124
125 return $this->fetcher->getClientName($httpHandler);
126 }
127
128 /**
129 * Sign a blob using the fetcher.
130 *
131 * @param string $stringToSign The string to sign.
132 * @param bool $forceOpenSsl Require use of OpenSSL for local signing. Does
133 * not apply to signing done using external services. **Defaults to**
134 * `false`.
135 * @return string The resulting signature.
136 * @throws \RuntimeException If the fetcher does not implement
137 * `Google\Auth\SignBlobInterface`.
138 */
139 public function signBlob($stringToSign, $forceOpenSsl = false)
140 {
141 if (!$this->fetcher instanceof SignBlobInterface) {
142 throw new \RuntimeException(
143 'Credentials fetcher does not implement ' .
144 'Google\Auth\SignBlobInterface'
145 );
146 }
147
148 // Pass the access token from cache to GCECredentials for signing a blob.
149 // This saves a call to the metadata server when a cached token exists.
150 if ($this->fetcher instanceof Credentials\GCECredentials) {
151 $cached = $this->fetchAuthTokenFromCache();
152 $accessToken = isset($cached['access_token']) ? $cached['access_token'] : null;
153 return $this->fetcher->signBlob($stringToSign, $forceOpenSsl, $accessToken);
154 }
155
156 return $this->fetcher->signBlob($stringToSign, $forceOpenSsl);
157 }
158
159 /**
160 * Get the quota project used for this API request from the credentials
161 * fetcher.
162 *
163 * @return string|null
164 */
165 public function getQuotaProject()
166 {
167 if ($this->fetcher instanceof GetQuotaProjectInterface) {
168 return $this->fetcher->getQuotaProject();
169 }
170
171 return null;
172 }
173
174 /*
175 * Get the Project ID from the fetcher.
176 *
177 * @param callable $httpHandler Callback which delivers psr7 request
178 * @return string|null
179 * @throws \RuntimeException If the fetcher does not implement
180 * `Google\Auth\ProvidesProjectIdInterface`.
181 */
182 public function getProjectId(callable $httpHandler = null)
183 {
184 if (!$this->fetcher instanceof ProjectIdProviderInterface) {
185 throw new \RuntimeException(
186 'Credentials fetcher does not implement ' .
187 'Google\Auth\ProvidesProjectIdInterface'
188 );
189 }
190
191 return $this->fetcher->getProjectId($httpHandler);
192 }
193
194 /**
195 * Updates metadata with the authorization token.
196 *
197 * @param array<mixed> $metadata metadata hashmap
198 * @param string $authUri optional auth uri
199 * @param callable $httpHandler callback which delivers psr7 request
200 * @return array<mixed> updated metadata hashmap
201 * @throws \RuntimeException If the fetcher does not implement
202 * `Google\Auth\UpdateMetadataInterface`.
203 */
204 public function updateMetadata(
205 $metadata,
206 $authUri = null,
207 callable $httpHandler = null
208 ) {
209 if (!$this->fetcher instanceof UpdateMetadataInterface) {
210 throw new \RuntimeException(
211 'Credentials fetcher does not implement ' .
212 'Google\Auth\UpdateMetadataInterface'
213 );
214 }
215
216 $cached = $this->fetchAuthTokenFromCache($authUri);
217 if ($cached) {
218 // Set the access token in the `Authorization` metadata header so
219 // the downstream call to updateMetadata know they don't need to
220 // fetch another token.
221 if (isset($cached['access_token'])) {
222 $metadata[self::AUTH_METADATA_KEY] = [
223 'Bearer ' . $cached['access_token']
224 ];
225 }
226 }
227
228 $newMetadata = $this->fetcher->updateMetadata(
229 $metadata,
230 $authUri,
231 $httpHandler
232 );
233
234 if (!$cached && $token = $this->fetcher->getLastReceivedToken()) {
235 $this->saveAuthTokenInCache($token, $authUri);
236 }
237
238 return $newMetadata;
239 }
240
241 /**
242 * @param string|null $authUri
243 * @return array<mixed>|null
244 */
245 private function fetchAuthTokenFromCache($authUri = null)
246 {
247 // Use the cached value if its available.
248 //
249 // TODO: correct caching; update the call to setCachedValue to set the expiry
250 // to the value returned with the auth token.
251 //
252 // TODO: correct caching; enable the cache to be cleared.
253
254 // if $authUri is set, use it as the cache key
255 $cacheKey = $authUri
256 ? $this->getFullCacheKey($authUri)
257 : $this->fetcher->getCacheKey();
258
259 $cached = $this->getCachedValue($cacheKey);
260 if (is_array($cached)) {
261 if (empty($cached['expires_at'])) {
262 // If there is no expiration data, assume token is not expired.
263 // (for JwtAccess and ID tokens)
264 return $cached;
265 }
266 if ((time() + $this->eagerRefreshThresholdSeconds) < $cached['expires_at']) {
267 // access token is not expired
268 return $cached;
269 }
270 }
271
272 return null;
273 }
274
275 /**
276 * @param array<mixed> $authToken
277 * @param string|null $authUri
278 * @return void
279 */
280 private function saveAuthTokenInCache($authToken, $authUri = null)
281 {
282 if (isset($authToken['access_token']) ||
283 isset($authToken['id_token'])) {
284 // if $authUri is set, use it as the cache key
285 $cacheKey = $authUri
286 ? $this->getFullCacheKey($authUri)
287 : $this->fetcher->getCacheKey();
288
289 $this->setCachedValue($cacheKey, $authToken);
290 }
291 }
292 }
293