PluginProbe
WP-Stateless – Google Cloud Storage / 2.1.4
WP-Stateless – Google Cloud Storage v2.1.4
4.4.3 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.3.0 2.3.1 2.3.2 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 All 62 releases
wp-stateless / lib / Google / vendor / google / auth / src / Credentials / GCECredentials.php

GCECredentials.php in WP-Stateless – Google Cloud Storage 2.1.4, at lib/Google/vendor/google/auth/src/Credentials/GCECredentials.php

198 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Copyright 2015 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\Credentials;
19
20 use Google\Auth\CredentialsLoader;
21 use Google\Auth\HttpHandler\HttpHandlerFactory;
22 use GuzzleHttp\Exception\ClientException;
23 use GuzzleHttp\Exception\RequestException;
24 use GuzzleHttp\Exception\ServerException;
25 use GuzzleHttp\Psr7\Request;
26
27 /**
28 * GCECredentials supports authorization on Google Compute Engine.
29 *
30 * It can be used to authorize requests using the AuthTokenMiddleware, but will
31 * only succeed if being run on GCE:
32 *
33 * use Google\Auth\Credentials\GCECredentials;
34 * use Google\Auth\Middleware\AuthTokenMiddleware;
35 * use GuzzleHttp\Client;
36 * use GuzzleHttp\HandlerStack;
37 *
38 * $gce = new GCECredentials();
39 * $middleware = new AuthTokenMiddleware($gce);
40 * $stack = HandlerStack::create();
41 * $stack->push($middleware);
42 *
43 * $client = new Client([
44 * 'handler' => $stack,
45 * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/',
46 * 'auth' => 'google_auth'
47 * ]);
48 *
49 * $res = $client->get('myproject/taskqueues/myqueue');
50 */
51 class GCECredentials extends CredentialsLoader
52 {
53 /**
54 * The metadata IP address on appengine instances.
55 *
56 * The IP is used instead of the domain 'metadata' to avoid slow responses
57 * when not on Compute Engine.
58 */
59 const METADATA_IP = '169.254.169.254';
60
61 /**
62 * The metadata path of the default token.
63 */
64 const TOKEN_URI_PATH = 'v1/instance/service-accounts/default/token';
65
66 /**
67 * The header whose presence indicates GCE presence.
68 */
69 const FLAVOR_HEADER = 'Metadata-Flavor';
70
71 /**
72 * Flag used to ensure that the onGCE test is only done once;
73 */
74 private $hasCheckedOnGce = false;
75
76 /**
77 * Flag that stores the value of the onGCE check.
78 */
79 private $isOnGce = false;
80
81 /**
82 * Result of fetchAuthToken
83 */
84 protected $lastReceivedToken;
85
86 /**
87 * The full uri for accessing the default token.
88 */
89 public static function getTokenUri()
90 {
91 $base = 'http://' . self::METADATA_IP . '/computeMetadata/';
92 return $base . self::TOKEN_URI_PATH;
93 }
94
95 /**
96 * Determines if this a GCE instance, by accessing the expected metadata
97 * host.
98 * If $httpHandler is not specified a the default HttpHandler is used.
99 *
100 * @param callable $httpHandler callback which delivers psr7 request
101 * @return true if this a GCEInstance false otherwise
102 */
103 public static function onGce(callable $httpHandler = null)
104 {
105 if (is_null($httpHandler)) {
106 $httpHandler = HttpHandlerFactory::build();
107 }
108 $checkUri = 'http://' . self::METADATA_IP;
109 try {
110 // Comment from: oauth2client/client.py
111 //
112 // Note: the explicit `timeout` below is a workaround. The underlying
113 // issue is that resolving an unknown host on some networks will take
114 // 20-30 seconds; making this timeout short fixes the issue, but
115 // could lead to false negatives in the event that we are on GCE, but
116 // the metadata resolution was particularly slow. The latter case is
117 // "unlikely".
118 $resp = $httpHandler(
119 new Request('GET', $checkUri),
120 ['timeout' => 0.3]
121 );
122 return $resp->getHeaderLine(self::FLAVOR_HEADER) == 'Google';
123 } catch (ClientException $e) {
124 return false;
125 } catch (ServerException $e) {
126 return false;
127 } catch (RequestException $e) {
128 return false;
129 }
130 }
131
132 /**
133 * Implements FetchAuthTokenInterface#fetchAuthToken.
134 *
135 * Fetches the auth tokens from the GCE metadata host if it is available.
136 * If $httpHandler is not specified a the default HttpHandler is used.
137 *
138 * @param callable $httpHandler callback which delivers psr7 request
139 * @return array the response
140 */
141 public function fetchAuthToken(callable $httpHandler = null)
142 {
143 if (is_null($httpHandler)) {
144 $httpHandler = HttpHandlerFactory::build();
145 }
146 if (!$this->hasCheckedOnGce) {
147 $this->isOnGce = self::onGce($httpHandler);
148 }
149 if (!$this->isOnGce) {
150 return array(); // return an empty array with no access token
151 }
152 $resp = $httpHandler(
153 new Request(
154 'GET',
155 self::getTokenUri(),
156 [self::FLAVOR_HEADER => 'Google']
157 )
158 );
159 $body = (string) $resp->getBody();
160
161 // Assume it's JSON; if it's not throw an exception
162 if (null === $json = json_decode($body, true)) {
163 throw new \Exception('Invalid JSON response');
164 }
165
166 // store this so we can retrieve it later
167 $this->lastReceivedToken = $json;
168 $this->lastReceivedToken['expires_at'] = time() + $json['expires_in'];
169
170 return $json;
171 }
172
173 /**
174 * Implements FetchAuthTokenInterface#getCacheKey.
175 *
176 * @return 'GOOGLE_AUTH_PHP_GCE'
177 */
178 public function getCacheKey()
179 {
180 return 'GOOGLE_AUTH_PHP_GCE';
181 }
182
183 /**
184 * Implements FetchAuthTokenInterface#getLastReceivedToken.
185 */
186 public function getLastReceivedToken()
187 {
188 if ($this->lastReceivedToken) {
189 return [
190 'access_token' => $this->lastReceivedToken['access_token'],
191 'expires_at' => $this->lastReceivedToken['expires_at'],
192 ];
193 }
194
195 return null;
196 }
197 }
198