Compare commits

...

2 Commits

Author SHA1 Message Date
Abel Hoogeveen a2f3165e24
Fixed bug where CSRF-tokens are not replaced in cached forms.
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
- A bug was discovered where cached forms always would contain the same CSRF-token. This would prevent the hidden token from being replaced, resulting in CSRF-errors in WebComponent on every POST-request.
2023-03-06 21:23:27 +01:00
Abel Hoogeveen c134339526 Fixed bug with option fields.
continuous-integration/drone/push Build is passing Details
If the addOptions() method was used on RadioField or SelectField, and the array was provided as numeric, it would wrongly get added as numeric and values would not be associated correctly with their options. This was especially troublesome for the first element in the options array, as that element would be impossible to select.
2023-02-09 15:37:54 +01:00
3 changed files with 60 additions and 1 deletions

View File

@ -75,6 +75,9 @@ class RadioField extends Field
*/
public function addOptions(array $options): self
{
if (!$this->_isAssoc($options))
throw new InputException("Could not add options. Options must be provided as an associative array [name => label]");
foreach ($options as $key => $val)
$this->addOption($key, $val);
@ -134,4 +137,16 @@ class RadioField extends Field
$out .= "</div>";
return $out;
}
/**
* Internal method for addOptions()
*
* @param array $arr
* @return bool
*/
private function _isAssoc(array $arr): bool
{
if (array() === $arr) return false;
return array_keys($arr) !== range(0, count($arr) - 1);
}
}

View File

@ -43,6 +43,7 @@ use FuzeWorks\Logger;
use FuzeWorks\ObjectStorage\ObjectStorageCache;
use FuzeWorks\ObjectStorage\ObjectStorageComponent;
use FuzeWorks\Priority;
use FuzeWorks\Security;
class Forms implements iLibrary
{
@ -98,7 +99,19 @@ class Forms implements iLibrary
if ($cache->has($key))
{
Logger::log("Returning cached Form '".$name."'");
return $cache->get($key);
/** @var Form $form */
$form = $cache->get($key);
$csrf = $form->getCsrfField();
if (!is_null($csrf))
{
/** @var Security $security */
$security = Factory::getInstance("security");
$hash = $security->get_csrf_hash();
$csrf->setValue($hash);
}
return $form;
}
// Otherwise, create the form

View File

@ -34,6 +34,7 @@
* @version Version 1.3.0
*/
use FuzeWorks\Forms\Fields\HiddenField;
use FuzeWorks\Forms\Form;
use FuzeWorks\Forms\Forms;
use PHPUnit\Framework\TestCase;
@ -84,4 +85,34 @@ class LibraryTest extends TestCase
$this->assertSame($form, $form2);
}
/**
* @depends testGetCachedForm
*/
public function testGetCachedFormCsrfChange()
{
/** @var \FuzeWorks\Security $security */
$security = \FuzeWorks\Factory::getInstance("security");
$hash = $security->get_csrf_hash();
$form = $this->forms->getCachedForm(function (Form $form) {
return $form;
}, 'testGetCachedFormCsrfChange', 'testLabel');
$csrfField = $form->getCsrfField();
$this->assertInstanceOf(HiddenField::class, $csrfField);
$this->assertEquals($hash, $csrfField->getValue());
// Now change the hash
$security->csrf_regenerate();
$newHash = $security->get_csrf_hash();
$this->assertNotEquals($hash, $newHash);
// Regenerate the form
$newForm = $this->forms->getCachedForm(function (Form $form) {
return $form;
}, 'testGetCachedFormCsrfChange', 'testLabel');
$csrfField = $newForm->getCsrfField();
$this->assertEquals($newHash, $csrfField->getValue());
}
}