BxOAuthAPI.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup OAuth2 OAuth2 server
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. use OAuth2\Response;
  12. class BxOAuthAPI extends BxDol
  13. {
  14. protected $_oModule;
  15. protected $_oDb;
  16. public $aAction2Scope = array (
  17. 'me' => 'basic,market,service',
  18. 'user' => 'basic,market,service',
  19. 'friends' => 'basic,market,service',
  20. 'service' => 'service',
  21. 'market' => 'market',
  22. );
  23. function __construct($oModule)
  24. {
  25. $this->_oModule = $oModule;
  26. $this->_oDb = $oModule->_oDb;
  27. }
  28. /**
  29. * @page private_api API Private
  30. * @section private_api_me /m/oauth2/api/me
  31. *
  32. * Provides information about current profile.
  33. *
  34. * **Scopes:**
  35. * `basic`, `service`, `market`
  36. *
  37. * **HTTP Method:**
  38. * `GET`
  39. *
  40. * **Request header:**
  41. * @code
  42. * Authorization: Bearer 9802c4a34e1535d8c3b721604ee0e7fb04116c49
  43. * @endcode
  44. *
  45. * **Response (success):**
  46. * @code
  47. * {
  48. * "id":"123",
  49. * "type":"bx_organizations",
  50. * "email":"test@example.com",
  51. * "role":"1",
  52. * "name":"Test",
  53. * "profile_display_name":"Test",
  54. * "profile_link":"http:\/\/example.com\/path-to-una\/page\/view-organization-profile?id=12",
  55. * "picture":"http:\/\/example.com\/path-to-una\/image_transcoder.php?o=bx_organizations_picture&h=36&dpx=1&t=1496247306"
  56. * }
  57. * @endcode
  58. *
  59. * **Response (error):**
  60. * @code
  61. * {
  62. * "error":"short error description here",
  63. * "error_description":"long error description here"
  64. * }
  65. * @endcode
  66. *
  67. */
  68. function me($aToken)
  69. {
  70. if (!($oProfile = BxDolProfile::getInstance($aToken['user_id']))) {
  71. $this->errorOutput('404', 'not_found', 'Profile was not found');
  72. return;
  73. }
  74. $aClient = $this->_oDb->getClientsBy(array('type' => 'client_id', 'client_id' => $aToken['client_id']));
  75. $aProfile = $this->_prepareProfileArray($oProfile, false);
  76. $aProfile['owner'] = (int)$aProfile['id'] == (int)$aClient['user_id'];
  77. $this->output($aProfile);
  78. }
  79. /**
  80. * @page private_api API Private
  81. * @section private_api_user /m/oauth2/api/user
  82. *
  83. * Provides information about particular profile profile.
  84. *
  85. * **Parameters:**
  86. * - `id` - profile ID
  87. *
  88. * Everything else is equivalent to @ref private_api_me
  89. */
  90. function user($aToken)
  91. {
  92. $iProfileId = (int)bx_get('id');
  93. if ($iProfileId == $aToken['user_id']) {
  94. $this->me($aToken);
  95. return;
  96. }
  97. if (!($oProfile = $this->_getProfileWithAccessChecking($iProfileId)))
  98. return;
  99. if (!($oProfile = BxDolProfile::getInstance($aToken['user_id'])))
  100. return;
  101. $this->output($this->_prepareProfileArray($oProfile, !isAdmin($oProfile->getAccountId())));
  102. }
  103. /**
  104. * @page private_api API Private
  105. * @section private_api_friends /m/oauth2/api/friends
  106. *
  107. * Get list of friends.
  108. *
  109. * **Scopes:**
  110. * `basic`, `service`, `market`
  111. *
  112. * **HTTP Method:**
  113. * `GET`
  114. *
  115. * **Parameters:**
  116. * - `id` - profile ID
  117. *
  118. * **Request header:**
  119. * @code
  120. * Authorization: Bearer 9802c4a34e1535d8c3b721604ee0e7fb04116c49
  121. * @endcode
  122. *
  123. * **Response (success):**
  124. * @code
  125. * {
  126. * "user_id":30,
  127. * "friends":[
  128. * "24",
  129. * "29",
  130. * "51"
  131. * ]
  132. * }
  133. * @endcode
  134. *
  135. * **Response (error):**
  136. * @code
  137. * {
  138. * "error":"short error description here",
  139. * "error_description":"long error description here"
  140. * }
  141. * @endcode
  142. *
  143. */
  144. function friends($aToken)
  145. {
  146. $iProfileId = (int)bx_get('id');
  147. if (!($oProfile = $this->_getProfileWithAccessChecking($iProfileId)))
  148. return;
  149. if (!($oConn = BxDolConnection::getObjectInstance('sys_profiles_friends'))) {
  150. $this->errorOutput(405, 'not_supported', 'Friends lists aren\'t supported');
  151. return false;
  152. }
  153. $this->output(array(
  154. 'user_id' => $iProfileId,
  155. 'friends' => $oConn->getConnectedContent($iProfileId, true),
  156. ));
  157. }
  158. /**
  159. * @page private_api API Private
  160. * @section private_api_market /m/oauth2/api/market
  161. *
  162. * Market service call.
  163. *
  164. * **Scopes:**
  165. * `market`, `service`
  166. *
  167. * Everything is equivalent to @ref private_api_service, only module name parameter can be ommited
  168. */
  169. function market($aToken)
  170. {
  171. $_GET['key'] = $_POST['key'] = $aToken['client_id'];
  172. $_GET['module'] = $_POST['module'] = 'bx_market_api';
  173. $this->service($aToken);
  174. }
  175. /**
  176. * @page private_api API Private
  177. * @section private_api_service /m/oauth2/api/service
  178. *
  179. * Perform system call.
  180. * For a list of avalibale service calls and their parameters refer to @ref service page.
  181. *
  182. * URL should look like this in case of service API call:
  183. * @code
  184. * http://example.com/m/oauth2/api/service?module=bx_market&method=test&params[]=1&params[]=abc&class=custom_class_name_or_remove_it_if_module_class
  185. * http://example.com/m/oauth2/api/service?module=bx_market&method=test&params=serialized_string_of_params
  186. * @endcode
  187. *
  188. * **Scopes:**
  189. * `service`
  190. *
  191. * **HTTP Method:**
  192. * `GET`, `POST`
  193. *
  194. * **Parameters:**
  195. * - `module` - module name to perform service call in
  196. * - `method` - service call method
  197. * - `params` - parameters array
  198. * - `class` - custom module name if different from main module class
  199. *
  200. * **Request header:**
  201. * @code
  202. * Authorization: Bearer 9802c4a34e1535d8c3b721604ee0e7fb04116c49
  203. * @endcode
  204. *
  205. * **Response (success):**
  206. * Depends on particular service call
  207. *
  208. * **Response (error):**
  209. * Error responce is described in particular service method.
  210. * In case of general error (for example when service call isn't found, or error with token), the format is following:
  211. * @code
  212. * {
  213. * "error":"short error description here",
  214. * "error_description":"long error description here"
  215. * }
  216. * @endcode
  217. *
  218. */
  219. function service($aToken)
  220. {
  221. if (!($oProfile = BxDolProfile::getInstance($aToken['user_id']))) {
  222. $this->errorOutput('404', 'not_found', 'Profile was not found');
  223. return;
  224. }
  225. bx_login($oProfile->getAccountId(), false);
  226. check_logged();
  227. $sModule = bx_get('module');
  228. $sMethod = bx_get('method');
  229. if (!($aParams = bx_get('params')))
  230. $aParams = array();
  231. elseif (is_string($aParams) && preg_match('/^a:[\d+]:\{/', $aParams))
  232. $aParams = @unserialize($aParams);
  233. if (!is_array($aParams))
  234. $aParams = array($aParams);
  235. if (!($sClass = bx_get('class')))
  236. $sClass = 'Module';
  237. if (!BxDolRequest::serviceExists($sModule, $sMethod, $sClass)) {
  238. $this->errorOutput(404, 'not_found', 'Service was not found');
  239. return false;
  240. }
  241. $mixedRet = BxDolService::call($sModule, $sMethod, $aParams, $sClass);
  242. $this->output(array(
  243. 'module' => $sModule,
  244. 'method' => $sMethod,
  245. 'data' => $mixedRet,
  246. ));
  247. }
  248. function errorOutput($iHttpCode, $sError, $sErrorDesc)
  249. {
  250. $oReponse = new Response();
  251. $oReponse->setError($iHttpCode, $sError, $sErrorDesc);
  252. $oReponse->send();
  253. }
  254. function output($a)
  255. {
  256. $oReponse = new Response();
  257. $oReponse->setParameters($a);
  258. $oReponse->send();
  259. }
  260. protected function _getProfileWithAccessChecking ($iProfileId)
  261. {
  262. if (!$oProfile = BxDolProfile::getInstance($iProfileId)) {
  263. $this->errorOutput('404', 'not_found', 'Profile was not found');
  264. return false;
  265. }
  266. /*
  267. // TODO: check visibility
  268. if (!bx_check_profile_visibility($iProfileId, $aToken['user_id'], true)) {
  269. $this->errorOutput(403, 'access_denied', 'You have no rights to view this user info');
  270. return false;
  271. }
  272. */
  273. return $oProfile;
  274. }
  275. protected function _prepareProfileArray ($oProfile, $bPublicFieldsOnly = true)
  276. {
  277. $oAccount = $oProfile->getAccountObject();
  278. $aProfileInfo = $oProfile->getInfo();
  279. $aAccountInfo = $oAccount->getInfo();
  280. if ($bPublicFieldsOnly) {
  281. $aProfileInfo = array(
  282. 'id' => $aProfileInfo['id'],
  283. );
  284. }
  285. else {
  286. unset($aProfileInfo['account_id']);
  287. unset($aProfileInfo['content_id']);
  288. unset($aProfileInfo['status']);
  289. // --- account's profiles info
  290. $aProfileInfo['email'] = $oAccount->getEmail();
  291. // ---- returns all accounts profiles React Jot
  292. $aProfiles = $oAccount->getProfiles();
  293. foreach($aProfiles as &$aProfile) {
  294. $oSubProfile = BxDolProfile::getInstance($aProfile['id']);
  295. $aProfileInfo['profiles'][$aProfile['id']] = array(
  296. 'name' => $oSubProfile->getDisplayName(),
  297. 'profile_link' => $oSubProfile->getUrl(),
  298. 'picture' => $oSubProfile->getThumb(),
  299. 'id' => $aProfile['id']
  300. );
  301. }
  302. // TODO: fetch extended info from profile module
  303. }
  304. $aProfileInfo['role'] = $aAccountInfo['role'];
  305. $aProfileInfo['name'] = $oAccount->getDisplayName();
  306. $aProfileInfo['profile_display_name'] = $oProfile->getDisplayName();
  307. $aProfileInfo['profile_link'] = $oProfile->getUrl();
  308. $aProfileInfo['picture'] = $oProfile->getPicture();
  309. // ---- additional profile's fields for React Jot
  310. $aProfileInfo['cover'] = $oProfile->getCover();
  311. $aProfileInfo['followers'] = (int)BxDolConnection::getObjectInstance('sys_profiles_subscriptions')->getConnectedInitiatorsCount($aProfileInfo['id']);
  312. $aProfileInfo['following'] = (int)BxDolConnection::getObjectInstance('sys_profiles_subscriptions')->getConnectedContentCount($aProfileInfo['id']);
  313. $aProfileInfo['friends'] = (int)BxDolConnection::getObjectInstance('sys_profiles_friends')->getConnectedContentCount($aProfileInfo['id'], true);
  314. return $aProfileInfo;
  315. }
  316. }
  317. /** @} */