-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from Matteo-Peronnet/fix-captcha-validation
Adding several captchas
- Loading branch information
Showing
35 changed files
with
1,091 additions
and
495 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
namespace Victoire\Widget\FormBundle\Controller; | ||
|
||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; | ||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | ||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | ||
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | ||
use Symfony\Component\HttpFoundation\JsonResponse; | ||
use Symfony\Component\HttpFoundation\RedirectResponse; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Victoire\Widget\FormBundle\Domain\Captcha\Adapter\CaptchaInterface; | ||
use Victoire\Widget\FormBundle\Domain\Captcha\Adapter\SecurimageAdapter; | ||
use Victoire\Widget\FormBundle\Entity\WidgetForm; | ||
|
||
/** | ||
* Class CaptchaController. | ||
* | ||
* @Route("/_victoire_form_captcha") | ||
*/ | ||
class CaptchaController extends Controller | ||
{ | ||
|
||
/** | ||
* @Route("/validate/captcha/{widget_form_id}", name="victoire_form_captcha_validate") | ||
* @ParamConverter("widget", class="VictoireWidgetFormBundle:WidgetForm", options={"id" = "widget_form_id"}) | ||
* @param Request $request | ||
* @return \Symfony\Component\HttpFoundation\Response | ||
*/ | ||
public function validateCaptchaAjaxAction(Request $request, WidgetForm $widget) { | ||
|
||
$captchaHandler = $this->get('victoire.form_widget.domain.captcha.handler'); | ||
try { | ||
/** @var $captchaAdapter CaptchaInterface */ | ||
$captchaAdapter = $captchaHandler->getCaptcha($widget->getCaptcha(), true); | ||
} catch (\Exception $e) { | ||
throw $this->createNotFoundException(); | ||
} | ||
|
||
$data = []; | ||
if(!$captchaAdapter->validateCaptcha($request, false)) { | ||
$captchaAdapter->generateNewCaptcha(); | ||
$data = $captchaAdapter->getTwigParameters(); | ||
$data['valid'] = false; | ||
} else { | ||
$data['valid'] = true; | ||
} | ||
|
||
return new JsonResponse($data); | ||
} | ||
|
||
/** | ||
* @Route("/render/captcha/{widget_form_id}", name="victoire_form_captcha_render") | ||
* @ParamConverter("widget", class="VictoireWidgetFormBundle:WidgetForm", options={"id" = "widget_form_id"}) | ||
* @param Request $request | ||
* @return \Symfony\Component\HttpFoundation\Response | ||
*/ | ||
public function rendererCaptchaAction(Request $request, WidgetForm $widget) { | ||
|
||
$captchaHandler = $this->get('victoire.form_widget.domain.captcha.handler'); | ||
try { | ||
/** @var $captchaAdapter CaptchaInterface */ | ||
$captchaAdapter = $captchaHandler->getCaptcha($widget->getCaptcha(), true, true); | ||
} catch (\Exception $e) { | ||
throw $this->createNotFoundException(); | ||
} | ||
|
||
return $this->render($captchaAdapter->getViewPath(), array_merge(['widget' => $widget], $captchaAdapter->getTwigParameters())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
namespace Victoire\Widget\FormBundle\Domain\Captcha\Adapter; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
abstract class AbstractCaptcha implements CaptchaInterface { | ||
|
||
/** | ||
* Check if the captcha is valid or not | ||
* @param Request $request | ||
* @param bool $clear | ||
* @return bool | ||
*/ | ||
abstract public function validateCaptcha($request, $clear = true); | ||
|
||
/** | ||
* Get the captcha name | ||
* @return string | ||
*/ | ||
abstract public function getName(); | ||
|
||
/** | ||
* Check if current configuration allow to use this captcha | ||
* @return boolean | ||
*/ | ||
public function canBeUsed() | ||
{ | ||
return true; | ||
} | ||
|
||
/** | ||
* Return all parameters necessary in the view | ||
* @return array | ||
*/ | ||
public function getTwigParameters() | ||
{ | ||
return []; | ||
} | ||
|
||
/** | ||
* Return the view path to render the widget | ||
*/ | ||
public function getViewPath() | ||
{ | ||
return; | ||
} | ||
|
||
/** | ||
* Regenerate a new Captcha | ||
* @return mixed | ||
*/ | ||
public function generateNewCaptcha() { | ||
return; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?php | ||
|
||
namespace Victoire\Widget\FormBundle\Domain\Captcha\Adapter; | ||
|
||
interface CaptchaCodeInterface | ||
{ | ||
/** | ||
* Get captcha Code by namespace | ||
* @param $namespace | ||
* @return mixed | ||
*/ | ||
public function getCaptchaCode($namespace); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
namespace Victoire\Widget\FormBundle\Domain\Captcha\Adapter; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
interface CaptchaInterface | ||
{ | ||
/** | ||
* Check if the captcha is valid or not | ||
* @param Request $request | ||
* @param bool $clear | ||
* @return bool | ||
*/ | ||
public function validateCaptcha($request, $clear = true); | ||
|
||
/** | ||
* Get the captcha name | ||
* @return string | ||
*/ | ||
public function getName(); | ||
|
||
/** | ||
* Check if current configuration allow to use this captcha | ||
* @return boolean | ||
*/ | ||
public function canBeUsed(); | ||
|
||
/** | ||
* Return all parameters necessary in the view | ||
* @return array | ||
*/ | ||
public function getTwigParameters(); | ||
|
||
/** | ||
* Return the view path to render the widget | ||
*/ | ||
public function getViewPath(); | ||
|
||
/** | ||
* Regenerate a new Captcha | ||
* @return mixed | ||
*/ | ||
public function generateNewCaptcha(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
namespace Victoire\Widget\FormBundle\Domain\Captcha\Adapter; | ||
|
||
use Gregwar\Captcha\CaptchaBuilder; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | ||
|
||
class GregwarCaptchaAdapter extends AbstractCaptcha implements CaptchaCodeInterface { | ||
|
||
/** | ||
* @var CaptchaBuilder | ||
*/ | ||
private $captchaBuilder; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $namespace; | ||
|
||
/** | ||
* @var SessionInterface | ||
*/ | ||
private $session; | ||
|
||
public function __construct(SessionInterface $session, $env) | ||
{ | ||
$this->session = $session; | ||
|
||
if ($this->canBeUsed()) { | ||
$phrase = ($env === 'ci' || $env === 'test') ? "correctly" : null; | ||
$this->captchaBuilder = new CaptchaBuilder($phrase); | ||
$this->generateNewCaptcha(); | ||
} | ||
} | ||
|
||
/** | ||
* Check if the captcha is valid or not | ||
* @param Request $request | ||
* @param bool $clear | ||
* @return bool | ||
*/ | ||
public function validateCaptcha($request, $clear = true) | ||
{ | ||
$code = $request->get('captcha_code'); | ||
$namespace = $request->get('captcha_namespace'); | ||
$codeDisplay = $this->getCaptchaCode($namespace); | ||
if ($clear) { | ||
$this->session->remove($namespace); | ||
} | ||
|
||
return strtolower($code) === strtolower($codeDisplay); | ||
} | ||
|
||
/** | ||
* Get the captcha name | ||
* @return string | ||
*/ | ||
public function getName() | ||
{ | ||
return 'GregwarCaptcha'; | ||
} | ||
|
||
public function getTwigParameters() { | ||
return [ | ||
'captcha_image' => $this->captchaBuilder->inline(), | ||
'captcha_namespace' => $this->namespace | ||
]; | ||
} | ||
|
||
/** | ||
* Check if current configuration allow to use this captcha | ||
* @return boolean | ||
*/ | ||
public function canBeUsed() | ||
{ | ||
return extension_loaded('gd'); | ||
} | ||
|
||
/** | ||
* Regenerate a new Captcha | ||
* @return mixed | ||
*/ | ||
public function generateNewCaptcha() { | ||
$this->setNamespace($this->generateCaptchaNamespace()); | ||
$this->captchaBuilder->build(); | ||
$this->session->set($this->getNamespace(), $this->captchaBuilder->getPhrase()); | ||
} | ||
|
||
/** | ||
* Return the view path to render the widget | ||
*/ | ||
public function getViewPath() | ||
{ | ||
return '@VictoireWidgetForm/form/captcha/captcha.html.twig'; | ||
} | ||
|
||
/** | ||
* Generate an unique id for the captcha namespace | ||
* @return string | ||
*/ | ||
private function generateCaptchaNamespace() { | ||
return md5(uniqid(rand(), true)); | ||
} | ||
|
||
/** | ||
* @param string $namespace | ||
*/ | ||
public function setNamespace($namespace) | ||
{ | ||
$this->namespace = $namespace; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getNamespace() | ||
{ | ||
return $this->namespace; | ||
} | ||
|
||
/** | ||
* Get captcha Code by namespace | ||
* @param $namespace | ||
* @return mixed | ||
*/ | ||
public function getCaptchaCode($namespace) | ||
{ | ||
return $this->session->get($namespace); | ||
} | ||
} |
Oops, something went wrong.