PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/application/Espo/Core/ExternalAccount/OAuth2/Client.php

https://gitlab.com/johanlindberg/irvato-crm
PHP | 260 lines | 186 code | 47 blank | 27 comment | 14 complexity | d0987277c803d55846151cbc60615928 MD5 | raw file
  1. <?php
  2. /************************************************************************
  3. * This file is part of EspoCRM.
  4. *
  5. * EspoCRM - Open Source CRM application.
  6. * Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
  7. * Website: http://www.espocrm.com
  8. *
  9. * EspoCRM is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * EspoCRM is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with EspoCRM. If not, see http://www.gnu.org/licenses/.
  21. *
  22. * The interactive user interfaces in modified source and object code versions
  23. * of this program must display Appropriate Legal Notices, as required under
  24. * Section 5 of the GNU General Public License version 3.
  25. *
  26. * In accordance with Section 7(b) of the GNU General Public License version 3,
  27. * these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
  28. ************************************************************************/
  29. namespace Espo\Core\ExternalAccount\OAuth2;
  30. class Client
  31. {
  32. const AUTH_TYPE_URI = 0;
  33. const AUTH_TYPE_AUTHORIZATION_BASIC = 1;
  34. const AUTH_TYPE_FORM = 2;
  35. const TOKEN_TYPE_URI = 'Uri';
  36. const TOKEN_TYPE_BEARER = 'Bearer';
  37. const TOKEN_TYPE_OAUTH = 'OAuth';
  38. const CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENENCODED = 'application/x-www-form-urlencoded';
  39. const CONTENT_TYPE_MULTIPART_FORM_DATA = 'multipart/form-data';
  40. const CONTENT_TYPE_APPLICATION_JSON = 'application/json';
  41. const HTTP_METHOD_GET = 'GET';
  42. const HTTP_METHOD_POST = 'POST';
  43. const HTTP_METHOD_PUT = 'PUT';
  44. const HTTP_METHOD_DELETE = 'DELETE';
  45. const HTTP_METHOD_HEAD = 'HEAD';
  46. const HTTP_METHOD_PATCH = 'PATCH';
  47. const GRANT_TYPE_AUTHORIZATION_CODE = 'authorization_code';
  48. const GRANT_TYPE_REFRESH_TOKEN = 'refresh_token';
  49. const GRANT_TYPE_PASSWORD = 'password';
  50. const GRANT_TYPE_CLIENT_CREDENTIALS = 'client_credentials';
  51. protected $clientId = null;
  52. protected $clientSecret = null;
  53. protected $accessToken = null;
  54. protected $authType = self::AUTH_TYPE_URI;
  55. protected $tokenType = self::TOKEN_TYPE_URI;
  56. protected $accessTokenSecret = null;
  57. protected $accessTokenParamName = 'access_token';
  58. protected $certificateFile = null;
  59. protected $curlOptions = array();
  60. public function __construct(array $params = array())
  61. {
  62. if (!extension_loaded('curl')) {
  63. throw new \Exception('CURL extension not found.');
  64. }
  65. }
  66. public function setClientId($clientId)
  67. {
  68. $this->clientId = $clientId;
  69. }
  70. public function setClientSecret($clientSecret)
  71. {
  72. $this->clientSecret = $clientSecret;
  73. }
  74. public function setAccessToken($accessToken)
  75. {
  76. $this->accessToken = $accessToken;
  77. }
  78. public function setAuthType($authType)
  79. {
  80. $this->authType = $authType;
  81. }
  82. public function setCertificateFile($certificateFile)
  83. {
  84. $this->certificateFile = $certificateFile;
  85. }
  86. public function setCurlOption($option, $value)
  87. {
  88. $this->curlOptions[$option] = $value;
  89. }
  90. public function setCurlOptions($options)
  91. {
  92. $this->curlOptions = array_merge($this->curlOptions, $options);
  93. }
  94. public function setTokenType($tokenType)
  95. {
  96. $this->tokenType = $tokenType;
  97. }
  98. public function setAccessTokenSecret($accessTokenSecret)
  99. {
  100. $this->accessTokenSecret = $accessTokenSecret;
  101. }
  102. public function request($url, $params = null, $httpMethod = self::HTTP_METHOD_GET, array $httpHeaders = array())
  103. {
  104. if ($this->accessToken) {
  105. switch ($this->tokenType) {
  106. case self::TOKEN_TYPE_URI:
  107. $params[$this->accessTokenParamName] = $this->accessToken;
  108. break;
  109. case self::TOKEN_TYPE_BEARER:
  110. $httpHeaders['Authorization'] = 'Bearer ' . $this->accessToken;
  111. break;
  112. case self::TOKEN_TYPE_OAUTH:
  113. $httpHeaders['Authorization'] = 'OAuth ' . $this->accessToken;
  114. break;
  115. default:
  116. throw new \Exception('Unknown access token type.');
  117. }
  118. }
  119. return $this->execute($url, $params, $httpMethod, $httpHeaders);
  120. }
  121. private function execute($url, $params = null, $httpMethod, array $httpHeaders = array())
  122. {
  123. $curlOptions = array(
  124. CURLOPT_RETURNTRANSFER => true,
  125. CURLOPT_SSL_VERIFYPEER => true,
  126. CURLOPT_CUSTOMREQUEST => $httpMethod
  127. );
  128. switch ($httpMethod) {
  129. case self::HTTP_METHOD_POST:
  130. $curlOptions[CURLOPT_POST] = true;
  131. case self::HTTP_METHOD_PUT:
  132. case self::HTTP_METHOD_PATCH:
  133. if (is_array($params)) {
  134. $postFields = http_build_query($params, null, '&');
  135. } else {
  136. $postFields = $params;
  137. }
  138. $curlOptions[CURLOPT_POSTFIELDS] = $postFields;
  139. break;
  140. case self::HTTP_METHOD_HEAD:
  141. $curlOptions[CURLOPT_NOBODY] = true;
  142. case self::HTTP_METHOD_DELETE:
  143. case self::HTTP_METHOD_GET:
  144. if (strpos($url, '?') === false) {
  145. $url .= '?';
  146. }
  147. if (is_array($params)) {
  148. $url .= http_build_query($params, null, '&');
  149. }
  150. break;
  151. default:
  152. break;
  153. }
  154. $curlOptions[CURLOPT_URL] = $url;
  155. $curlOptHttpHeader = array();
  156. foreach ($httpHeaders as $key => $value) {
  157. $curlOptHttpHeader[] = "{$key}: {$value}";
  158. }
  159. $curlOptions[CURLOPT_HTTPHEADER] = $curlOptHttpHeader;
  160. $ch = curl_init();
  161. curl_setopt_array($ch, $curlOptions);
  162. curl_setopt($ch, CURLOPT_HEADER, 1);
  163. if (!empty($this->certificateFile)) {
  164. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
  165. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  166. curl_setopt($ch, CURLOPT_CAINFO, $this->certificateFile);
  167. } else {
  168. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  169. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  170. }
  171. if (!empty($this->curlOptions)) {
  172. curl_setopt_array($ch, $this->curlOptions);
  173. }
  174. $response = curl_exec($ch);
  175. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  176. $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
  177. $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
  178. $responceHeader = substr($response, 0, $headerSize);
  179. $responceBody = substr($response, $headerSize);
  180. $resultArray = null;
  181. if ($curlError = curl_error($ch)) {
  182. throw new \Exception($curlError);
  183. } else {
  184. $resultArray = json_decode($responceBody, true);
  185. }
  186. curl_close($ch);
  187. return array(
  188. 'result' => (null !== $resultArray) ? $resultArray: $responceBody,
  189. 'code' => intval($httpCode),
  190. 'contentType' => $contentType,
  191. 'header' => $responceHeader,
  192. );
  193. }
  194. public function getAccessToken($url, $grantType, array $params)
  195. {
  196. $params['grant_type'] = $grantType;
  197. $httpHeaders = array();
  198. switch ($this->tokenType) {
  199. case self::AUTH_TYPE_URI:
  200. case self::AUTH_TYPE_FORM:
  201. $params['client_id'] = $this->clientId;
  202. $params['client_secret'] = $this->clientSecret;
  203. break;
  204. case self::AUTH_TYPE_AUTHORIZATION_BASIC:
  205. $params['client_id'] = $this->clientId;
  206. $httpHeaders['Authorization'] = 'Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret);
  207. break;
  208. default:
  209. throw new \Exception();
  210. }
  211. return $this->execute($url, $params, self::HTTP_METHOD_POST, $httpHeaders);
  212. }
  213. }