PluginProbe
Authorizer / 3.5.0
Authorizer v3.5.0
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.5.0, at vendor/google/auth/src/FetchAuthTokenCache.php

285 lines 8.6 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 * Implements FetchAuthTokenInterface#fetchAuthToken.
65 *
66 * Checks the cache for a valid auth token and fetches the auth tokens
67 * from the supplied fetcher.
68 *
69 * @param callable $httpHandler callback which delivers psr7 request
70 * @return array<mixed> the response
71 * @throws \Exception
72 */
73 public function fetchAuthToken(callable $httpHandler = null)
74 {
75 if ($cached = $this->fetchAuthTokenFromCache()) {
76 return $cached;
77 }
78
79 $auth_token = $this->fetcher->fetchAuthToken($httpHandler);
80
81 $this->saveAuthTokenInCache($auth_token);
82
83 return $auth_token;
84 }
85
86 /**
87 * @return string
88 */
89 public function getCacheKey()
90 {
91 return $this->getFullCacheKey($this->fetcher->getCacheKey());
92 }
93
94 /**
95 * @return array<mixed>|null
96 */
97 public function getLastReceivedToken()
98 {
99 return $this->fetcher->getLastReceivedToken();
100 }
101
102 /**
103 * Get the client name from the fetcher.
104 *
105 * @param callable $httpHandler An HTTP handler to deliver PSR7 requests.
106 * @return string
107 */
108 public function getClientName(callable $httpHandler = null)
109 {
110 if (!$this->fetcher instanceof SignBlobInterface) {
111 throw new \RuntimeException(
112 'Credentials fetcher does not implement ' .
113 'Google\Auth\SignBlobInterface'
114 );
115 }
116
117 return $this->fetcher->getClientName($httpHandler);
118 }
119
120 /**
121 * Sign a blob using the fetcher.
122 *
123 * @param string $stringToSign The string to sign.
124 * @param bool $forceOpenSsl Require use of OpenSSL for local signing. Does
125 * not apply to signing done using external services. **Defaults to**
126 * `false`.
127 * @return string The resulting signature.
128 * @throws \RuntimeException If the fetcher does not implement
129 * `Google\Auth\SignBlobInterface`.
130 */
131 public function signBlob($stringToSign, $forceOpenSsl = false)
132 {
133 if (!$this->fetcher instanceof SignBlobInterface) {
134 throw new \RuntimeException(
135 'Credentials fetcher does not implement ' .
136 'Google\Auth\SignBlobInterface'
137 );
138 }
139
140 // Pass the access token from cache to GCECredentials for signing a blob.
141 // This saves a call to the metadata server when a cached token exists.
142 if ($this->fetcher instanceof Credentials\GCECredentials) {
143 $cached = $this->fetchAuthTokenFromCache();
144 $accessToken = isset($cached['access_token']) ? $cached['access_token'] : null;
145 return $this->fetcher->signBlob($stringToSign, $forceOpenSsl, $accessToken);
146 }
147
148 return $this->fetcher->signBlob($stringToSign, $forceOpenSsl);
149 }
150
151 /**
152 * Get the quota project used for this API request from the credentials
153 * fetcher.
154 *
155 * @return string|null
156 */
157 public function getQuotaProject()
158 {
159 if ($this->fetcher instanceof GetQuotaProjectInterface) {
160 return $this->fetcher->getQuotaProject();
161 }
162
163 return null;
164 }
165
166 /*
167 * Get the Project ID from the fetcher.
168 *
169 * @param callable $httpHandler Callback which delivers psr7 request
170 * @return string|null
171 * @throws \RuntimeException If the fetcher does not implement
172 * `Google\Auth\ProvidesProjectIdInterface`.
173 */
174 public function getProjectId(callable $httpHandler = null)
175 {
176 if (!$this->fetcher instanceof ProjectIdProviderInterface) {
177 throw new \RuntimeException(
178 'Credentials fetcher does not implement ' .
179 'Google\Auth\ProvidesProjectIdInterface'
180 );
181 }
182
183 return $this->fetcher->getProjectId($httpHandler);
184 }
185
186 /**
187 * Updates metadata with the authorization token.
188 *
189 * @param array<mixed> $metadata metadata hashmap
190 * @param string $authUri optional auth uri
191 * @param callable $httpHandler callback which delivers psr7 request
192 * @return array<mixed> updated metadata hashmap
193 * @throws \RuntimeException If the fetcher does not implement
194 * `Google\Auth\UpdateMetadataInterface`.
195 */
196 public function updateMetadata(
197 $metadata,
198 $authUri = null,
199 callable $httpHandler = null
200 ) {
201 if (!$this->fetcher instanceof UpdateMetadataInterface) {
202 throw new \RuntimeException(
203 'Credentials fetcher does not implement ' .
204 'Google\Auth\UpdateMetadataInterface'
205 );
206 }
207
208 $cached = $this->fetchAuthTokenFromCache($authUri);
209 if ($cached) {
210 // Set the access token in the `Authorization` metadata header so
211 // the downstream call to updateMetadata know they don't need to
212 // fetch another token.
213 if (isset($cached['access_token'])) {
214 $metadata[self::AUTH_METADATA_KEY] = [
215 'Bearer ' . $cached['access_token']
216 ];
217 }
218 }
219
220 $newMetadata = $this->fetcher->updateMetadata(
221 $metadata,
222 $authUri,
223 $httpHandler
224 );
225
226 if (!$cached && $token = $this->fetcher->getLastReceivedToken()) {
227 $this->saveAuthTokenInCache($token, $authUri);
228 }
229
230 return $newMetadata;
231 }
232
233 /**
234 * @param string|null $authUri
235 * @return array<mixed>|null
236 */
237 private function fetchAuthTokenFromCache($authUri = null)
238 {
239 // Use the cached value if its available.
240 //
241 // TODO: correct caching; update the call to setCachedValue to set the expiry
242 // to the value returned with the auth token.
243 //
244 // TODO: correct caching; enable the cache to be cleared.
245
246 // if $authUri is set, use it as the cache key
247 $cacheKey = $authUri
248 ? $this->getFullCacheKey($authUri)
249 : $this->fetcher->getCacheKey();
250
251 $cached = $this->getCachedValue($cacheKey);
252 if (is_array($cached)) {
253 if (empty($cached['expires_at'])) {
254 // If there is no expiration data, assume token is not expired.
255 // (for JwtAccess and ID tokens)
256 return $cached;
257 }
258 if ((time() + $this->eagerRefreshThresholdSeconds) < $cached['expires_at']) {
259 // access token is not expired
260 return $cached;
261 }
262 }
263
264 return null;
265 }
266
267 /**
268 * @param array<mixed> $authToken
269 * @param string|null $authUri
270 * @return void
271 */
272 private function saveAuthTokenInCache($authToken, $authUri = null)
273 {
274 if (isset($authToken['access_token']) ||
275 isset($authToken['id_token'])) {
276 // if $authUri is set, use it as the cache key
277 $cacheKey = $authUri
278 ? $this->getFullCacheKey($authUri)
279 : $this->fetcher->getCacheKey();
280
281 $this->setCachedValue($cacheKey, $authToken);
282 }
283 }
284 }
285