1: <?php
2: namespace Genetsis\core;
3:
4: use Exception;
5: use Genetsis\Identity;
6: use Genetsis\core\InvalidGrantException;
7:
8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
18: class OAuth
19: {
20:
21: const GRANT_TYPE_AUTH_CODE = 'authorization_code';
22: const GRANT_TYPE_REFRESH_TOKEN = 'refresh_token';
23: const GRANT_TYPE_CLIENT_CREDENTIALS = 'client_credentials';
24: const GRANT_TYPE_VALIDATE_BEARER = 'urn:es.cocacola:oauth2:grant_type:validate_bearer';
25: const GRANT_TYPE_EXCHANGE_SESSION = 'urn:es.cocacola:oauth2:grant_type:exchange_session';
26:
27: const DEFAULT_EXPIRES_IN = 900;
28: 29: 30:
31: const SAFETY_RANGE_EXPIRES_IN = 0.10;
32:
33: const SSO_COOKIE_NAME = 'datr';
34:
35: 36: 37: 38: 39: 40: 41: 42:
43: public static function doGetClientToken($endpoint_url)
44: {
45: try {
46: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
47: throw new Exception ('Endpoint URL is empty');
48: }
49:
50: $params = array();
51: $params ['grant_type'] = self::GRANT_TYPE_CLIENT_CREDENTIALS;
52: $response = Request::execute($endpoint_url, $params, Request::HTTP_POST, Request::SECURED);
53:
54: self::checkErrors($response);
55:
56: if (!isset ($response['result']->access_token) || ($response['result']->access_token == '')) {
57: throw new Exception ('The client_token retrieved is empty');
58: }
59:
60: $expires_in = self::DEFAULT_EXPIRES_IN;
61: if (isset ($response['result']->expires_in)) {
62: $expires_in = intval($response['result']->expires_in);
63: }
64:
65: $expires_in = ($expires_in - ($expires_in * self::SAFETY_RANGE_EXPIRES_IN));
66: $expires_at = (time() + $expires_in);
67: $client_token = new ClientToken(trim($response['result']->access_token), $expires_in, $expires_at, '/');
68: self::storeToken($client_token);
69:
70: return $client_token;
71: } catch (Exception $e) {
72: Identity::getLogger()->error('Error [' . __FUNCTION__ . '] - ' . $e->getMessage());
73: throw $e;
74: }
75: }
76:
77: 78: 79: 80: 81: 82: 83:
84: private static function checkErrors($response)
85: {
86: if (isset($response['result']->error)) {
87: if (isset($response['result']->type)) {
88: switch ($response['result']->type) {
89: case 'InvalidGrantException' :
90: throw new InvalidGrantException($response['result']->error . ' (' . (isset($response['result']->type) ? trim($response['result']->type) : '') . ')');;
91: }
92: }
93: throw new Exception($response['result']->error . ' (' . (isset($response['result']->type) ? trim($response['result']->type) : '') . ')');
94: }
95: if (isset($response['code']) && ($response['code'] != 200)) {
96: throw new Exception('Error: ' .$response['code']);
97: }
98: }
99:
100: 101: 102: 103: 104: 105:
106: public static function storeToken($token)
107: {
108: if (!($token instanceof StoredToken)) {
109: throw new Exception('Token is not valid');
110: }
111:
112:
113: $encryption = new Encryption(OAuthConfig::getClientId());
114: $cod = $encryption->encode($token->getValue());
115: @setcookie($token->getName(), $cod, $token->getExpiresAt(), $token->getPath(), '', false, true);
116: }
117:
118: 119: 120: 121: 122: 123: 124: 125: 126: 127:
128: public static function doGetAccessToken($endpoint_url, $code, $redirect_url)
129: {
130: try {
131: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
132: throw new Exception ('Endpoint URL is empty');
133: }
134: if (($code = trim(( string )$code)) == '') {
135: throw new Exception ('Code is empty');
136: }
137: if (($redirect_url = trim(( string )$redirect_url)) == '') {
138: throw new Exception ('Redirect URL is empty');
139: }
140:
141: $params = array();
142: $params ['grant_type'] = self::GRANT_TYPE_AUTH_CODE;
143: $params ['code'] = $code;
144: $params ['redirect_uri'] = $redirect_url;
145: $response = Request::execute($endpoint_url, $params, Request::HTTP_POST, Request::SECURED);
146:
147: self::checkErrors($response);
148:
149: if (!isset ($response ['result']->access_token) || ($response ['result']->access_token == '')) {
150: throw new Exception ('The access_token retrieved is empty');
151: }
152: if (!isset ($response ['result']->refresh_token) || ($response ['result']->refresh_token == '')) {
153: throw new Exception ('The refresh_token retrieved is empty');
154: }
155:
156: $expires_in = self::DEFAULT_EXPIRES_IN;
157: if (isset ($response['result']->expires_in)) {
158: $expires_in = intval($response['result']->expires_in);
159: }
160: $expires_in = ($expires_in - ($expires_in * self::SAFETY_RANGE_EXPIRES_IN));
161: $expires_at = (time() + $expires_in);
162: $refresh_expires_at = ($expires_at + (60*60*24*12));
163:
164: $result['access_token'] = new AccessToken (trim($response ['result']->access_token), $expires_in, $expires_at, '/');
165: $result['refresh_token'] = new RefreshToken (trim($response ['result']->refresh_token), 0, $refresh_expires_at, '/');
166:
167: self::storeToken($result['access_token']);
168: self::storeToken($result['refresh_token']);
169:
170: $loginStatus = new LoginStatus();
171: if (isset ($response ['result']->login_status)) {
172: $loginStatus->setCkusid($response['result']->login_status->uid);
173: $loginStatus->setOid($response['result']->login_status->oid);
174: $loginStatus->setConnectState($response['result']->login_status->connect_state);
175: }
176:
177: $result['login_status'] = $loginStatus;
178:
179: return $result;
180: } catch (InvalidGrantException $e) {
181: throw new InvalidGrantException('Error [' . __FUNCTION__ . '] - Maybe "code" is reused - '.$e->getMessage());
182: } catch (Exception $e) {
183: throw new Exception('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
184: }
185: }
186:
187: 188: 189: 190: 191: 192: 193: 194:
195: public static function doRefreshToken($endpoint_url)
196: {
197: try {
198: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
199: throw new Exception ('Endpoint URL is empty');
200: }
201: if (!($refresh_token = Identity::getThings()->getRefreshToken()) instanceof RefreshToken) {
202: throw new Exception ('Refresh token is empty');
203: }
204:
205:
206: $params = array();
207: $params['grant_type'] = self::GRANT_TYPE_REFRESH_TOKEN;
208: $params['refresh_token'] = $refresh_token->getValue();
209: $response = Request::execute($endpoint_url, $params, Request::HTTP_POST, Request::SECURED);
210:
211: self::checkErrors($response);
212:
213: if (!isset ($response ['result']->access_token) || ($response ['result']->access_token == '')) {
214: throw new Exception ('The access_token retrieved is empty');
215: }
216: if (!isset ($response ['result']->refresh_token) || ($response ['result']->refresh_token == '')) {
217: throw new Exception ('The refresh_token retrieved is empty');
218: }
219:
220: $expires_in = self::DEFAULT_EXPIRES_IN;
221: if (isset ($response['result']->expires_in)) {
222: $expires_in = intval($response['result']->expires_in);
223: }
224: $expires_in = ($expires_in - ($expires_in * self::SAFETY_RANGE_EXPIRES_IN));
225: $expires_at = (time() + $expires_in);
226: $refresh_expires_at = ($expires_at + (60*60*24*12));
227:
228: $result['access_token'] = new AccessToken (trim($response ['result']->access_token), $expires_in, $expires_at, '/');
229: $result['refresh_token'] = new RefreshToken (trim($response ['result']->refresh_token), 0, $refresh_expires_at, '/');
230:
231: self::storeToken($result['access_token']);
232: self::storeToken($result['refresh_token']);
233:
234: $loginStatus = new LoginStatus();
235: if (isset ($response ['result']->login_status)) {
236: $loginStatus->setCkusid($response['result']->login_status->uid);
237: $loginStatus->setOid($response['result']->login_status->oid);
238: $loginStatus->setConnectState($response['result']->login_status->connect_state);
239: }
240: $result['login_status'] = $loginStatus;
241:
242: return $result;
243: } catch (InvalidGrantException $e) {
244: throw new InvalidGrantException('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
245: } catch (Exception $e) {
246: throw new Exception('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
247: }
248: }
249:
250: 251: 252: 253: 254: 255: 256:
257: public static function doValidateBearer($endpoint_url)
258: {
259: try {
260: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
261: throw new Exception ('Endpoint URL is empty');
262: }
263: if (!(($access_token = Identity::getThings()->getAccessToken()) instanceof AccessToken) || ($access_token->getValue() == '')) {
264: throw new Exception ('Access token is empty');
265: }
266:
267: $params = array();
268: $params ['grant_type'] = self::GRANT_TYPE_VALIDATE_BEARER;
269: $params ['oauth_token'] = $access_token->getValue();
270: unset ($access_token);
271: $response = Request::execute($endpoint_url, $params, Request::HTTP_POST, Request::SECURED);
272:
273: self::checkErrors($response);
274:
275: $loginStatus = new LoginStatus();
276: if (isset ($response ['result']->login_status)) {
277: $loginStatus->setCkusid($response['result']->login_status->uid);
278: $loginStatus->setOid($response['result']->login_status->oid);
279: $loginStatus->setConnectState($response['result']->login_status->connect_state);
280: }
281:
282: return $loginStatus;
283: } catch (InvalidGrantException $e) {
284: throw new InvalidGrantException('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
285: } catch (Exception $e) {
286: throw new Exception('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
287: }
288: }
289:
290: 291: 292: 293: 294: 295: 296: 297: 298:
299: public static function doExchangeSession($endpoint_url, $cookie_value)
300: {
301: try {
302: $access_token = null;
303:
304: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
305: throw new Exception ('Endpoint URL is empty');
306: }
307: if (($cookie_value = trim($cookie_value)) == '') {
308: throw new Exception ('SSO cookie is empty');
309: }
310:
311: $params = array();
312: $params ['grant_type'] = self::GRANT_TYPE_EXCHANGE_SESSION;
313: $response = Request::execute($endpoint_url, $params, Request::HTTP_POST, Request::SECURED, null, array(self::SSO_COOKIE_NAME . '=' . $cookie_value));
314:
315: self::checkErrors($response);
316:
317: if (!isset ($response ['result']->access_token) || ($response ['result']->access_token == '')) {
318: throw new Exception ('The access_token retrieved is empty');
319: }
320: if (!isset ($response ['result']->refresh_token) || ($response ['result']->refresh_token == '')) {
321: throw new Exception ('The refresh_token retrieved is empty');
322: }
323:
324: $expires_in = self::DEFAULT_EXPIRES_IN;
325: if (isset ($response['result']->expires_in)) {
326: $expires_in = intval($response['result']->expires_in);
327: }
328: $expires_in = ($expires_in - ($expires_in * self::SAFETY_RANGE_EXPIRES_IN));
329: $expires_at = (time() + $expires_in);
330: $refresh_expires_at = ($expires_at + (60*60*24*12));
331:
332: $result['access_token'] = new AccessToken (trim($response ['result']->access_token), $expires_in, $expires_at, '/');
333: $result['refresh_token'] = new RefreshToken (trim($response ['result']->refresh_token), 0, $refresh_expires_at, '/');
334:
335: self::storeToken($result['access_token']);
336: self::storeToken($result['refresh_token']);
337:
338: $loginStatus = new LoginStatus();
339: if (isset ($response ['result']->login_status)) {
340: $loginStatus->setCkusid($response['result']->login_status->uid);
341: $loginStatus->setOid($response['result']->login_status->oid);
342: $loginStatus->setConnectState($response['result']->login_status->connect_state);
343: }
344:
345: $result['login_status'] = $loginStatus;
346:
347: return $result;
348: } catch (InvalidGrantException $e) {
349: throw new InvalidGrantException('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
350: } catch (Exception $e) {
351: throw new Exception('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
352: }
353: }
354:
355: 356: 357: 358: 359: 360: 361:
362: public static function doLogout($endpoint_url)
363: {
364: try {
365: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
366: throw new Exception ('Endpoint URL is empty');
367: }
368: if (!($refresh_token = Identity::getThings()->getRefreshToken()) instanceof RefreshToken) {
369: throw new Exception ('Refresh token is empty');
370: }
371:
372: $params = array();
373: $params ['token'] = $refresh_token->getValue();
374: $params ['token_type'] = 'refresh_token';
375: unset ($refresh_token);
376: Request::execute($endpoint_url, $params, Request::HTTP_POST, Request::SECURED);
377:
378: unset($_COOKIE[self::SSO_COOKIE_NAME]);
379: setcookie(self::SSO_COOKIE_NAME, null, -1,null,'.cocacola.es');
380:
381: self::deleteStoredToken(iTokenTypes::ACCESS_TOKEN);
382: self::deleteStoredToken(iTokenTypes::REFRESH_TOKEN);
383:
384: } catch (Exception $e) {
385: throw new Exception('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
386: }
387: }
388:
389: 390: 391: 392: 393: 394: 395: 396:
397: public static function deleteStoredToken ($name)
398: {
399: if (isset($_COOKIE[$name])) {
400: setcookie($name, '', time()-42000, '/');
401: unset($_COOKIE[$name]);
402: }
403: }
404:
405:
406: 407: 408: 409: 410: 411:
412: public static function hasToken($name)
413: {
414: return (self::getStoredToken($name) instanceof StoredToken);
415: }
416:
417: 418: 419: 420: 421: 422: 423: 424: 425:
426: public static function getStoredToken($name)
427: {
428: if (($name = trim((string)$name)) == '') {
429: throw new Exception ('Token type not exist');
430: }
431:
432: $encryption = new Encryption(OAuthConfig::getClientId());
433: if (isset($_COOKIE[$name])) {
434: return StoredToken::factory($name, $encryption->decode($_COOKIE[$name]), 0, 0, '/');
435: } else {
436: return null;
437: }
438: }
439:
440: 441: 442: 443: 444: 445: 446: 447: 448:
449: public static function doGetOpinator($endpoint_url, $scope, $token)
450: {
451: try {
452: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
453: throw new Exception ('Endpoint Opinator URL is empty');
454: }
455:
456: if (($scope = trim((string)$scope)) == '') {
457: throw new Exception ('Scope is empty');
458: }
459:
460: if (($token->getValue() == '') || (!($token instanceof StoredToken))) {
461: throw new Exception ('Token is not valid');
462: }
463:
464:
465: $params = array();
466: $params ['oauth_token'] = $token->getValue();
467: $response = Request::execute($endpoint_url . '/' . $scope, $params, Request::HTTP_POST, Request::SECURED);
468:
469: if (isset($response['code']) && ($response['code'] == 200)) {
470: return $response['result'];
471: } else {
472: throw new Exception('Error [' . __FUNCTION__ . '] - ' . $response['code'] . ' - ' . $response['result']);
473: }
474:
475: } catch (Exception $e) {
476: throw new Exception('Error [' . __FUNCTION__ . '] - ' . $e->getMessage());
477: }
478: }
479:
480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490:
491: public static function doCheckUserCompleted($endpoint_url, $scope)
492: {
493: try {
494: if (($endpoint_url = trim(( string )$endpoint_url)) == '') {
495: throw new Exception ('Endpoint URL is empty');
496: }
497:
498: if (($scope = trim((string)$scope)) == '') {
499: throw new Exception ('Scope is empty');
500: }
501:
502: if (!(($access_token = Identity::getThings()->getAccessToken()) instanceof AccessToken) || ($access_token->getValue() == '')) {
503: throw new Exception ('Access token is empty');
504: }
505:
506:
507: $params = array();
508: $params['oauth_token'] = $access_token->getValue();
509: $params['s'] = "needsToCompleteData";
510: $params['f'] = "UserMeta";
511: $params['w.section'] = $scope;
512:
513: $response = Request::execute($endpoint_url, $params, Request::HTTP_POST);
514:
515: self::checkErrors($response);
516:
517: if (isset($response['code']) && ($response['code'] == 200)) {
518: return (($response['result']->data[0]->meta->value) === 'false') ? true : false;
519: } else {
520: return false;
521: }
522: } catch (Exception $e) {
523: throw new Exception('Error [' . __FUNCTION__ . '] - '.$e->getMessage());
524: }
525: }
526: }