PageRenderTime 23ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/xenforo_consumer/library/bdApiConsumer/Helper/Api.php

https://gitlab.com/billyprice1/bdApi
PHP | 274 lines | 215 code | 51 blank | 8 comment | 21 complexity | 879f717e8896fd4e2d7a4e33aa083cde MD5 | raw file
  1. <?php
  2. class bdApiConsumer_Helper_Api
  3. {
  4. const SCOPE = 'read post';
  5. public static function getRequestUrl(array $provider, $redirectUri, array $extraParams = array())
  6. {
  7. $url = call_user_func_array('sprintf', array(
  8. '%s/index.php?oauth/authorize/&client_id=%s&redirect_uri=%s&response_type=code&scope=%s',
  9. rtrim($provider['root'], '/'),
  10. rawurlencode($provider['client_id']),
  11. rawurlencode($redirectUri),
  12. rawurlencode(self::SCOPE),
  13. ));
  14. if (XenForo_Application::getConfig()->get(bdApiConsumer_Option::CONFIG_TRACK_AUTHORIZE_URL_STATE)
  15. && !isset($extraParams['state'])
  16. ) {
  17. $extraParams['state'] = base64_encode(json_encode(array(
  18. 'time' => XenForo_Application::$time,
  19. 'ip' => XenForo_Helper_Ip::convertIpBinaryToString(XenForo_Application::getSession()->get('ip')),
  20. )));
  21. }
  22. foreach ($extraParams as $key => $value) {
  23. $url .= sprintf('&%s=%s', $key, rawurlencode($value));
  24. }
  25. return $url;
  26. }
  27. public static function getLoginLink(array $provider, $accessToken, $redirectUri)
  28. {
  29. return call_user_func_array('sprintf', array(
  30. '%s/index.php?tools/login&oauth_token=%s&redirect_uri=%s',
  31. rtrim($provider['root'], '/'),
  32. rawurlencode($accessToken),
  33. rawurlencode($redirectUri),
  34. ));
  35. }
  36. public static function getLogoutLink(array $provider, $accessToken, $redirectUri)
  37. {
  38. return call_user_func_array('sprintf', array(
  39. '%s/index.php?tools/logout&oauth_token=%s&redirect_uri=%s',
  40. rtrim($provider['root'], '/'),
  41. rawurlencode($accessToken),
  42. rawurlencode($redirectUri),
  43. ));
  44. }
  45. public static function getPublicLink(array $provider, $route)
  46. {
  47. $json = self::_post($provider, 'tools/link/', self::generateOneTimeToken($provider), 'link', array(
  48. 'type' => 'public',
  49. 'route' => $route,
  50. ));
  51. if (!empty($json['link'])) {
  52. return $json['link'];
  53. }
  54. return false;
  55. }
  56. public static function getAccessTokenFromCode(array $provider, $code, $redirectUri)
  57. {
  58. return self::_post($provider, 'oauth/token/', '', 'access_token', array(
  59. 'grant_type' => 'authorization_code',
  60. 'client_id' => $provider['client_id'],
  61. 'client_secret' => $provider['client_secret'],
  62. 'code' => $code,
  63. 'redirect_uri' => $redirectUri,
  64. ));
  65. }
  66. public static function getAccessTokenFromRefreshToken(array $provider, $refreshToken)
  67. {
  68. return self::_post($provider, 'oauth/token/', '', 'access_token', array(
  69. 'grant_type' => 'refresh_token',
  70. 'client_id' => $provider['client_id'],
  71. 'client_secret' => $provider['client_secret'],
  72. 'refresh_token' => $refreshToken,
  73. ));
  74. }
  75. public static function getAccessTokenFromUsernamePassword(array $provider, $username, $password)
  76. {
  77. return self::_post($provider, 'oauth/token/', '', 'access_token', array(
  78. 'grant_type' => 'password',
  79. 'client_id' => $provider['client_id'],
  80. 'client_secret' => $provider['client_secret'],
  81. 'username' => $username,
  82. 'password' => $password,
  83. ));
  84. }
  85. public static function generateOneTimeToken(array $provider, $userId = 0, $accessToken = '', $ttl = 10)
  86. {
  87. $timestamp = time() + $ttl;
  88. $once = md5($userId . $timestamp . $accessToken . $provider['client_secret']);
  89. return sprintf('%d,%d,%s,%s', $userId, $timestamp, $once, $provider['client_id']);
  90. }
  91. /**
  92. * @param array $provider
  93. * @param $accessToken
  94. * @param bool|true $autoSubscribe
  95. * @return array|false
  96. */
  97. public static function getVisitor(array $provider, $accessToken, $autoSubscribe = true)
  98. {
  99. $json = self::_get($provider, 'users/me/', $accessToken, 'user');
  100. if (!empty($json['user'])) {
  101. $json['_headerLinkHub'] = self::_getHeaderLinkHub($json['_headers']);
  102. if ($autoSubscribe AND empty($parts['subscription_callback']) AND !empty($json['_headerLinkHub'])) {
  103. self::postSubscription($provider, $accessToken, $json['_headerLinkHub']);
  104. }
  105. return $json['user'];
  106. }
  107. return false;
  108. }
  109. public static function getNotifications(array $provider, $accessToken)
  110. {
  111. $json = self::_get($provider, 'notifications/', $accessToken, 'notifications');
  112. if (isset($json['notifications'])) {
  113. $json['_headerLinkHub'] = self::_getHeaderLinkHub($json['_headers']);
  114. return $json;
  115. }
  116. return false;
  117. }
  118. public static function postLoginSocial(array $provider)
  119. {
  120. return self::_post($provider, 'tools/login-social/', self::generateOneTimeToken($provider), 'social');
  121. }
  122. public static function postPasswordResetRequest(array $provider, $accessToken)
  123. {
  124. return self::_post($provider, 'tools/password-reset-request/', $accessToken, 'status');
  125. }
  126. public static function postSubscription(array $provider, $accessToken, $url)
  127. {
  128. $json = self::_post($provider, $url, $accessToken, false, array(
  129. 'hub.callback' => XenForo_Link::buildPublicLink('canonical:misc/api-consumer/callback'),
  130. 'hub.mode' => 'subscribe',
  131. ));
  132. return (!empty($json['_responseStatus']) AND $json['_responseStatus'] == 202);
  133. }
  134. public static function postNotificationsRead(array $provider, $accessToken)
  135. {
  136. $json = self::_post($provider, 'notifications/read/', $accessToken);
  137. return (!empty($json['_responseStatus']) AND $json['_responseStatus'] == 200);
  138. }
  139. public static function verifyJsSdkSignature(array $provider, array $data, $prefix = '_api_data_')
  140. {
  141. $str = '';
  142. $prefixLength = utf8_strlen($prefix);
  143. $keys = array_keys($data);
  144. asort($keys);
  145. foreach ($keys as $key) {
  146. if (utf8_substr($key, 0, $prefixLength) !== $prefix) {
  147. // ignore keys that do not match our prefix
  148. continue;
  149. }
  150. $keySubstr = substr($key, $prefixLength);
  151. if ($keySubstr == 'signature') {
  152. // do not put the signature into calculation
  153. continue;
  154. }
  155. $str .= sprintf('%s=%s&', $keySubstr, $data[$key]);
  156. }
  157. $str .= $provider['client_secret'];
  158. $signature = md5($str);
  159. return isset($data[$prefix . 'signature']) AND ($signature === $data[$prefix . 'signature']);
  160. }
  161. protected static function _get(array $provider, $path, $accessToken = false, $expectedKey = false, array $params = array())
  162. {
  163. return self::_request('GET', $provider, $path, $accessToken, $expectedKey, $params);
  164. }
  165. protected static function _post(array $provider, $path, $accessToken = false, $expectedKey = false, array $params = array())
  166. {
  167. return self::_request('POST', $provider, $path, $accessToken, $expectedKey, $params);
  168. }
  169. protected static function _request($method, array $provider, $path, $accessToken = false, $expectedKey = false, array $params = array())
  170. {
  171. try {
  172. if (Zend_Uri::check($path)) {
  173. $uri = $path;
  174. } else {
  175. $uri = call_user_func_array('sprintf', array(
  176. '%s/index.php?%s',
  177. rtrim($provider['root'], '/'),
  178. $path,
  179. ));
  180. }
  181. $client = XenForo_Helper_Http::getClient($uri);
  182. if ($accessToken !== false AND !isset($params['oauth_token'])) {
  183. $params['oauth_token'] = $accessToken;
  184. }
  185. if ($method === 'GET') {
  186. $client->setParameterGet($params);
  187. } else {
  188. $client->setParameterPost($params);
  189. }
  190. $response = $client->request($method);
  191. $body = $response->getBody();
  192. $json = @json_decode($body, true);
  193. if (!is_array($json)) {
  194. $json = array('_body' => $body);
  195. }
  196. if ($expectedKey !== false) {
  197. if (!isset($json[$expectedKey])) {
  198. XenForo_Error::logException(new XenForo_Exception(sprintf(
  199. 'Key "%s" not found in %s `%s`: %s', $expectedKey, $method, $path, $body)), false);
  200. return false;
  201. }
  202. }
  203. $json['_headers'] = $response->getHeaders();
  204. $json['_responseStatus'] = $response->getStatus();
  205. return $json;
  206. } catch (Zend_Http_Client_Exception $e) {
  207. XenForo_Error::logException($e, false);
  208. return false;
  209. }
  210. }
  211. protected static function _getHeaderLinkHub(array $headers)
  212. {
  213. if (empty($headers['Link'])) {
  214. return null;
  215. }
  216. foreach ($headers['Link'] as $headerLink) {
  217. if (preg_match('/<(?<url>[^>]+)>; rel=hub/', $headerLink, $matches)) {
  218. return $matches['url'];
  219. }
  220. }
  221. return null;
  222. }
  223. }