Exemplo n.º 1
0
 public function actionExternal()
 {
     $providerCode = $this->_input->filterSingle('provider', XenForo_Input::STRING);
     $assocUserId = $this->_input->filterSingle('assoc', XenForo_Input::UINT);
     $externalCode = $this->_input->filterSingle('code', XenForo_Input::STRING);
     $redirect = $this->_bdApiConsumer_getRedirect();
     $state = $this->_input->filterSingle('state', XenForo_Input::STRING);
     if (!empty($state)) {
         // looks like bdApiConsumer_Option::CONFIG_TRACK_AUTHORIZE_URL_STATE has been enabled
         // attempt to unpack the state data now
         $stateData = @base64_decode($state);
         if ($stateData !== false) {
             $stateData = @json_decode($stateData, true, 2);
             if ($stateData !== null) {
                 if (isset($stateData['time'])) {
                     $stateData['timeElapsed'] = XenForo_Application::$time - $stateData['time'];
                 }
                 // make it available in server error log (if an error occurs)
                 $_POST['.state'] = $stateData;
             }
         }
     }
     $provider = bdApiConsumer_Option::getProviderByCode($providerCode);
     if (empty($provider)) {
         if (!empty($externalCode)) {
             // make this available in server error log
             $_POST['.dynamicRedirect'] = $this->getDynamicRedirect();
             // this is one serious error
             throw new XenForo_Exception('Provider could not be determined');
         } else {
             return $this->responseNoPermission();
         }
     }
     $externalRedirectUri = XenForo_Link::buildPublicLink('canonical:register/external', false, array('provider' => $providerCode, 'assoc' => $assocUserId ? $assocUserId : false));
     if ($this->_input->filterSingle('reg', XenForo_Input::UINT)) {
         XenForo_Application::get('session')->set(self::SESSION_KEY_REDIRECT, $redirect);
         $social = $this->_input->filterSingle('social', XenForo_Input::STRING);
         $requestUrl = bdApiConsumer_Helper_Api::getRequestUrl($provider, $externalRedirectUri, array('social' => $social));
         return $this->responseRedirect(XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL, $requestUrl);
     }
     $externalToken = null;
     if (empty($externalToken)) {
         $_token = $this->_input->filterSingle('_token', XenForo_Input::STRING);
         if (!empty($_token)) {
             $_token = @base64_decode($_token);
             if (!empty($_token)) {
                 $_token = @json_decode($_token, true);
                 if (!empty($_token)) {
                     $externalToken = $_token;
                 }
             }
         }
     }
     if (empty($externalToken)) {
         // there should be `code` at this point...
         if (empty($externalCode)) {
             return $this->responseError(new XenForo_Phrase('bdapi_consumer_error_occurred_while_connecting_with_x', array('provider' => $provider['name'])));
         }
         $externalToken = bdApiConsumer_Helper_Api::getAccessTokenFromCode($provider, $externalCode, $externalRedirectUri);
         if (!empty($externalToken)) {
             $selfRedirect = $this->_request->getRequestUri();
             $selfRedirect = preg_replace('#(\\?|&)code=.+(&|$)#', '$1', $selfRedirect);
             $selfRedirect = preg_replace('#(\\?|&)state=.+(&|$)#', '$1', $selfRedirect);
             // filter $externalToken keys to make it more lightweight
             foreach (array_keys($externalToken) as $_key) {
                 if ($_key === 'debug' || substr($_key, 0, 1) === '_') {
                     unset($externalToken[$_key]);
                 }
             }
             $selfRedirect .= sprintf('%1$s_token=%2$s', strpos($selfRedirect, '?') === false ? '?' : '&', rawurlencode(base64_encode(json_encode($externalToken))));
             // do a self redirect immediately so user won't refresh the page
             // TODO: improve this
             return $this->responseRedirect(XenForo_ControllerResponse_Redirect::SUCCESS, $selfRedirect);
         }
     }
     if (empty($externalToken)) {
         if (!XenForo_Visitor::getUserId()) {
             // report error only if user hasn't been logged in
             return $this->responseError(new XenForo_Phrase('bdapi_consumer_error_occurred_while_connecting_with_x', array('provider' => $provider['name'])));
         } else {
             // or try to be friendly and just redirect user back to where s/he was
             return $this->responseRedirect(XenForo_ControllerResponse_Redirect::SUCCESS, $redirect);
         }
     }
     $externalVisitor = bdApiConsumer_Helper_Api::getVisitor($provider, $externalToken['access_token']);
     if (empty($externalVisitor)) {
         return $this->responseError(new XenForo_Phrase('bdapi_consumer_error_occurred_while_connecting_with_x', array('provider' => $provider['name'])));
     }
     if (empty($externalVisitor['user_email'])) {
         return $this->responseError(new XenForo_Phrase('bdapi_consumer_x_returned_unknown_error', array('provider' => $provider['name'])));
     }
     if (isset($externalVisitor['user_is_valid']) && isset($externalVisitor['user_is_verified'])) {
         if (empty($externalVisitor['user_is_valid']) || empty($externalVisitor['user_is_verified'])) {
             return $this->responseError(new XenForo_Phrase('bdapi_consumer_x_account_not_good_standing', array('provider' => $provider['name'])));
         }
     }
     $userModel = $this->_getUserModel();
     /** @var bdApiConsumer_XenForo_Model_UserExternal $userExternalModel */
     $userExternalModel = $this->_getUserExternalModel();
     $existingAssoc = $userExternalModel->getExternalAuthAssociation($userExternalModel->bdApiConsumer_getProviderCode($provider), $externalVisitor['user_id']);
     $autoRegistered = false;
     if (empty($existingAssoc)) {
         $existingAssoc = $this->_bdApiConsumer_autoRegister($provider, $externalToken, $externalVisitor);
         if (!empty($existingAssoc)) {
             $autoRegistered = true;
         }
     }
     if ($existingAssoc && $userModel->getUserById($existingAssoc['user_id'])) {
         XenForo_Application::get('session')->changeUserId($existingAssoc['user_id']);
         XenForo_Visitor::setup($existingAssoc['user_id']);
         if (!$autoRegistered) {
             $userExternalModel->bdApiConsumer_updateExternalAuthAssociation($provider, $externalVisitor['user_id'], $existingAssoc['user_id'], array_merge($externalVisitor, array('token' => $externalToken)));
         }
         return $this->responseRedirect(XenForo_ControllerResponse_Redirect::SUCCESS, $redirect);
     }
     $existingUser = false;
     $emailMatch = false;
     if (XenForo_Visitor::getUserId()) {
         $existingUser = XenForo_Visitor::getInstance();
     } elseif ($assocUserId) {
         $existingUser = $userModel->getUserById($assocUserId);
     }
     if (!$existingUser) {
         $existingUser = $userModel->getUserByEmail($externalVisitor['user_email']);
         $emailMatch = true;
     }
     if ($existingUser) {
         // must associate: matching user
         return $this->responseView('bdApiConsumer_ViewPublic_Register_External', 'bdapi_consumer_register', array('associateOnly' => true, 'provider' => $provider, 'externalToken' => $externalToken, 'externalVisitor' => $externalVisitor, 'existingUser' => $existingUser, 'emailMatch' => $emailMatch, 'redirect' => $redirect));
     }
     if (bdApiConsumer_Option::get('bypassRegistrationActive')) {
         // do not check for registration active option
     } else {
         $this->_assertRegistrationActive();
     }
     $externalVisitor['username'] = bdApiConsumer_Helper_AutoRegister::suggestUserName($externalVisitor['username'], $userModel);
     return $this->responseView('bdApiConsumer_ViewPublic_Register_External', 'bdapi_consumer_register', array('provider' => $provider, 'externalToken' => $externalToken, 'externalVisitor' => $externalVisitor, 'redirect' => $redirect, 'customFields' => $this->_getFieldModel()->prepareUserFields($this->_getFieldModel()->getUserFields(array('registration' => true)), true), 'timeZones' => XenForo_Helper_TimeZone::getTimeZones(), 'tosUrl' => XenForo_Dependencies_Public::getTosUrl()), $this->_getRegistrationContainerParams());
 }
Exemplo n.º 2
0
 public function actionExternal()
 {
     $providerCode = $this->_input->filterSingle('provider', XenForo_Input::STRING);
     $assocUserId = $this->_input->filterSingle('assoc', XenForo_Input::UINT);
     $redirect = $this->_input->filterSingle('redirect', XenForo_Input::STRING);
     $provider = bdApiConsumer_Option::getProviderByCode($providerCode);
     if (empty($provider)) {
         // this is one serious error
         throw new XenForo_Exception('Provider could not be determined');
     }
     $externalRedirectUri = XenForo_Link::buildPublicLink('canonical:register/external', false, array('provider' => $providerCode, 'assoc' => $assocUserId ? $assocUserId : false));
     if ($this->_input->filterSingle('reg', XenForo_Input::UINT)) {
         $redirect = XenForo_Link::convertUriToAbsoluteUri($this->getDynamicRedirect());
         XenForo_Application::get('session')->set(self::SESSION_KEY_REDIRECT, $redirect);
         $social = $this->_input->filterSingle('social', XenForo_Input::STRING);
         $requestUrl = bdApiConsumer_Helper_Api::getRequestUrl($provider, $externalRedirectUri, array('social' => $social));
         return $this->responseRedirect(XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL, $requestUrl);
     }
     // try to use the non-standard query parameter `t` first,
     // continue exchange code for access token later if that fails
     $externalCode = $this->_input->filterSingle('code', XenForo_Input::STRING);
     if (empty($externalCode)) {
         return $this->responseError(new XenForo_Phrase('bdapi_consumer_error_occurred_while_connecting_with_x', array('provider' => $provider['name'])));
     }
     $externalToken = bdApiConsumer_Helper_Api::getAccessTokenFromCode($provider, $externalCode, $externalRedirectUri);
     if (empty($externalToken)) {
         return $this->responseError(new XenForo_Phrase('bdapi_consumer_error_occurred_while_connecting_with_x', array('provider' => $provider['name'])));
     }
     $externalVisitor = bdApiConsumer_Helper_Api::getVisitor($provider, $externalToken['access_token']);
     if (empty($externalVisitor)) {
         return $this->responseError(new XenForo_Phrase('bdapi_consumer_error_occurred_while_connecting_with_x', array('provider' => $provider['name'])));
     }
     if (empty($externalVisitor['user_email'])) {
         return $this->responseError(new XenForo_Phrase('bdapi_consumer_x_returned_unknown_error', array('provider' => $provider['name'])));
     }
     if (isset($externalVisitor['user_is_valid']) and isset($externalVisitor['user_is_verified'])) {
         if (empty($externalVisitor['user_is_valid']) or empty($externalVisitor['user_is_verified'])) {
             return $this->responseError(new XenForo_Phrase('bdapi_consumer_x_account_not_good_standing', array('provider' => $provider['name'])));
         }
     }
     $userModel = $this->_getUserModel();
     $userExternalModel = $this->_getUserExternalModel();
     $existingAssoc = $userExternalModel->getExternalAuthAssociation($userExternalModel->bdApiConsumer_getProviderCode($provider), $externalVisitor['user_id']);
     $autoRegistered = false;
     if (empty($existingAssoc)) {
         $existingAssoc = $this->_bdApiConsumer_autoRegister($provider, $externalToken, $externalVisitor);
         if (!empty($existingAssoc)) {
             $autoRegistered = true;
         }
     }
     if ($existingAssoc && $userModel->getUserById($existingAssoc['user_id'])) {
         $redirect = XenForo_Application::get('session')->get(self::SESSION_KEY_REDIRECT);
         XenForo_Application::get('session')->changeUserId($existingAssoc['user_id']);
         XenForo_Visitor::setup($existingAssoc['user_id']);
         XenForo_Application::get('session')->remove(self::SESSION_KEY_REDIRECT);
         if (empty($redirect)) {
             $redirect = $this->getDynamicRedirect(false, false);
         }
         if (!$autoRegistered) {
             $userExternalModel->bdApiConsumer_updateExternalAuthAssociation($provider, $externalVisitor['user_id'], $existingAssoc['user_id'], $externalVisitor + array('token' => $externalToken));
         }
         return $this->responseRedirect(XenForo_ControllerResponse_Redirect::SUCCESS, $redirect);
     }
     $existingUser = false;
     $emailMatch = false;
     if (XenForo_Visitor::getUserId()) {
         $existingUser = XenForo_Visitor::getInstance();
     } elseif ($assocUserId) {
         $existingUser = $userModel->getUserById($assocUserId);
     }
     if (!$existingUser) {
         $existingUser = $userModel->getUserByEmail($externalVisitor['user_email']);
         $emailMatch = true;
     }
     if ($existingUser) {
         // must associate: matching user
         return $this->responseView('bdApiConsumer_ViewPublic_Register_External', 'bdapi_consumer_register', array('associateOnly' => true, 'provider' => $provider, 'externalToken' => $externalToken, 'externalVisitor' => $externalVisitor, 'existingUser' => $existingUser, 'emailMatch' => $emailMatch, 'redirect' => $redirect));
     }
     if (bdApiConsumer_Option::get('bypassRegistrationActive')) {
         // do not check for registration active option
     } else {
         $this->_assertRegistrationActive();
     }
     $externalVisitor['username'] = bdApiConsumer_Helper_AutoRegister::suggestUserName($externalVisitor['username'], $userModel);
     return $this->responseView('bdApiConsumer_ViewPublic_Register_External', 'bdapi_consumer_register', array('provider' => $provider, 'externalToken' => $externalToken, 'externalVisitor' => $externalVisitor, 'redirect' => $redirect, 'customFields' => $this->_getFieldModel()->prepareUserFields($this->_getFieldModel()->getUserFields(array('registration' => true)), true), 'timeZones' => XenForo_Helper_TimeZone::getTimeZones(), 'tosUrl' => XenForo_Dependencies_Public::getTosUrl()), $this->_getRegistrationContainerParams());
 }