Fixing session key, removing valid_keys which was painful to transport

the whitelist in the session (see #36)
This commit is contained in:
Gregwar 2012-12-04 11:33:54 +01:00
parent 39532390e1
commit 31d080a9b7
7 changed files with 42 additions and 12 deletions

View File

@ -24,7 +24,18 @@ class CaptchaController extends Controller
public function generateCaptchaAction(Request $request, $key) public function generateCaptchaAction(Request $request, $key)
{ {
$options = $this->container->getParameter('gregwar_captcha.config'); $options = $this->container->getParameter('gregwar_captcha.config');
if (!$options['as_url'] || !in_array($key, $options['valid_keys'])) { $session = $this->get('session');
$whitelistKey = $options['whitelist_key'];
$isOk = false;
if ($options['as_url'] && $session->has($whitelistKey)) {
$keys = $session->get($whitelistKey);
if (is_array($keys) && in_array($key, $keys)) {
$isOk = true;
}
}
if (!$isOk) {
return $this->createNotFoundException('Unable to generate a captcha via a URL without the proper configuration.'); return $this->createNotFoundException('Unable to generate a captcha via a URL without the proper configuration.');
} }

View File

@ -35,7 +35,7 @@ class Configuration implements ConfigurationInterface
->scalarNode('quality')->defaultValue(15)->end() ->scalarNode('quality')->defaultValue(15)->end()
->scalarNode('invalid_message')->defaultValue('Bad code value')->end() ->scalarNode('invalid_message')->defaultValue('Bad code value')->end()
->scalarNode('bypass_code')->defaultValue(null)->end() ->scalarNode('bypass_code')->defaultValue(null)->end()
->arrayNode('valid_keys')->defaultValue(array('captcha'))->prototype('scalar')->end() ->scalarNode('whitelist_key')->defaultValue('captcha_whitelist_key')->end()
->end() ->end()
; ;

View File

@ -31,6 +31,7 @@ class GregwarCaptchaExtension extends Extension
$container->setParameter('gregwar_captcha.config.web_path', $config['web_path']); $container->setParameter('gregwar_captcha.config.web_path', $config['web_path']);
$container->setParameter('gregwar_captcha.config.gc_freq', $config['gc_freq']); $container->setParameter('gregwar_captcha.config.gc_freq', $config['gc_freq']);
$container->setParameter('gregwar_captcha.config.expiration', $config['expiration']); $container->setParameter('gregwar_captcha.config.expiration', $config['expiration']);
$container->setParameter('gregwar_captcha.config.whitelist_key', $config['whitelist_key']);
$resources = $container->getParameter('twig.form.resources'); $resources = $container->getParameter('twig.form.resources');
$container->setParameter('twig.form.resources', array_merge(array('GregwarCaptchaBundle::captcha.html.twig'), $resources)); $container->setParameter('twig.form.resources', array_merge(array('GregwarCaptchaBundle::captcha.html.twig'), $resources));

View File

@ -16,6 +16,12 @@ class CaptchaGenerator
*/ */
protected $session; protected $session;
/**
* Name of the whitelist key
* @var string
*/
protected $whitelistKey;
/** /**
* @var \Symfony\Component\Routing\RouterInterface * @var \Symfony\Component\Routing\RouterInterface
*/ */
@ -65,7 +71,7 @@ class CaptchaGenerator
* @param int $gcFreq * @param int $gcFreq
* @param int $expiration * @param int $expiration
*/ */
public function __construct(SessionInterface $session, RouterInterface $router, $imageFolder, $webPath, $gcFreq, $expiration) public function __construct(SessionInterface $session, RouterInterface $router, $imageFolder, $webPath, $gcFreq, $expiration, $whitelistKey)
{ {
$this->session = $session; $this->session = $session;
$this->router = $router; $this->router = $router;
@ -73,6 +79,7 @@ class CaptchaGenerator
$this->webPath = $webPath; $this->webPath = $webPath;
$this->gcFreq = $gcFreq; $this->gcFreq = $gcFreq;
$this->expiration = $expiration; $this->expiration = $expiration;
$this->whitelistKey = $whitelistKey;
} }
/** /**
@ -96,6 +103,11 @@ class CaptchaGenerator
// Returns the configured URL for image generation // Returns the configured URL for image generation
if ($options['as_url']) { if ($options['as_url']) {
$keys = $this->session->get($this->whitelistKey, array());
if (!in_array($key, $keys)) {
$keys[] = $key;
}
$this->session->set($this->whitelistKey, $keys);
return $this->router->generate('gregwar_captcha.generate_captcha', array('key' => $key)); return $this->router->generate('gregwar_captcha.generate_captcha', array('key' => $key));
} }

View File

@ -132,7 +132,7 @@ You can define the following configuration options globally or on the CaptchaTyp
* **as_url**: if set to true, a URL will be used in the image tag and will handle captcha generation. This can be used in a multiple-server environment and support IE6/7 (default=false) * **as_url**: if set to true, a URL will be used in the image tag and will handle captcha generation. This can be used in a multiple-server environment and support IE6/7 (default=false)
* **invalid_message**: error message displayed when an non-matching code is submitted (default="Bad code value") * **invalid_message**: error message displayed when an non-matching code is submitted (default="Bad code value")
* **bypass_code**: code that will always validate the captcha (default=null) * **bypass_code**: code that will always validate the captcha (default=null)
* **valid_keys**: names that are able to be used for a captcha form type (default=[captcha]) * **whitelist_key**: the session key to use for keep the session keys that can be used for captcha storage, when using as_url (default=captcha_whitelist_key)
Example : Example :
@ -167,10 +167,7 @@ This will use the bundle's route of "/generate-captcha/{key}" to handle the gene
resource: "@GregwarCaptchaBundle/Resources/config/routing/routing.yml" resource: "@GregwarCaptchaBundle/Resources/config/routing/routing.yml"
prefix: /_gcb prefix: /_gcb
If you are using multiple captchas or assigning names other than the default "captcha", you will need to whitelist your captcha names in the "valid_keys" configuration: Since the session key is transported in the URL, it's also added in another session array, under the `whitelist_key` key, for security reasons
gregwar_captcha:
valid_keys: [registration_captcha, confirmation_captcha]
Form Theming Form Theming
============ ============

View File

@ -19,3 +19,4 @@ services:
- %gregwar_captcha.config.web_path% - %gregwar_captcha.config.web_path%
- %gregwar_captcha.config.gc_freq% - %gregwar_captcha.config.gc_freq%
- %gregwar_captcha.config.expiration% - %gregwar_captcha.config.expiration%
- %gregwar_captcha.config.whitelist_key%

View File

@ -25,6 +25,12 @@ class CaptchaType extends AbstractType
*/ */
protected $session; protected $session;
/**
* The session key
* @var string
*/
protected $key = null;
/** /**
* @var \Gregwar\CaptchaBundle\Generator\CaptchaGenerator * @var \Gregwar\CaptchaBundle\Generator\CaptchaGenerator
*/ */
@ -54,9 +60,11 @@ class CaptchaType extends AbstractType
*/ */
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$this->key = 'gcb_'.$builder->getForm()->getName();
$validator = new CaptchaValidator( $validator = new CaptchaValidator(
$this->session, $this->session,
$builder->getForm()->getName(), $this->key,
$options['invalid_message'], $options['invalid_message'],
$options['bypass_code'] $options['bypass_code']
); );
@ -74,7 +82,7 @@ class CaptchaType extends AbstractType
$view->vars = array_merge($view->vars, array( $view->vars = array_merge($view->vars, array(
'captcha_width' => $options['width'], 'captcha_width' => $options['width'],
'captcha_height' => $options['height'], 'captcha_height' => $options['height'],
'captcha_code' => $this->generator->getCaptchaCode($form->getName(), $options), 'captcha_code' => $this->generator->getCaptchaCode($this->key, $options),
'value' => '', 'value' => '',
)); ));
} }