From 7877c42c763c319b06f5ceb9e8125b77bb4a37f6 Mon Sep 17 00:00:00 2001 From: Matteo Peronnet Date: Thu, 3 May 2018 15:01:18 +0000 Subject: [PATCH 01/27] Adding captcha validation in Javascript --- Resources/config/assetic_injector.json | 2 +- .../views/macros/form_elements.html.twig | 3 - Resources/views/show.html.twig | 60 ++++++++++++------- 3 files changed, 41 insertions(+), 24 deletions(-) delete mode 100644 Resources/views/macros/form_elements.html.twig diff --git a/Resources/config/assetic_injector.json b/Resources/config/assetic_injector.json index 9ca4b33..6802b91 100644 --- a/Resources/config/assetic_injector.json +++ b/Resources/config/assetic_injector.json @@ -9,7 +9,7 @@ }, "stylesheets": { - "victoire_widget_form_recaptcha": "@VictoireWidgetFormBundle/Resources/public/css/recaptcha.css" + "head": "@VictoireWidgetFormBundle/Resources/public/css/recaptcha.css" } } } \ No newline at end of file diff --git a/Resources/views/macros/form_elements.html.twig b/Resources/views/macros/form_elements.html.twig deleted file mode 100644 index 3db3bfe..0000000 --- a/Resources/views/macros/form_elements.html.twig +++ /dev/null @@ -1,3 +0,0 @@ -{% macro recaptcha(siteKey)%} -
-{% endmacro %} diff --git a/Resources/views/show.html.twig b/Resources/views/show.html.twig index 7a9b782..573419a 100644 --- a/Resources/views/show.html.twig +++ b/Resources/views/show.html.twig @@ -1,5 +1,4 @@ {% extends 'VictoireCoreBundle:Widget:show.html.twig' %} -{% import 'VictoireWidgetFormBundle:macros:form_elements.html.twig' as formElements %} {% block content %}

{{ widget.title }}

@@ -135,25 +134,46 @@ {% if recaptcha_public_key is defined %} - {% stylesheets injector="victoire_widget_form_recaptcha" - %} - - {% endstylesheets %} -
-
- {{formElements.recaptcha(recaptcha_public_key)}} - -
+
+ +
+
{% endif %} From 0982f02d973ba0a625a67926747639253fe9f820 Mon Sep 17 00:00:00 2001 From: Matteo Peronnet Date: Fri, 4 May 2018 12:39:21 +0000 Subject: [PATCH 02/27] Refactoring code recaptcha --- Domain/Captcha/Adapter/CaptchaInterface.php | 9 ++++ Domain/Captcha/Adapter/RecaptchaAdapter.php | 53 +++++++++++++++++++ Domain/Captcha/CaptchaHandler.php | 47 ++++++++++++++++ Entity/WidgetForm.php | 20 +------ Form/WidgetFormType.php | 21 ++++---- Resolver/WidgetFormContentResolver.php | 19 ++++--- Resources/config/services.yml | 21 ++++++-- Resources/translations/victoire.en.xliff | 14 +++-- Resources/translations/victoire.es.xliff | 14 +++-- Resources/translations/victoire.fr.xliff | 18 ++++--- .../form/captcha/captchaManager.html.twig | 3 ++ .../views/form/captcha/recaptcha.html.twig | 41 ++++++++++++++ Resources/views/new.html.twig | 8 ++- Resources/views/show.html.twig | 46 +--------------- 14 files changed, 232 insertions(+), 102 deletions(-) create mode 100644 Domain/Captcha/Adapter/CaptchaInterface.php create mode 100644 Domain/Captcha/Adapter/RecaptchaAdapter.php create mode 100644 Domain/Captcha/CaptchaHandler.php create mode 100644 Resources/views/form/captcha/captchaManager.html.twig create mode 100644 Resources/views/form/captcha/recaptcha.html.twig diff --git a/Domain/Captcha/Adapter/CaptchaInterface.php b/Domain/Captcha/Adapter/CaptchaInterface.php new file mode 100644 index 0000000..59e246d --- /dev/null +++ b/Domain/Captcha/Adapter/CaptchaInterface.php @@ -0,0 +1,9 @@ +recaptchaPrivateKey = $recaptchaPrivateKey; + $this->recaptchaPublicKey = $recaptchaPublicKey; + } + + public function validateCaptcha() + { +// $recaptcha = new ReCaptcha($this->recaptchaPrivateKey); +// $resp = $recaptcha->verify($request->request->get('g-recaptcha-response'), $request->getClientIp()); +// +// return $resp->isSuccess(); + return true; + } + + public function getName() + { + return 'recaptcha'; + } + + public function canBeUsed() + { + return $this->recaptchaPublicKey && $this->recaptchaPrivateKey; + } + + /** + * @return mixed + */ + public function getRecaptchaPrivateKey() + { + return $this->recaptchaPrivateKey; + } + + /** + * @return mixed + */ + public function getRecaptchaPublicKey() + { + return $this->recaptchaPublicKey; + } +} \ No newline at end of file diff --git a/Domain/Captcha/CaptchaHandler.php b/Domain/Captcha/CaptchaHandler.php new file mode 100644 index 0000000..9cac756 --- /dev/null +++ b/Domain/Captcha/CaptchaHandler.php @@ -0,0 +1,47 @@ +adapters = $adapters; + $this->translator = $translator; + } + + public function getCaptcha($name) { + foreach ($this->adapters as $adapter) { + if($adapter->getName() === $name) { + return $adapter; + } + } + return null; + } + + public function getNameOfAllAvailableCaptcha () { + $listAvailableCaptcha = []; + $labelNone = $this->translator->trans('widget_form.form.captcha.none', [], 'victoire'); + $listAvailableCaptcha[$labelNone] = $labelNone; + + foreach ($this->adapters as $adapter) { + if($adapter->canBeUsed()) { + $listAvailableCaptcha[$adapter->getName()] = $adapter->getName(); + } + } + return $listAvailableCaptcha; + } +} \ No newline at end of file diff --git a/Entity/WidgetForm.php b/Entity/WidgetForm.php index 2748518..820cb79 100644 --- a/Entity/WidgetForm.php +++ b/Entity/WidgetForm.php @@ -112,9 +112,9 @@ class WidgetForm extends Widget /** * @var bool * - * @ORM\Column(name="recaptcha", type="boolean", nullable=true) + * @ORM\Column(name="captcha", type="string", nullable=true) */ - protected $recaptcha; + protected $captcha; /** * @var string @@ -772,21 +772,5 @@ public function setSubmitClass($submitClass) $this->submitClass = $submitClass; } - /** - * @return bool - */ - public function isRecaptcha() - { - return $this->recaptcha; - } - /** - * @param bool $recaptcha - * @return WidgetForm - */ - public function setRecaptcha($recaptcha) - { - $this->recaptcha = $recaptcha; - return $this; - } } diff --git a/Form/WidgetFormType.php b/Form/WidgetFormType.php index dfdbba9..d8f005a 100644 --- a/Form/WidgetFormType.php +++ b/Form/WidgetFormType.php @@ -13,8 +13,8 @@ use Victoire\Bundle\FormBundle\Form\Type\FontAwesomePickerType; use Victoire\Bundle\FormBundle\Form\Type\LinkType; use Victoire\Bundle\MediaBundle\Form\Type\MediaType; +use Victoire\Widget\FormBundle\Domain\Captcha\CaptchaHandler; use Victoire\Widget\FormBundle\Entity\WidgetFormQuestion; -use Victoire\Widget\FormBundle\Helper\RecaptchaHelper; /** * WidgetForm form type. @@ -22,15 +22,15 @@ class WidgetFormType extends WidgetType { private $formPrefill; - private $recaptchaHelper; + private $captchaHandler; /** * Constructor. */ - public function __construct($formPrefill, RecaptchaHelper $recaptchaHelper) + public function __construct($formPrefill, CaptchaHandler $captchaHandler) { $this->formPrefill = $formPrefill; - $this->recaptchaHelper = $recaptchaHelper; + $this->captchaHandler = $captchaHandler; } /** @@ -173,12 +173,13 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'label' => 'widget_form.form.errorMessage.label', 'required' => false, ] - ); - if ($this->recaptchaHelper->canUseReCaptcha()) { - $builder->add('recaptcha', null, [ - 'label' => 'widget_form.form.captcha.label', - ]); - } + ) + ->add('captcha', ChoiceType::class, [ + 'label' => 'widget_form.form.captcha.label', + 'choices' => $this->captchaHandler->getNameOfAllAvailableCaptcha(), + 'choice_value' => function ($choice) { return $choice; }, + ]); + if ($this->formPrefill) { $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { $widgetFormSlot = $event->getData(); diff --git a/Resolver/WidgetFormContentResolver.php b/Resolver/WidgetFormContentResolver.php index 007ca06..9c83ba8 100644 --- a/Resolver/WidgetFormContentResolver.php +++ b/Resolver/WidgetFormContentResolver.php @@ -4,18 +4,21 @@ use Victoire\Bundle\WidgetBundle\Model\Widget; use Victoire\Bundle\WidgetBundle\Resolver\BaseWidgetContentResolver; +use Victoire\Widget\FormBundle\Domain\Captcha\Adapter\RecaptchaAdapter; +use Victoire\Widget\FormBundle\Domain\Captcha\CaptchaHandler; use Victoire\Widget\FormBundle\Entity\WidgetForm; use Victoire\Widget\FormBundle\Helper\RecaptchaHelper; class WidgetFormContentResolver extends BaseWidgetContentResolver { - protected $recaptchaPublicKey; - protected $recaptchaHelper; + /** + * @var CaptchaHandler + */ + protected $captchaHandler; - public function __construct($recaptchaPublicKey, RecaptchaHelper $recaptchaHelper) + public function __construct(CaptchaHandler $captchaHandler) { - $this->recaptchaPublicKey = $recaptchaPublicKey; - $this->recaptchaHelper = $recaptchaHelper; + $this->captchaHandler = $captchaHandler; } /** @@ -76,8 +79,10 @@ public function getWidgetQueryContent(Widget $widget) protected function addRecaptchaKey(WidgetForm $widget, array $parameters) { - if ($widget->isRecaptcha() && $this->recaptchaHelper->canUseReCaptcha()) { - return array_merge($parameters, ['recaptcha_public_key' => $this->recaptchaPublicKey]); + $captchaAdapter = $this->captchaHandler->getCaptcha($widget->getCaptcha()); + if ($captchaAdapter instanceof RecaptchaAdapter) { + /** @var $captchaAdapter RecaptchaAdapter*/ + return array_merge($parameters, ['recaptcha_public_key' => $captchaAdapter->getRecaptchaPublicKey()]); } return $parameters; diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 812d4e5..c2a4993 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -3,8 +3,7 @@ services: parent: victoire_widget.base_widget_content_resolver class: Victoire\Widget\FormBundle\Resolver\WidgetFormContentResolver arguments: - - '%victoire_widget_form.recaptcha_public_key%' - - '@victoire.form_widget.helper.recaptcha' + - '@victoire.form_widget.domain.captcha.handler' tags: - { name: victoire_widget.widget_content_resolver, alias: Form } @@ -17,7 +16,7 @@ services: class: Victoire\Widget\FormBundle\Form\WidgetFormType arguments: - %victoire_widget_form.prefill% - - '@victoire.form_widget.helper.recaptcha' + - '@victoire.form_widget.domain.captcha.handler' tags: - { name: form.type } @@ -31,3 +30,19 @@ services: class: Victoire\Widget\FormBundle\Twig\WidgetFormExtension tags: - { name: twig.extension } + + # Domain + + victoire.form_widget.domain.captcha.handler: + class: Victoire\Widget\FormBundle\Domain\Captcha\CaptchaHandler + arguments: + - !tagged victoire.form_widget.captcha.adapter + - '@translator' + + victoire.form_widget.domain.captcha.adapter.recaptcha: + class: Victoire\Widget\FormBundle\Domain\Captcha\Adapter\RecaptchaAdapter + arguments: + - '%victoire_widget_form.recaptcha_private_key%' + - '%victoire_widget_form.recaptcha_public_key%' + tags: + - 'victoire.form_widget.captcha.adapter' diff --git a/Resources/translations/victoire.en.xliff b/Resources/translations/victoire.en.xliff index 96da2b7..fcd40e9 100644 --- a/Resources/translations/victoire.en.xliff +++ b/Resources/translations/victoire.en.xliff @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -66,11 +66,17 @@ widget_form.form.captcha.error Captcha is not valid /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Controller/FormController.php + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/show.html.twig widget_form.form.captcha.label Captcha - /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Form/WidgetFormType.php + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Form/WidgetFormType.php + + + widget_form.form.captcha.none + None + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Domain/Captcha/CaptchaHandler.php widget_form.form.choice.style.label.danger @@ -115,7 +121,7 @@ widget_form.form.message.help_block  You can use the form's variables using the following format : {{Name}}

]]>
- /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig
widget_form.form.message.label @@ -155,7 +161,7 @@ widget_form.form.question.new.label  Add a new question]]> - /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig widget_form.form.question.prefix.label diff --git a/Resources/translations/victoire.es.xliff b/Resources/translations/victoire.es.xliff index ed55d3e..22ab48c 100644 --- a/Resources/translations/victoire.es.xliff +++ b/Resources/translations/victoire.es.xliff @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -66,11 +66,17 @@ widget_form.form.captcha.error No válido captcha /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Controller/FormController.php + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/show.html.twig widget_form.form.captcha.label Captcha - /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Form/WidgetFormType.php + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Form/WidgetFormType.php + + + widget_form.form.captcha.none + No + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Domain/Captcha/CaptchaHandler.php widget_form.form.choice.style.label.danger @@ -115,7 +121,7 @@ widget_form.form.message.help_block  Puede utilizar las variables en la forma que rodea el nombre con dobles llaves : {{Nombre}}

]]>
- /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig
widget_form.form.message.label @@ -155,7 +161,7 @@ widget_form.form.question.new.label  Añadir una nueva pregunta]]> - /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig widget_form.form.question.prefix.label diff --git a/Resources/translations/victoire.fr.xliff b/Resources/translations/victoire.fr.xliff index 1b013f4..ab36023 100644 --- a/Resources/translations/victoire.fr.xliff +++ b/Resources/translations/victoire.fr.xliff @@ -1,6 +1,6 @@ - +
The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message. @@ -66,11 +66,17 @@ widget_form.form.captcha.error Le captcha n'est pas valide /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Controller/FormController.php + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/show.html.twig widget_form.form.captcha.label Captcha - /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Form/WidgetFormType.php + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Form/WidgetFormType.php + + + widget_form.form.captcha.none + Aucun + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Domain/Captcha/CaptchaHandler.php widget_form.form.choice.style.label.danger @@ -115,7 +121,7 @@ widget_form.form.message.help_block  Vous pouvez utiliser les variables présentes dans le formulaire en entourant le nom par des doubles accolades : {{Nom}}

]]>
- /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig
widget_form.form.message.label @@ -129,7 +135,7 @@ widget_form.form.proposal.new.label - Ajouter une proposition + Ajouter une proposition /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/formCreatorQuestion.html.twig @@ -154,8 +160,8 @@ widget_form.form.question.new.label -  Ajouter une nouvelle question]]> - /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig +  Ajouter une nouvelle question]]> + /../vendor/victoire/form-widget/Victoire/Widget/FormBundle/Resources/views/new.html.twig widget_form.form.question.prefix.label diff --git a/Resources/views/form/captcha/captchaManager.html.twig b/Resources/views/form/captcha/captchaManager.html.twig new file mode 100644 index 0000000..2ae6fb4 --- /dev/null +++ b/Resources/views/form/captcha/captchaManager.html.twig @@ -0,0 +1,3 @@ +{% if widget.captcha == 'recaptcha' %} + {% include '@VictoireWidgetForm/form/captcha/recaptcha.html.twig' %} +{% endif %} \ No newline at end of file diff --git a/Resources/views/form/captcha/recaptcha.html.twig b/Resources/views/form/captcha/recaptcha.html.twig new file mode 100644 index 0000000..672e232 --- /dev/null +++ b/Resources/views/form/captcha/recaptcha.html.twig @@ -0,0 +1,41 @@ +
+ +
+ +
\ No newline at end of file diff --git a/Resources/views/new.html.twig b/Resources/views/new.html.twig index a368216..a7f32e7 100644 --- a/Resources/views/new.html.twig +++ b/Resources/views/new.html.twig @@ -17,6 +17,9 @@ {{ form_row(form.submitIcon) }} {{ form_row(form.submitClass) }}
+
+ {{ form_row(form.captcha) }} +
{{ form_row(form.successCallback) }} @@ -29,11 +32,6 @@ {{ form_row(form.targetEmail) }} {{ form_row(form.adminSubject) }}
- {% if form.recaptcha is defined %} -
- {{ form_row(form.recaptcha) }} -
- {% endif %} {% set params = (form.autoAnswer.vars.checked == 'on' ? 'true' : '') %} {{ form_row(form.autoAnswer, {'attr': {'onclick' : 'showTargetField()'}, value : params }) }}
diff --git a/Resources/views/show.html.twig b/Resources/views/show.html.twig index 573419a..56d3ca1 100644 --- a/Resources/views/show.html.twig +++ b/Resources/views/show.html.twig @@ -132,51 +132,7 @@ {% endif %} {% endfor %}
- - {% if recaptcha_public_key is defined %} -
- -
- -
- {% endif %} - + {% include '@VictoireWidgetForm/form/captcha/captchaManager.html.twig' %}
+{% endif %} From 2bea5d05954d842ac0370785ec7c63a4f72c53b5 Mon Sep 17 00:00:00 2001 From: Matteo Peronnet Date: Mon, 7 May 2018 14:24:51 +0000 Subject: [PATCH 04/27] Adding captcha by ip with iphub --- Domain/Captcha/Adapter/IpHubAdapter.php | 77 +++++++++++++++++++++++++ Resources/config/services.yml | 8 +++ 2 files changed, 85 insertions(+) create mode 100644 Domain/Captcha/Adapter/IpHubAdapter.php diff --git a/Domain/Captcha/Adapter/IpHubAdapter.php b/Domain/Captcha/Adapter/IpHubAdapter.php new file mode 100644 index 0000000..ec45b72 --- /dev/null +++ b/Domain/Captcha/Adapter/IpHubAdapter.php @@ -0,0 +1,77 @@ +iphubPrivateKey = $iphubPrivateKey; + $this->requestStack = $requestStack; + } + + /** + * Check if the captcha is valid or not + * @return boolean + */ + public function validateCaptcha() + { + $request = $this->requestStack->getCurrentRequest(); + return !$this->isBadIP($request->getClientIp(), $this->iphubPrivateKey); + } + + /** + * Get the captcha name + * @return string + */ + public function getName() + { + return 'iphub'; + } + + /** + * Check if current configuration allow to use this captcha + * @return boolean + */ + public function canBeUsed() + { + return $this->iphubPrivateKey; + } + + /** + * Return all parameters necessary in the view + * @return array + */ + public function getTwigParameters() + { + return []; + } + + private function isBadIP($ip, $key, $strict = false) { + $ch = curl_init(); + curl_setopt_array($ch, [ + CURLOPT_URL => "http://v2.api.iphub.info/ip/{$ip}", + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HTTPHEADER => ["X-Key: {$key}"] + ]); + + try { + $block = json_decode(curl_exec($ch))->block; + } catch (Exception $e) { + throw $e; + } + if ($block) { + if ($strict) { + return true; + } elseif (!$strict && $block === 1) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/Resources/config/services.yml b/Resources/config/services.yml index a50b5f9..a71f0dd 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -38,5 +38,13 @@ services: - '%victoire_widget_form.recaptcha_private_key%' - '%victoire_widget_form.recaptcha_public_key%' - '@request_stack' + tags: + - 'victoire.form_widget.captcha.adapter' + + victoire.form_widget.domain.captcha.adapter.iphub: + class: Victoire\Widget\FormBundle\Domain\Captcha\Adapter\IpHubAdapter + arguments: + - 'MjE5MTpDTnFHWEVBRlRyb3l6WnRVOGpGS1g1V2hoZ0VUSTJMeA==' + - '@request_stack' tags: - 'victoire.form_widget.captcha.adapter' \ No newline at end of file From 863cb502f3ce1cf514a21da876de6f0eca63ac0a Mon Sep 17 00:00:00 2001 From: Matteo Peronnet Date: Mon, 7 May 2018 14:35:06 +0000 Subject: [PATCH 05/27] Update composer.json, adding securimage --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index dbe4220..fbb07c2 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,8 @@ "victoire/victoire": "~2.3 | ~3.0", "troopers/alertify-bundle": "~3.0", "egeloen/ckeditor-bundle": "~4.0", - "google/recaptcha": "~1.1" + "google/recaptcha": "~1.1", + "dapphp/securimage": "^4.0" }, "suggest": { "ornicar/akismet-bundle": "Analyze form content thanks to akismet" From ce65c1729e5398a3567b710f7b06fdb4e7654da4 Mon Sep 17 00:00:00 2001 From: Matteo Peronnet Date: Mon, 14 May 2018 12:16:43 +0000 Subject: [PATCH 06/27] Adding securimage captcha --- Controller/FormController.php | 1 - Domain/Captcha/Adapter/SecurimageAdapter.php | 107 ++++++++++++++++++ Resources/config/config.yml | 2 +- Resources/config/services.yml | 7 ++ .../form/captcha/captchaManager.html.twig | 3 + .../views/form/captcha/securimage.html.twig | 10 ++ 6 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 Domain/Captcha/Adapter/SecurimageAdapter.php create mode 100644 Resources/views/form/captcha/securimage.html.twig diff --git a/Controller/FormController.php b/Controller/FormController.php index 14433fd..598c346 100644 --- a/Controller/FormController.php +++ b/Controller/FormController.php @@ -10,7 +10,6 @@ use Symfony\Component\Validator\Constraints\Email as EmailConstraint; use Troopers\AlertifyBundle\Controller\AlertifyControllerTrait; use Victoire\Bundle\MediaBundle\Entity\Media; -use Victoire\Widget\FormBundle\Domain\Captcha\Adapter\CaptchaInterface; use Victoire\Widget\FormBundle\Domain\Captcha\CaptchaHandler; use Victoire\Widget\FormBundle\Entity\WidgetForm; use Victoire\Widget\FormBundle\Event\WidgetFormeMailEvent; diff --git a/Domain/Captcha/Adapter/SecurimageAdapter.php b/Domain/Captcha/Adapter/SecurimageAdapter.php new file mode 100644 index 0000000..91d96ec --- /dev/null +++ b/Domain/Captcha/Adapter/SecurimageAdapter.php @@ -0,0 +1,107 @@ +requestStack = $requestStack; + } + + /** + * Checks if the captcha is valid or not. + * Then delete it from session if captcha is valid + * + * @param bool $clear + * @return bool + */ + public function validateCaptcha($clear=true) + { + $request = $this->requestStack->getCurrentRequest()->request; + $securimage_namespace = $request->get('securimage_namespace'); + $code = $request->get('securimage_code'); + $sc = $this->getSerurimageInstance($securimage_namespace); + + if($clear) { + return $sc->check($code); + } else { + return $sc->getCode() === $code; + } + } + + /** + * Get the captcha name. + * + * @return string + */ + public function getName() + { + return 'securimage'; + } + + /** + * Check if current configuration allow to use this captcha. + * + * @return bool + */ + public function canBeUsed() + { + return true; + } + + /** + * Return all parameters necessary in the view. + * + * @return array + */ + public function getTwigParameters() + { + $namespace = md5(uniqid(rand(), true)); + $sc = $this->getSerurimageInstance($namespace); + + ob_start(); + $sc->show(); + $imageData = ob_get_contents(); + ob_end_clean(); + + $imageStr = base64_encode($imageData); + + return [ + 'securimage_html' => $imageStr, + 'securimage_namespace' => $namespace, + ]; + } + + /** + * @return Securimage + * + * @param mixed $namespace + */ + private function getSerurimageInstance($namespace) + { + $sc = new Securimage($this->getSecurimageParameters()); + $sc->setNamespace($namespace); + + return $sc; + } + + private function getSecurimageParameters() + { + return [ + 'no_session' => false, + 'use_database' => false, + 'no_exit' => true, + 'image_width' => 275, + 'code_length' => mt_rand(4, 6), + ]; + } +} diff --git a/Resources/config/config.yml b/Resources/config/config.yml index 15a228e..5847be1 100644 --- a/Resources/config/config.yml +++ b/Resources/config/config.yml @@ -3,7 +3,7 @@ victoire_core: Form: class: "Victoire\\Widget\\FormBundle\\Entity\\WidgetForm" name: Form - + cache: false jms_translation: configs: victoire_form_bundle: diff --git a/Resources/config/services.yml b/Resources/config/services.yml index a71f0dd..1824456 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -46,5 +46,12 @@ services: arguments: - 'MjE5MTpDTnFHWEVBRlRyb3l6WnRVOGpGS1g1V2hoZ0VUSTJMeA==' - '@request_stack' + tags: + - 'victoire.form_widget.captcha.adapter' + + victoire.form_widget.domain.captcha.adapter.securimage: + class: Victoire\Widget\FormBundle\Domain\Captcha\Adapter\SecurimageAdapter + arguments: + - '@request_stack' tags: - 'victoire.form_widget.captcha.adapter' \ No newline at end of file diff --git a/Resources/views/form/captcha/captchaManager.html.twig b/Resources/views/form/captcha/captchaManager.html.twig index cc2b342..f02286a 100644 --- a/Resources/views/form/captcha/captchaManager.html.twig +++ b/Resources/views/form/captcha/captchaManager.html.twig @@ -1,3 +1,6 @@ {% if widget.captcha == 'recaptcha' %} {% include '@VictoireWidgetForm/form/captcha/recaptcha.html.twig' %} +{% elseif widget.captcha == 'securimage' %} + {% include '@VictoireWidgetForm/form/captcha/securimage.html.twig' %} +{% else %} {% endif %} diff --git a/Resources/views/form/captcha/securimage.html.twig b/Resources/views/form/captcha/securimage.html.twig new file mode 100644 index 0000000..28c86b9 --- /dev/null +++ b/Resources/views/form/captcha/securimage.html.twig @@ -0,0 +1,10 @@ +
+
+ Captcha Image + +
+ + +
+
+
From 53ddfe6611b7cd3e1b923d4ac0bb6850c06ffadf Mon Sep 17 00:00:00 2001 From: Matteo Peronnet Date: Mon, 14 May 2018 15:39:49 +0000 Subject: [PATCH 07/27] Adding validation securimage in ajax --- Controller/CaptchaController.php | 42 +++++++++++++++++++ Domain/Captcha/Adapter/SecurimageAdapter.php | 38 ++++++++++++----- Resources/config/services.yml | 7 +++- .../views/form/captcha/securimage.html.twig | 37 ++++++++++++++-- Resources/views/show.html.twig | 2 +- 5 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 Controller/CaptchaController.php diff --git a/Controller/CaptchaController.php b/Controller/CaptchaController.php new file mode 100644 index 0000000..652bb94 --- /dev/null +++ b/Controller/CaptchaController.php @@ -0,0 +1,42 @@ +validateCaptcha(false)) { + $data = $securimage->generateNewImage(); + $data['valid'] = false; + } else { + $data['valid'] = true; + } + + return new JsonResponse($data); + } +} diff --git a/Domain/Captcha/Adapter/SecurimageAdapter.php b/Domain/Captcha/Adapter/SecurimageAdapter.php index 91d96ec..bc5e942 100644 --- a/Domain/Captcha/Adapter/SecurimageAdapter.php +++ b/Domain/Captcha/Adapter/SecurimageAdapter.php @@ -3,39 +3,40 @@ namespace Victoire\Widget\FormBundle\Domain\Captcha\Adapter; use Securimage; -use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Request; class SecurimageAdapter implements CaptchaInterface { /** - * @var RequestStack + * @var Request */ - private $requestStack; + private $request; - public function __construct(RequestStack $requestStack) + public function __construct(Request $request) { - $this->requestStack = $requestStack; + $this->request = $request; } /** * Checks if the captcha is valid or not. - * Then delete it from session if captcha is valid + * Then delete it from session if captcha is valid. * * @param bool $clear + * * @return bool */ - public function validateCaptcha($clear=true) + public function validateCaptcha($clear = true) { - $request = $this->requestStack->getCurrentRequest()->request; + $request = $this->request->request; $securimage_namespace = $request->get('securimage_namespace'); $code = $request->get('securimage_code'); $sc = $this->getSerurimageInstance($securimage_namespace); - if($clear) { + if ($clear) { return $sc->check($code); - } else { - return $sc->getCode() === $code; } + + return strtolower($sc->getCode()) === strtolower($code); } /** @@ -64,6 +65,16 @@ public function canBeUsed() * @return array */ public function getTwigParameters() + { + return $this->generateNewImage(); + } + + /** + * Return a new Image encoded in base64 and his namespace. + * + * @return array + */ + public function generateNewImage() { $namespace = md5(uniqid(rand(), true)); $sc = $this->getSerurimageInstance($namespace); @@ -94,6 +105,11 @@ private function getSerurimageInstance($namespace) return $sc; } + /** + * Return all parameters to instanciate Securimage. + * + * @return array + */ private function getSecurimageParameters() { return [ diff --git a/Resources/config/services.yml b/Resources/config/services.yml index 1824456..f0014d8 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -25,6 +25,11 @@ services: tags: - { name: twig.extension } + #Controller +# victoire.widget.form.controller.form: +# class: Victoire\Widget\FormBundle\Controller\FormController +# arguments: ["@victoire.form_widget.domain.captcha.handler"] + # Domain victoire.form_widget.domain.captcha.handler: @@ -52,6 +57,6 @@ services: victoire.form_widget.domain.captcha.adapter.securimage: class: Victoire\Widget\FormBundle\Domain\Captcha\Adapter\SecurimageAdapter arguments: - - '@request_stack' + - "@=service('request_stack').getCurrentRequest()" tags: - 'victoire.form_widget.captcha.adapter' \ No newline at end of file diff --git a/Resources/views/form/captcha/securimage.html.twig b/Resources/views/form/captcha/securimage.html.twig index 28c86b9..8f8ed91 100644 --- a/Resources/views/form/captcha/securimage.html.twig +++ b/Resources/views/form/captcha/securimage.html.twig @@ -1,10 +1,41 @@
+
- Captcha Image + Captcha Image
- - + +
+
diff --git a/Resources/views/show.html.twig b/Resources/views/show.html.twig index 56d3ca1..e36467e 100644 --- a/Resources/views/show.html.twig +++ b/Resources/views/show.html.twig @@ -131,8 +131,8 @@ {% endif %} {% endfor %} - {% include '@VictoireWidgetForm/form/captcha/captchaManager.html.twig' %} +