BxTriConModule.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup TridentConnect Trident Connect
  7. * @ingroup TridentModules
  8. *
  9. * @{
  10. */
  11. class BxTriConModule extends BxBaseModConnectModule
  12. {
  13. function __construct(&$aModule)
  14. {
  15. parent::__construct($aModule);
  16. }
  17. /**
  18. * Generate admin page;
  19. *
  20. * @return : (text) - html presentation data;
  21. */
  22. function actionAdministration()
  23. {
  24. parent::_actionAdministration('bx_tricon_api_key', '_bx_tricon_settings', '_bx_tricon_information', '_bx_tricon_information_block');
  25. }
  26. /**
  27. * Redirect to remote Trident site login form
  28. *
  29. * @return n/a/ - redirect or HTML page in case of error
  30. */
  31. function actionStart()
  32. {
  33. if (isLogged())
  34. $this->_redirect ($this -> _oConfig -> sDefaultRedirectUrl);
  35. if (!$this->_oConfig->sApiID || !$this->_oConfig->sApiSecret || !$this->_oConfig->sApiUrl) {
  36. $sCode = MsgBox( _t('_bx_tricon_profile_error_api_keys') );
  37. $this->_oTemplate->getPage(_t('_bx_tricon'), $sCode);
  38. }
  39. else {
  40. // define redirect URL to the remote Trident site
  41. $sUrl = bx_append_url_params($this->_oConfig->sApiUrl . 'auth', array(
  42. 'response_type' => 'code',
  43. 'client_id' => $this->_oConfig->sApiID,
  44. 'redirect_uri' => $this->_oConfig->sPageHandle,
  45. 'scope' => $this->_oConfig->sScope,
  46. 'state' => $this->_genCsrfToken(),
  47. ));
  48. $this->_redirect($sUrl);
  49. }
  50. }
  51. function actionHandle()
  52. {
  53. require_once(BX_DIRECTORY_PATH_INC . 'design.inc.php');
  54. // check CSRF token
  55. if ($this->_getCsrfToken() != bx_get('state')) {
  56. $this->_oTemplate->getPage(_t('_Error'), MsgBox(_t('_bx_tricon_state_invalid')));
  57. return;
  58. }
  59. // check code
  60. $sCode = bx_get('code');
  61. if (!$sCode) {
  62. $sErrorDescription = bx_get('error_description') ? bx_get('error_description') : _t('_error occured');
  63. $this->_oTemplate->getPage(_t('_Error'), MsgBox($sErrorDescription));
  64. return;
  65. }
  66. // make request for token
  67. $s = bx_file_get_contents($this->_oConfig->sApiUrl . 'token', array(
  68. 'client_id' => $this->_oConfig->sApiID,
  69. 'client_secret' => $this->_oConfig->sApiSecret,
  70. 'grant_type' => 'authorization_code',
  71. 'code' => $sCode,
  72. 'redirect_uri' => $this->_oConfig->sPageHandle,
  73. ), 'post');
  74. // handle error
  75. if (!$s || NULL === ($aResponse = json_decode($s, true)) || !isset($aResponse['access_token']) || isset($aResponse['error'])) {
  76. $sErrorDescription = isset($aResponse['error_description']) ? $aResponse['error_description'] : _t('_error occured');
  77. $this->_oTemplate->getPage(_t('_Error'), MsgBox($sErrorDescription));
  78. return;
  79. }
  80. // get the data, especially access_token
  81. $sAccessToken = $aResponse['access_token'];
  82. $sExpiresIn = $aResponse['expires_in'];
  83. $sExpiresAt = new \DateTime('+' . $sExpiresIn . ' seconds');
  84. $sRefreshToken = $aResponse['refresh_token'];
  85. // request info about profile
  86. $s = bx_file_get_contents($this->_oConfig->sApiUrl . 'api/me', array(), 'get', array(
  87. 'Authorization: Bearer ' . $sAccessToken,
  88. ));
  89. // handle error
  90. if (!$s || NULL === ($aResponse = json_decode($s, true)) || !$aResponse || isset($aResponse['error'])) {
  91. $sErrorDescription = isset($aResponse['error_description']) ? $aResponse['error_description'] : _t('_error occured');
  92. $this->_oTemplate->getPage(_t('_Error'), MsgBox($sErrorDescription));
  93. return;
  94. }
  95. $aRemoteProfileInfo = $aResponse;
  96. if ($aRemoteProfileInfo) {
  97. // check if user logged in before
  98. $iLocalProfileId = $this->_oDb->getProfileId($aRemoteProfileInfo['id']);
  99. if ($iLocalProfileId && $oProfile = BxDolProfile::getInstance($iLocalProfileId)) {
  100. // user already exists
  101. $this->setLogged($oProfile ->id());
  102. }
  103. else {
  104. // register new user
  105. $this->_createProfile($aRemoteProfileInfo);
  106. }
  107. }
  108. else {
  109. $this->_oTemplate->getPage(_t('_Error'), MsgBox(_t('_bx_tricon_profile_error_info')));
  110. }
  111. }
  112. protected function _redirect($sUrl, $iStatus = 302)
  113. {
  114. header("Location:{$sUrl}", true, $iStatus);
  115. exit;
  116. }
  117. /**
  118. * @param $aProfileInfo - remote profile info
  119. * @param $sAlternativeName - suffix to add to NickName to make it unique
  120. * @return profile array info, ready for the local database
  121. */
  122. protected function _convertRemoteFields($aProfileInfo, $sAlternativeName = '')
  123. {
  124. $aProfileFields = $aProfileInfo;
  125. $aProfileFields['name'] = $aProfileInfo['profile_display_name'];
  126. $aProfileFields['fullname'] = $aProfileInfo['profile_display_name'];
  127. return $aProfileFields;
  128. }
  129. protected function _genCsrfToken($bReturn = false)
  130. {
  131. if (getParam('sys_security_form_token_enable') != 'on' || defined('BX_DOL_CRON_EXECUTE'))
  132. return false;
  133. $oSession = BxDolSession::getInstance();
  134. $iCsrfTokenLifetime = (int)$this->_oDb->getParam('sys_security_form_token_lifetime');
  135. if ($oSession->getValue('bx_tricon_csrf_token') === false || ($iCsrfTokenLifetime != 0 && time() - (int)$oSession->getValue('csrf_token_time') > $iCsrfTokenLifetime)) {
  136. $sToken = genRndPwd(20, false);
  137. $oSession->setValue('bx_tricon_csrf_token', $sToken);
  138. $oSession->setValue('bx_tricon_csrf_token_time', time());
  139. }
  140. else {
  141. $sToken = $oSession->getValue('bx_tricon_csrf_token');
  142. }
  143. return $sToken;
  144. }
  145. protected function _getCsrfToken()
  146. {
  147. $oSession = BxDolSession::getInstance();
  148. return $oSession->getValue('bx_tricon_csrf_token');
  149. }
  150. }
  151. /** @} */