From d69c75655c1cfdca77f843f6c0afb659ae645ec5 Mon Sep 17 00:00:00 2001 From: Daniel Galla Date: Wed, 18 Oct 2023 16:49:56 +0200 Subject: [PATCH 1/2] Implement option to set custom endpoints --- Block/Frontend/FriendlyCaptcha.php | 7 +-- Model/Config.php | 48 ++++++++++++++--- Model/Config/Source/Endpoint.php | 39 ++++++++++++++ Model/Validate.php | 6 +-- Setup/Patch/Data/MigrateEuEndpointConfig.php | 51 +++++++++++++++++++ etc/adminhtml/system.xml | 22 ++++++-- etc/config.xml | 2 +- .../templates/imi_friendly_captcha.phtml | 4 +- 8 files changed, 157 insertions(+), 22 deletions(-) create mode 100644 Model/Config/Source/Endpoint.php create mode 100644 Setup/Patch/Data/MigrateEuEndpointConfig.php diff --git a/Block/Frontend/FriendlyCaptcha.php b/Block/Frontend/FriendlyCaptcha.php index 1ebceec..021ea5e 100644 --- a/Block/Frontend/FriendlyCaptcha.php +++ b/Block/Frontend/FriendlyCaptcha.php @@ -60,12 +60,9 @@ public function getSiteKey(): string return $this->config->getSiteKey(); } - /** - * @return bool - */ - public function useEuEndpoint(): bool + public function getPuzzleEndpoint(): string { - return $this->config->useEuEndpoint(); + return $this->config->getPuzzleEndpoint(); } /** diff --git a/Model/Config.php b/Model/Config.php index a242f0c..fea4cf0 100644 --- a/Model/Config.php +++ b/Model/Config.php @@ -8,6 +8,7 @@ namespace IMI\FriendlyCaptcha\Model; +use IMI\FriendlyCaptcha\Model\Config\Source\Endpoint; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\Phrase; use Magento\Store\Model\ScopeInterface; @@ -18,7 +19,7 @@ class Config public const CONFIG_PATH_APIEKEY = 'imi_friendly_captcha/general/apikey'; - public const CONFIG_PATH_EU_ENDPOINT = 'imi_friendly_captcha/general/eu_endpoint'; + public const CONFIG_PATH_ENDPOINT = 'imi_friendly_captcha/general/endpoint'; public const CONFIG_PATH_ENABLED_FRONTEND = 'imi_friendly_captcha/frontend/enabled'; @@ -36,6 +37,10 @@ class Config public const CONFIG_PATH_ENABLED_FRONTEND_SENDFRIEND = 'imi_friendly_captcha/frontend/enabled_sendfriend'; + protected const CONFIG_PATH_CUSTOM_PUZZLE = 'imi_friendly_captcha/general/custom_puzzle'; + + protected const CONFIG_PATH_CUSTOM_VERIFY = 'imi_friendly_captcha/general/custom_verify'; + /** * @var ScopeConfigInterface */ @@ -116,14 +121,43 @@ public function getApikey(): string } /** - * Get Friendly Captcha endpoint - * - * @return bool + * Get Friendly Captcha puzzle endpoint */ - public function useEuEndpoint(): bool + public function getPuzzleEndpoint(): string { - return (bool)$this->scopeConfig->getValue(static::CONFIG_PATH_EU_ENDPOINT, - ScopeInterface::SCOPE_WEBSITE); + $endpoint = (int)$this->scopeConfig->getValue(static::CONFIG_PATH_ENDPOINT, ScopeInterface::SCOPE_WEBSITE); + + switch ($endpoint) { + case Endpoint::EU: + return 'https://eu-api.friendlycaptcha.eu/api/v1/puzzle'; + case Endpoint::CUSTOM: + return (string)$this->scopeConfig->getValue( + static::CONFIG_PATH_CUSTOM_PUZZLE, + ScopeInterface::SCOPE_WEBSITE + ); + default: + return ''; + } + } + + /** + * Get Friendly Captcha verify endpoint + */ + public function getVerifyEndpoint(): string + { + $endpoint = (int)$this->scopeConfig->getValue(static::CONFIG_PATH_ENDPOINT, ScopeInterface::SCOPE_WEBSITE); + + switch ($endpoint) { + case Endpoint::EU: + return 'https://eu-api.friendlycaptcha.eu/api/v1/puzzle'; + case Endpoint::CUSTOM: + return (string)$this->scopeConfig->getValue( + static::CONFIG_PATH_CUSTOM_VERIFY, + ScopeInterface::SCOPE_WEBSITE + ); + default: + return 'https://api.friendlycaptcha.com/api/v1/siteverify'; + } } /** diff --git a/Model/Config/Source/Endpoint.php b/Model/Config/Source/Endpoint.php new file mode 100644 index 0000000..c32c7f9 --- /dev/null +++ b/Model/Config/Source/Endpoint.php @@ -0,0 +1,39 @@ + + */ + public function toOptionArray() + { + return [ + ['value' => self::DEFAULT, 'label' => __('Default')], + ['value' => self::EU, 'label' => __('EU Endpoint')], + ['value' => self::CUSTOM, 'label' => __('Custom Endpoint')], + ]; + } + + /** + * @return array + */ + public function toArray() + { + return [ + self::DEFAULT => __('Default'), + self::EU => __('EU Endpoint'), + self::CUSTOM => __('Custom Endpoint'), + ]; + } +} diff --git a/Model/Validate.php b/Model/Validate.php index 1330e1f..383a97d 100644 --- a/Model/Validate.php +++ b/Model/Validate.php @@ -96,11 +96,7 @@ public function validate(string $friendlyCaptchaSolution): bool private function getSiteVerifyUrl(): string { - if ($this->config->useEuEndpoint()) { - return 'https://eu-api.friendlycaptcha.eu/api/v1/siteverify'; - } - - return 'https://api.friendlycaptcha.com/api/v1/siteverify'; + return $this->config->getVerifyEndpoint(); } private function shouldUseResponse(Curl $curl, $response): bool diff --git a/Setup/Patch/Data/MigrateEuEndpointConfig.php b/Setup/Patch/Data/MigrateEuEndpointConfig.php new file mode 100644 index 0000000..acc362e --- /dev/null +++ b/Setup/Patch/Data/MigrateEuEndpointConfig.php @@ -0,0 +1,51 @@ +configCollectionFactory->create(); + $collection->addFieldToFilter('path', ['eq' => 'imi_friendly_captcha/general/eu_endpoint']); + $collection->getItems(); + + /** @var Value $config */ + foreach ($collection as $config) { + $config->setPath('imi_friendly_captcha/general/endpoint'); + $this->configResource->save($config); + } + } +} diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 2c8985b..12cdf8c 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -30,9 +30,25 @@ Magento\Config\Model\Config\Backend\Encrypted - - - Magento\Config\Model\Config\Source\Yesno + + + IMI\FriendlyCaptcha\Model\Config\Source\Endpoint + + + + + 2 + + required-entry validate-url validate-no-html-tags + + + + + 2 + + required-entry validate-url validate-no-html-tags - 0 + 0 0 diff --git a/view/frontend/templates/imi_friendly_captcha.phtml b/view/frontend/templates/imi_friendly_captcha.phtml index 1f71397..ccbd9dc 100644 --- a/view/frontend/templates/imi_friendly_captcha.phtml +++ b/view/frontend/templates/imi_friendly_captcha.phtml @@ -5,11 +5,13 @@ */ /** @var $block IMI\FriendlyCaptcha\Block\Frontend\FriendlyCaptcha */ +/** @var $escaper \Magento\Framework\Escaper */ +$endpoint = $block->getPuzzleEndpoint(); ?>
useEuEndpoint()): ?>data-puzzle-endpoint="https://eu-api.friendlycaptcha.eu/api/v1/puzzle" + data-puzzle-endpoint="escapeUrl($endpoint) ?>" data-lang="getLang() ?>" data-callback="captchaSolved_getWidgetId() ?>" >
From 640389455b8c6bec7aafb1aef8a32b7f8abe16b6 Mon Sep 17 00:00:00 2001 From: Daniel Galla Date: Wed, 18 Oct 2023 17:52:44 +0200 Subject: [PATCH 2/2] Support controllers that do not extend deprecated AbstractAction --- Model/Provider/Failure/AjaxResponseFailure.php | 6 +++--- .../Failure/AuthenticationExceptionFailure.php | 6 +++--- Model/Provider/Failure/ObserverRedirectFailure.php | 6 +++--- Model/Provider/FailureProviderInterface.php | 5 +++-- Observer/FriendlyCaptchaObserver.php | 13 +++++++++++-- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Model/Provider/Failure/AjaxResponseFailure.php b/Model/Provider/Failure/AjaxResponseFailure.php index 748256b..b31db8c 100644 --- a/Model/Provider/Failure/AjaxResponseFailure.php +++ b/Model/Provider/Failure/AjaxResponseFailure.php @@ -7,7 +7,7 @@ namespace IMI\FriendlyCaptcha\Model\Provider\Failure; use Magento\Framework\App\ActionFlag; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\Http; use Magento\Framework\App\Action\Action; use Magento\Framework\Json\EncoderInterface; use IMI\FriendlyCaptcha\Model\Config; @@ -48,10 +48,10 @@ public function __construct( /** * Handle friendlyCaptcha failure - * @param ResponseInterface $response + * @param Http $response * @return void */ - public function execute(ResponseInterface $response = null) + public function execute(Http $response) { $this->actionFlag->set('', Action::FLAG_NO_DISPATCH, true); diff --git a/Model/Provider/Failure/AuthenticationExceptionFailure.php b/Model/Provider/Failure/AuthenticationExceptionFailure.php index 66dcff2..b230724 100644 --- a/Model/Provider/Failure/AuthenticationExceptionFailure.php +++ b/Model/Provider/Failure/AuthenticationExceptionFailure.php @@ -6,7 +6,7 @@ namespace IMI\FriendlyCaptcha\Model\Provider\Failure; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\Http; use Magento\Framework\Exception\Plugin\AuthenticationException; use IMI\FriendlyCaptcha\Model\Config; use IMI\FriendlyCaptcha\Model\Provider\FailureProviderInterface; @@ -30,12 +30,12 @@ public function __construct( /** * Handle friendlyCaptcha failure - * @param ResponseInterface $response + * @param Http $response * @return void * @throws AuthenticationException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function execute(ResponseInterface $response = null) + public function execute(Http $response) { throw new AuthenticationException($this->config->getErrorDescription()); } diff --git a/Model/Provider/Failure/ObserverRedirectFailure.php b/Model/Provider/Failure/ObserverRedirectFailure.php index cd5f1a0..6e03140 100644 --- a/Model/Provider/Failure/ObserverRedirectFailure.php +++ b/Model/Provider/Failure/ObserverRedirectFailure.php @@ -7,7 +7,7 @@ namespace IMI\FriendlyCaptcha\Model\Provider\Failure; use Magento\Framework\App\ActionFlag; -use Magento\Framework\App\ResponseInterface; +use Magento\Framework\App\Response\Http; use Magento\Framework\Message\ManagerInterface as MessageManagerInterface; use Magento\Framework\App\Action\Action; use Magento\Framework\UrlInterface; @@ -74,10 +74,10 @@ private function getUrl() /** * Handle friendlyCaptcha failure - * @param ResponseInterface $response + * @param Http $response * @return void */ - public function execute(ResponseInterface $response = null) + public function execute(Http $response) { $this->messageManager->addErrorMessage($this->config->getErrorDescription()); $this->actionFlag->set('', Action::FLAG_NO_DISPATCH, true); diff --git a/Model/Provider/FailureProviderInterface.php b/Model/Provider/FailureProviderInterface.php index 1f59545..be16519 100644 --- a/Model/Provider/FailureProviderInterface.php +++ b/Model/Provider/FailureProviderInterface.php @@ -6,6 +6,7 @@ namespace IMI\FriendlyCaptcha\Model\Provider; +use Magento\Framework\App\Response\Http; use Magento\Framework\App\ResponseInterface; interface FailureProviderInterface @@ -13,9 +14,9 @@ interface FailureProviderInterface /** * Handle friendlyCaptcha failure * - * @param ResponseInterface|null $response + * @param Http $response * * @return void */ - public function execute(ResponseInterface $response = null); + public function execute(Http $response); } diff --git a/Observer/FriendlyCaptchaObserver.php b/Observer/FriendlyCaptchaObserver.php index 8878fd7..d854e8b 100644 --- a/Observer/FriendlyCaptchaObserver.php +++ b/Observer/FriendlyCaptchaObserver.php @@ -6,7 +6,9 @@ namespace IMI\FriendlyCaptcha\Observer; +use Magento\Framework\App\Action\AbstractAction; use Magento\Framework\App\Action\Action; +use Magento\Framework\App\Response\Http as HttpResponse; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; use IMI\FriendlyCaptcha\Api\ValidateInterface; @@ -37,6 +39,11 @@ class FriendlyCaptchaObserver implements ObserverInterface */ private $isCheckRequired; + /** + * @var HttpResponse + */ + private $response; + /** * @param SolutionProviderInterface $responseProvider * @param ValidateInterface $validate @@ -47,12 +54,14 @@ public function __construct( SolutionProviderInterface $responseProvider, ValidateInterface $validate, FailureProviderInterface $failureProvider, - IsCheckRequiredInterface $isCheckRequired + IsCheckRequiredInterface $isCheckRequired, + HttpResponse $response ) { $this->responseProvider = $responseProvider; $this->validate = $validate; $this->failureProvider = $failureProvider; $this->isCheckRequired = $isCheckRequired; + $this->response = $response; } /** @@ -68,7 +77,7 @@ public function execute(Observer $observer): void if (!$this->validate->validate($friendlyCaptchaResponse)) { /** @var Action $controller */ $controller = $observer->getControllerAction(); - $this->failureProvider->execute($controller ? $controller->getResponse() : null); + $this->failureProvider->execute($controller instanceof AbstractAction ? $controller->getResponse() : $this->response); } } }