From 509f81d2c82ee769935d6becd11c753e36dc720f Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Sat, 15 Apr 2017 23:54:56 +0300 Subject: [PATCH] Fix recaptcha api request (#891) --- plugins/recaptcha/VERSION | 2 +- plugins/recaptcha/index.php | 299 ++++++++++++++++++------------------ 2 files changed, 152 insertions(+), 149 deletions(-) diff --git a/plugins/recaptcha/VERSION b/plugins/recaptcha/VERSION index 42f7d2336..616187889 100644 --- a/plugins/recaptcha/VERSION +++ b/plugins/recaptcha/VERSION @@ -1 +1 @@ -2.1 \ No newline at end of file +2.2 \ No newline at end of file diff --git a/plugins/recaptcha/index.php b/plugins/recaptcha/index.php index 36801e89d..bffda14b1 100644 --- a/plugins/recaptcha/index.php +++ b/plugins/recaptcha/index.php @@ -1,148 +1,151 @@ -UseLangs(true); - - $this->addJs('js/recaptcha.js'); - - $this->addHook('ajax.action-pre-call', 'AjaxActionPreCall'); - $this->addHook('filter.ajax-response', 'FilterAjaxResponse'); - } - - /** - * @return array - */ - public function configMapping() - { - return array( - \RainLoop\Plugins\Property::NewInstance('public_key')->SetLabel('Site key') - ->SetAllowedInJs(true) - ->SetDefaultValue(''), - \RainLoop\Plugins\Property::NewInstance('private_key')->SetLabel('Secret key') - ->SetDefaultValue(''), - \RainLoop\Plugins\Property::NewInstance('theme')->SetLabel('Theme') - ->SetAllowedInJs(true) - ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION) - ->SetDefaultValue(array('light', 'dark')), - \RainLoop\Plugins\Property::NewInstance('error_limit')->SetLabel('Limit') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION) - ->SetDefaultValue(array(0, 1, 2, 3, 4, 5)) - ->SetDescription('') - ); - } - - /** - * @return string - */ - private function getCaptchaCacherKey() - { - return 'CaptchaNew/Login/'.\RainLoop\Utils::GetConnectionToken(); - } - - /** - * @return int - */ - private function getLimit() - { - $iConfigLimit = $this->Config()->Get('plugin', 'error_limit', 0); - if (0 < $iConfigLimit) - { - $oCacher = $this->Manager()->Actions()->Cacher(); - $sLimit = $oCacher && $oCacher->IsInited() ? $oCacher->Get($this->getCaptchaCacherKey()) : '0'; - - if (0 < \strlen($sLimit) && \is_numeric($sLimit)) - { - $iConfigLimit -= (int) $sLimit; - } - } - - return $iConfigLimit; - } - - /** - * @return void - */ - public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aData) - { - if (!$bAdmin && !$bAuth && \is_array($aData)) - { - $aData['show_captcha_on_login'] = 1 > $this->getLimit(); - } - } - - /** - * @param string $sAction - */ - public function AjaxActionPreCall($sAction) - { - if ('Login' === $sAction && 0 >= $this->getLimit()) - { - $bResult = false; - - $sResult = $this->Manager()->Actions()->Http()->GetUrlAsString( - 'https://www.google.com/recaptcha/api/siteverify?secret='. - \urlencode($this->Config()->Get('plugin', 'private_key', '')).'&response='. - \urlencode($this->Manager()->Actions()->GetActionParam('RecaptchaResponse', ''))); - - if ($sResult) - { - $aResp = @\json_decode($sResult, true); - if (\is_array($aResp) && isset($aResp['success']) && $aResp['success']) - { - $bResult = true; - } - } - - if (!$bResult) - { - $this->Manager()->Actions()->Logger()->Write('RecaptchaResponse:'.$sResult); - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CaptchaError); - } - } - } - - /** - * @param string $sAction - * @param array $aResponseItem - */ - public function FilterAjaxResponse($sAction, &$aResponseItem) - { - if ('Login' === $sAction && $aResponseItem && isset($aResponseItem['Result'])) - { - $oCacher = $this->Manager()->Actions()->Cacher(); - $iConfigLimit = (int) $this->Config()->Get('plugin', 'error_limit', 0); - - $sKey = $this->getCaptchaCacherKey(); - - if (0 < $iConfigLimit && $oCacher && $oCacher->IsInited()) - { - if (false === $aResponseItem['Result']) - { - $iLimit = 0; - $sLimut = $oCacher->Get($sKey); - if (0 < \strlen($sLimut) && \is_numeric($sLimut)) - { - $iLimit = (int) $sLimut; - } - - $oCacher->Set($sKey, ++$iLimit); - - if ($iConfigLimit <= $iLimit) - { - $aResponseItem['Captcha'] = true; - } - } - else - { - $oCacher->Delete($sKey); - } - } - } - } -} +UseLangs(true); + + $this->addJs('js/recaptcha.js'); + + $this->addHook('ajax.action-pre-call', 'AjaxActionPreCall'); + $this->addHook('filter.ajax-response', 'FilterAjaxResponse'); + } + + /** + * @return array + */ + public function configMapping() + { + return array( + \RainLoop\Plugins\Property::NewInstance('public_key')->SetLabel('Site key') + ->SetAllowedInJs(true) + ->SetDefaultValue(''), + \RainLoop\Plugins\Property::NewInstance('private_key')->SetLabel('Secret key') + ->SetDefaultValue(''), + \RainLoop\Plugins\Property::NewInstance('theme')->SetLabel('Theme') + ->SetAllowedInJs(true) + ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION) + ->SetDefaultValue(array('light', 'dark')), + \RainLoop\Plugins\Property::NewInstance('error_limit')->SetLabel('Limit') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION) + ->SetDefaultValue(array(0, 1, 2, 3, 4, 5)) + ->SetDescription('') + ); + } + + /** + * @return string + */ + private function getCaptchaCacherKey() + { + return 'CaptchaNew/Login/'.\RainLoop\Utils::GetConnectionToken(); + } + + /** + * @return int + */ + private function getLimit() + { + $iConfigLimit = $this->Config()->Get('plugin', 'error_limit', 0); + if (0 < $iConfigLimit) + { + $oCacher = $this->Manager()->Actions()->Cacher(); + $sLimit = $oCacher && $oCacher->IsInited() ? $oCacher->Get($this->getCaptchaCacherKey()) : '0'; + + if (0 < \strlen($sLimit) && \is_numeric($sLimit)) + { + $iConfigLimit -= (int) $sLimit; + } + } + + return $iConfigLimit; + } + + /** + * @return void + */ + public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aData) + { + if (!$bAdmin && !$bAuth && \is_array($aData)) + { + $aData['show_captcha_on_login'] = 1 > $this->getLimit(); + } + } + + /** + * @param string $sAction + */ + public function AjaxActionPreCall($sAction) + { + if ('Login' === $sAction && 0 >= $this->getLimit()) + { + $bResult = false; + + $sResult = $this->Manager()->Actions()->Http()->SendPostRequest( + 'https://www.google.com/recaptcha/api/siteverify', + array( + 'secret' => $this->Config()->Get('plugin', 'private_key', ''), + 'response' => $this->Manager()->Actions()->GetActionParam('RecaptchaResponse', '') + ) + ); + + if ($sResult) + { + $aResp = @\json_decode($sResult, true); + if (\is_array($aResp) && isset($aResp['success']) && $aResp['success']) + { + $bResult = true; + } + } + + if (!$bResult) + { + $this->Manager()->Actions()->Logger()->Write('RecaptchaResponse:'.$sResult); + throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CaptchaError); + } + } + } + + /** + * @param string $sAction + * @param array $aResponseItem + */ + public function FilterAjaxResponse($sAction, &$aResponseItem) + { + if ('Login' === $sAction && $aResponseItem && isset($aResponseItem['Result'])) + { + $oCacher = $this->Manager()->Actions()->Cacher(); + $iConfigLimit = (int) $this->Config()->Get('plugin', 'error_limit', 0); + + $sKey = $this->getCaptchaCacherKey(); + + if (0 < $iConfigLimit && $oCacher && $oCacher->IsInited()) + { + if (false === $aResponseItem['Result']) + { + $iLimit = 0; + $sLimut = $oCacher->Get($sKey); + if (0 < \strlen($sLimut) && \is_numeric($sLimut)) + { + $iLimit = (int) $sLimut; + } + + $oCacher->Set($sKey, ++$iLimit); + + if ($iConfigLimit <= $iLimit) + { + $aResponseItem['Captcha'] = true; + } + } + else + { + $oCacher->Delete($sKey); + } + } + } + } +}