From de87e22569998cf541748c62e239926e546848e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Hugo=20Valle=20Castillo?= Date: Wed, 10 Aug 2016 20:18:17 -0300 Subject: [PATCH] Improving the recaptcha (feature). --- DependencyInjection/Configuration.php | 24 ++- Form/Type/VihuvacRecaptchaType.php | 75 ++++---- README.md | 84 ++++++-- Resources/config/services.yml | 7 +- Resources/translations/validators.en.xliff | 15 -- Resources/translations/validators.en.yml | 4 + Resources/translations/validators.es.xliff | 15 -- Resources/translations/validators.es.yml | 4 + Resources/translations/validators.fr.xliff | 15 -- Resources/translations/validators.fr.yml | 4 + .../Form/vihuvac_recaptcha_widget.html.php | 71 ++++--- .../Form/vihuvac_recaptcha_widget.html.twig | 78 +++++--- Validator/Constraints/IsTrue.php | 2 +- Validator/Constraints/IsTrueValidator.php | 180 ++++++++++-------- 14 files changed, 347 insertions(+), 231 deletions(-) delete mode 100644 Resources/translations/validators.en.xliff create mode 100644 Resources/translations/validators.en.yml delete mode 100644 Resources/translations/validators.es.xliff create mode 100644 Resources/translations/validators.es.yml delete mode 100755 Resources/translations/validators.fr.xliff create mode 100755 Resources/translations/validators.fr.yml diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 10a164a..244ac73 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -11,6 +11,7 @@ namespace Vihuvac\Bundle\RecaptchaBundle\DependencyInjection; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -33,12 +34,33 @@ public function getConfigTreeBuilder() ->children() ->scalarNode("site_key")->isRequired()->end() ->scalarNode("secret_key")->isRequired()->end() - ->booleanNode("secure")->defaultFalse()->end() ->booleanNode("enabled")->defaultTrue()->end() + ->booleanNode("ajax")->defaultFalse()->end() ->scalarNode("locale_key")->defaultValue("%kernel.default_locale%")->end() ->end() ; + $this->addHttpClientConfiguration($rootNode); + return $treeBuilder; } + + /** + * {@inheritDoc} + */ + private function addHttpClientConfiguration(ArrayNodeDefinition $node) + { + $node + ->children() + ->arrayNode("http_proxy") + ->addDefaultsIfNotSet() + ->children() + ->scalarNode("host")->defaultValue(null)->end() + ->scalarNode("port")->defaultValue(null)->end() + ->scalarNode("auth")->defaultValue(null)->end() + ->end() + ->end() + ->end() + ; + } } diff --git a/Form/Type/VihuvacRecaptchaType.php b/Form/Type/VihuvacRecaptchaType.php index 56a6ede..95ed6fc 100644 --- a/Form/Type/VihuvacRecaptchaType.php +++ b/Form/Type/VihuvacRecaptchaType.php @@ -11,7 +11,6 @@ namespace Vihuvac\Bundle\RecaptchaBundle\Form\Type; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormView; @@ -24,10 +23,10 @@ class VihuvacRecaptchaType extends AbstractType { /** - * The reCAPTCHA server URL's + * The reCAPTCHA Server URL's */ - const RECAPTCHA_API_SERVER = "http://www.google.com/recaptcha/api"; - const RECAPTCHA_API_SECURE_SERVER = "https://www.google.com/recaptcha/api"; + const RECAPTCHA_API_SERVER = "https://www.google.com/recaptcha/api"; + const RECAPTCHA_API_JS_SERVER = "https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"; /** * The public key @@ -36,12 +35,12 @@ class VihuvacRecaptchaType extends AbstractType */ protected $siteKey; - /** - * Use secure url? - * - * @var Boolean - */ - protected $secure; + /** + * Use AJAX API + * + * @var Boolean + */ + protected $ajax; /** * Enable recaptcha? @@ -62,16 +61,16 @@ class VihuvacRecaptchaType extends AbstractType * Construct. * * @param string $siteKey Recaptcha site key - * @param string $secure Recaptcha securey api url * @param Boolean $enabled Recaptcha status + * @param Boolean $ajax Ajax status * @param string $language Language or locale code */ - public function __construct(ContainerInterface $container) + public function __construct($siteKey, $enabled, $ajax, $language) { - $this->siteKey = $container->getParameter("vihuvac_recaptcha.site_key"); - $this->secure = $container->getParameter("vihuvac_recaptcha.secure"); - $this->enabled = $container->getParameter("vihuvac_recaptcha.enabled"); - $this->language = $container->getParameter("vihuvac_recaptcha.locale_key"); + $this->siteKey = $siteKey; + $this->enabled = $enabled; + $this->ajax = $ajax; + $this->language = $language; } /** @@ -79,30 +78,30 @@ public function __construct(ContainerInterface $container) */ public function buildView(FormView $view, FormInterface $form, array $options) { - $view->vars = array_replace( - $view->vars, - array( - "vihuvac_recaptcha_enabled" => $this->enabled - ) - ); + $view->vars = array_replace($view->vars, array( + "vihuvac_recaptcha_enabled" => $this->enabled, + "vihuvac_recaptcha_ajax" => $this->ajax + )); if (!$this->enabled) { return; } - if ($this->secure) { - $server = self::RECAPTCHA_API_SECURE_SERVER; + if (!isset($options["language"])) { + $options["language"] = $this->language; + } + + if (!$this->ajax) { + $view->vars = array_replace($view->vars, array( + "url_challenge" => sprintf("%s.js?hl=%s", self::RECAPTCHA_API_SERVER, $options["language"]), + "site_key" => $this->siteKey + )); } else { - $server = self::RECAPTCHA_API_SERVER; + $view->vars = array_replace($view->vars, array( + "url_api" => self::RECAPTCHA_API_JS_SERVER, + "site_key" => $this->siteKey + )); } - - $view->vars = array_replace( - $view->vars, - array( - "url_challenge" => sprintf("%s.js?hl=%s", $server, $this->language), - "site_key" => $this->siteKey - ) - ); } /** @@ -113,12 +112,18 @@ public function configureOptions(OptionsResolver $resolver) $resolver->setDefaults( array( "compound" => false, + "language" => $this->language, "site_key" => null, "url_challenge" => null, + "url_noscript" => null, "attr" => array( "options" => array( - "theme" => null, - "type" => null + "theme" => "light", + "type" => "image", + "size" => "normal", + "expiredCallback" => null, + "defer" => false, + "async" => false, ) ) ) diff --git a/README.md b/README.md index 80da74c..c8e6ee8 100644 --- a/README.md +++ b/README.md @@ -41,25 +41,45 @@ Add the following to your config file: vihuvac_recaptcha: site_key: here_is_your_site_key secret_key: here_is_your_secret_key - secure: true - enabled: true locale_key: kernel.default_locale ``` > **NOTE**: > -> If you want to use the secure URL for the reCAPTCHA, just set ```true``` as value in the secure parameter (__false is the default value__). +> This bundle uses a secure API (**HTTPS Protocol**). **Google API** solves the requests by the Browser (**Client**). > > The ```site_key``` parameter is the same than the ```public_key``` parameter and the ```secret_key``` parameter is the same than the ```private_key``` parameter (parameters used in the previous versions). -You can easily disable reCAPTCHA (for example in a local or test environment): +You can easily **enable** and **disable** the reCAPTCHA feature using any one of the booleans ```true``` or ```false``` through the **enabled** parameter, e.g: ``` yaml # app/config/config.yml vihuvac_recaptcha: // ... - enabled: false + enabled: true +``` + +You can load the reCAPTCHA using the Ajax API (**optional**): + +``` yaml +# app/config/config.yml + +vihuvac_recaptcha: + // ... + ajax: true +``` + +Additionally you can add HTTP Proxy configuration (**optional**): + +``` yaml +# app/config/config.yml + +vihuvac_recaptcha: + // ... + host: proxy.your-domain.com + port: 3128 + auth: proxy_username:proxy_password ``` Congratulations! You're ready! @@ -83,10 +103,14 @@ public function buildForm(FormBuilder $builder, array $options) You can pass extra options to reCAPTCHA with the ```attr > options``` option, e.g: -| Tag attribute | Render parameter | Value | Default | Description | -| ------------- | :--------------: | :-----------: | :-----: | ---------------------------------------: | -| data-theme | theme | dark / light | light | Optional. The color theme of the widget. | -| data-type | type | audio / image | image | Optional. The type of CAPTCHA to serve. | +| Tag attribute | Render parameter | Value | Default | Description | +| --------------------- | :--------------: | :--------------: | :-----: | ---------------------------------------: | +| data-theme | theme | dark / light | light | Optional. The color theme of the widget. | +| data-type | type | audio / image | image | Optional. The type of CAPTCHA to serve. | +| data-size | size | compact / normal | normal | Optional. The size of the widget. | +| data-expired-callback | expiredCallback | | | Optional. The name of your callback function to be executed when the recaptcha response expires and the user needs to solve a new CAPTCHA. | +| | defer | true / false | false | Optional for the Ajax API. | +| | async | true / false | false | Optional for the Ajax API. | ``` php array( "options" => array( "theme" => "light", - "type" => "audio" + "type" => "audio", + "size" => "normal" ) ) ) @@ -141,7 +166,8 @@ public function buildForm(FormBuilder $builder, array $options) "attr" => array( "options" => array( "theme" => "light", - "type" => "audio" + "type" => "audio", + "size" => "normal" ) ), "mapped" => false, @@ -227,4 +253,40 @@ using JavaScript: ``` +**Customization**: + +If you want to use a custom theme, put your chunk of code before setting the theme: + +``` +
+
+
Incorrect please try again
+ + Enter the words above: + Enter the numbers you hear: + + + +
Get another CAPTCHA
+ + + +
Help
+
+ +{% form_theme form "VihuvacRecaptchaBundle:Form:vihuvac_recaptcha_widget.html.twig %} + +{{ + form_widget( + form.recaptcha, { + "attr": { + "options" : { + "theme" : "custom", + }, + } + } + ) +}} +``` + **Further reading**: [Google Official Documentation](https://developers.google.com/recaptcha/docs/start) diff --git a/Resources/config/services.yml b/Resources/config/services.yml index f0669bf..c93e465 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -6,9 +6,9 @@ services: vihuvac_recaptcha.form.type: class: "%vihuvac_recaptcha.form.type.class%" arguments: - - "@service_container" - "%vihuvac_recaptcha.site_key%" - "%vihuvac_recaptcha.enabled%" + - "%vihuvac_recaptcha.ajax%" - "%vihuvac_recaptcha.locale_key%" tags: - { name: form.type, alias: vihuvac_recaptcha } @@ -16,8 +16,9 @@ services: vihuvac_recaptcha.validator.true: class: "%vihuvac_recaptcha.validator.true.class%" arguments: - - "@service_container" - - "%vihuvac_recaptcha.secret_key%" - "%vihuvac_recaptcha.enabled%" + - "%vihuvac_recaptcha.secret_key%" + - "@request_stack" + - "%vihuvac_recaptcha.http_proxy%" tags: - { name: validator.constraint_validator, alias: vihuvac_recaptcha.true } diff --git a/Resources/translations/validators.en.xliff b/Resources/translations/validators.en.xliff deleted file mode 100644 index 86e9f24..0000000 --- a/Resources/translations/validators.en.xliff +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - validate_captcha_value - Please, don't forget to tick the checkbox in the reCAPTCHA. - - - recaptcha_remote_ip - For security reasons, you must pass the remote IP to reCAPTCHA. - - - - diff --git a/Resources/translations/validators.en.yml b/Resources/translations/validators.en.yml new file mode 100644 index 0000000..c800e77 --- /dev/null +++ b/Resources/translations/validators.en.yml @@ -0,0 +1,4 @@ +vihuvac_recaptcha: + validator: + message: Please, don't forget to tick the checkbox in the reCAPTCHA field. + remote_ip: For security reasons, you must pass the Remote IP to reCAPTCHA. diff --git a/Resources/translations/validators.es.xliff b/Resources/translations/validators.es.xliff deleted file mode 100644 index 823049f..0000000 --- a/Resources/translations/validators.es.xliff +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - validate_captcha_value - Por favor, no se olvide de marcar la casilla de verificación en el reCAPTCHA. - - - recaptcha_remote_ip - Por razones de seguridad, debes pasar la IP remota al reCAPTCHA. - - - - diff --git a/Resources/translations/validators.es.yml b/Resources/translations/validators.es.yml new file mode 100644 index 0000000..f155b01 --- /dev/null +++ b/Resources/translations/validators.es.yml @@ -0,0 +1,4 @@ +vihuvac_recaptcha: + validator: + message: Por favor, no olvides de marcar la casilla de verificación en el campo de reCAPTCHA. + remote_ip: Por razones de seguridad, debes pasar la IP Remota al reCAPTCHA. diff --git a/Resources/translations/validators.fr.xliff b/Resources/translations/validators.fr.xliff deleted file mode 100755 index cf39169..0000000 --- a/Resources/translations/validators.fr.xliff +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - validate_captcha_value - Veuillez cliquez sur la case à cocher du reCAPTCHA. - - - recaptcha_remote_ip - Pour des raisons de sécurité, vous devez passer l'IP distante à reCAPTCHA. - - - - diff --git a/Resources/translations/validators.fr.yml b/Resources/translations/validators.fr.yml new file mode 100755 index 0000000..590ae2a --- /dev/null +++ b/Resources/translations/validators.fr.yml @@ -0,0 +1,4 @@ +vihuvac_recaptcha: + validator: + message: Veuillez cliquez sur la case à cocher du reCAPTCHA. + remote_ip: Pour des raisons de sécurité, vous devez passer l'IP Distante à reCAPTCHA. diff --git a/Resources/views/Form/vihuvac_recaptcha_widget.html.php b/Resources/views/Form/vihuvac_recaptcha_widget.html.php index 25e7e34..c2ef480 100644 --- a/Resources/views/Form/vihuvac_recaptcha_widget.html.php +++ b/Resources/views/Form/vihuvac_recaptcha_widget.html.php @@ -10,33 +10,50 @@ #}--> - -
-