1 <?php
2
3 namespace PayPal\Auth;
4
5 use PayPal\Cache\AuthorizationCache;
6 use PayPal\Common\PayPalResourceModel;
7 use PayPal\Core\PayPalHttpConfig;
8 use PayPal\Core\PayPalHttpConnection;
9 use PayPal\Core\PayPalLoggingManager;
10 use PayPal\Exception\PayPalConfigurationException;
11 use PayPal\Exception\PayPalConnectionException;
12 use PayPal\Handler\IPayPalHandler;
13 use PayPal\Rest\ApiContext;
14 use PayPal\Security\Cipher;
15
16 17 18
19 class OAuthTokenCredential extends PayPalResourceModel
20 {
21
22 public static $CACHE_PATH = '/../../../var/auth.cache';
23
24 25 26
27 public static $AUTH_HANDLER = 'PayPal\Handler\OauthHandler';
28
29 30 31 32 33
34 public static $expiryBufferTime = 120;
35
36 37 38 39 40
41 private $clientId;
42
43 44 45 46 47
48 private $clientSecret;
49
50 51 52 53 54
55 private $accessToken;
56
57 58 59 60 61
62 private $tokenExpiresIn;
63
64 65 66 67 68
69 private $tokenCreateTime;
70
71 72 73 74 75
76 private $cipher;
77
78 79 80 81 82 83
84 public function __construct($clientId, $clientSecret)
85 {
86 $this->clientId = $clientId;
87 $this->clientSecret = $clientSecret;
88 $this->cipher = new Cipher($this->clientSecret);
89 }
90
91 92 93 94 95
96 public function getClientId()
97 {
98 return $this->clientId;
99 }
100
101 102 103 104 105
106 public function getClientSecret()
107 {
108 return $this->clientSecret;
109 }
110
111 112 113 114 115 116 117
118 public function getAccessToken($config)
119 {
120
121 if ($this->accessToken && (time() - $this->tokenCreateTime) < ($this->tokenExpiresIn - self::$expiryBufferTime)) {
122 return $this->accessToken;
123 }
124
125 $token = AuthorizationCache::pull($config, $this->clientId);
126 if ($token) {
127
128
129 if (array_key_exists('accessToken', $token)) {
130 $this->accessToken = $token['accessToken'];
131 }
132
133 $this->tokenCreateTime = $token['tokenCreateTime'];
134 $this->tokenExpiresIn = $token['tokenExpiresIn'];
135
136
137 if (!array_key_exists('accessTokenEncrypted', $token)) {
138 AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn);
139 } else {
140 $this->accessToken = $this->decrypt($token['accessTokenEncrypted']);
141 }
142 }
143
144
145
146
147
148
149 if (
150 $this->accessToken != null &&
151 (time() - $this->tokenCreateTime) > ($this->tokenExpiresIn - self::$expiryBufferTime)
152 ) {
153 $this->accessToken = null;
154 }
155
156
157
158 if ($this->accessToken == null) {
159
160 $this->updateAccessToken($config);
161 AuthorizationCache::push($config, $this->clientId, $this->encrypt($this->accessToken), $this->tokenCreateTime, $this->tokenExpiresIn);
162 }
163
164 return $this->accessToken;
165 }
166
167
168 169 170 171 172 173 174 175
176 public function getRefreshToken($config, $authorizationCode = null, $params = array())
177 {
178 static $allowedParams = array(
179 'grant_type' => 'authorization_code',
180 'code' => 1,
181 'redirect_uri' => 'urn:ietf:wg:oauth:2.0:oob',
182 'response_type' => 'token'
183 );
184
185 $params = is_array($params) ? $params : array();
186 if ($authorizationCode) {
187
188 $params['code'] = $authorizationCode;
189 }
190 $payload = http_build_query(array_merge($allowedParams, array_intersect_key($params, $allowedParams)));
191
192 $response = $this->getToken($config, $this->clientId, $this->clientSecret, $payload);
193
194 if ($response != null && isset($response["refresh_token"])) {
195 return $response['refresh_token'];
196 }
197
198 return null;
199 }
200
201 202 203 204 205 206 207
208 public function updateAccessToken($config, $refreshToken = null)
209 {
210 $this->generateAccessToken($config, $refreshToken);
211 return $this->accessToken;
212 }
213
214 215 216 217 218 219 220 221 222 223 224
225 protected function getToken($config, $clientId, $clientSecret, $payload)
226 {
227 $httpConfig = new PayPalHttpConfig(null, 'POST', $config);
228
229
230 if (!empty($config['http.Proxy'])) {
231 $httpConfig->setHttpProxy($config['http.Proxy']);
232 }
233
234 $handlers = array(self::$AUTH_HANDLER);
235
236
237 foreach ($handlers as $handler) {
238 if (!is_object($handler)) {
239 $fullHandler = "\\" . (string)$handler;
240 $handler = new $fullHandler(new ApiContext($this));
241 }
242 $handler->handle($httpConfig, $payload, array('clientId' => $clientId, 'clientSecret' => $clientSecret));
243 }
244
245 $connection = new PayPalHttpConnection($httpConfig, $config);
246 $res = $connection->execute($payload);
247 $response = json_decode($res, true);
248
249 return $response;
250 }
251
252
253 254 255 256 257 258 259 260
261 private function generateAccessToken($config, $refreshToken = null)
262 {
263 $params = array('grant_type' => 'client_credentials');
264 if ($refreshToken != null) {
265
266
267 $params['grant_type'] = 'refresh_token';
268 $params['refresh_token'] = $refreshToken;
269 }
270 $payload = http_build_query($params);
271 $response = $this->getToken($config, $this->clientId, $this->clientSecret, $payload);
272
273 if ($response == null || !isset($response["access_token"]) || !isset($response["expires_in"])) {
274 $this->accessToken = null;
275 $this->tokenExpiresIn = null;
276 PayPalLoggingManager::getInstance(__CLASS__)->warning("Could not generate new Access token. Invalid response from server: ");
277 throw new PayPalConnectionException(null, "Could not generate new Access token. Invalid response from server: ");
278 } else {
279 $this->accessToken = $response["access_token"];
280 $this->tokenExpiresIn = $response["expires_in"];
281 }
282 $this->tokenCreateTime = time();
283
284 return $this->accessToken;
285 }
286
287 288 289 290 291 292
293 public function encrypt($data)
294 {
295 return $this->cipher->encrypt($data);
296 }
297
298 299 300 301 302 303
304 public function decrypt($data)
305 {
306 return $this->cipher->decrypt($data);
307 }
308 }
309