- Added CSRF through form processing
This commit is contained in:
parent
97f1f67af1
commit
83fee32ac0
|
@ -43,7 +43,7 @@ class UiInput extends UiElement implements Extension {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($attributes['class'] ?? false) {
|
if ($attributes['class'] ?? false) {
|
||||||
$attributes['class'] .= " {$this->attributes['class']}";
|
$attributes['class'] = implode(" ", array_merge((array) $attributes['class'], (array) $this->attributes['class']));
|
||||||
unset($this->attributes['class']);
|
unset($this->attributes['class']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,6 @@ class Form implements Extension {
|
||||||
|
|
||||||
public function formClass(FormInterface $form, ? FormContext $formContext = null) : FormHandler
|
public function formClass(FormInterface $form, ? FormContext $formContext = null) : FormHandler
|
||||||
{
|
{
|
||||||
return new FormHandler($this->request, $form, $formContext);
|
return new FormHandler($formContext ? $formContext->request : $this->request, $form, $formContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ class FormContext implements FormContextInterface
|
||||||
{
|
{
|
||||||
public string $formName;
|
public string $formName;
|
||||||
|
|
||||||
public bool $formSent;
|
public bool $formSent = false;
|
||||||
|
|
||||||
public bool $formExecuted = false;
|
public bool $formExecuted = false;
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@ class FormContext implements FormContextInterface
|
||||||
public array $files = [];
|
public array $files = [];
|
||||||
|
|
||||||
public array $messages = [];
|
public array $messages = [];
|
||||||
|
|
||||||
|
public bool $skipCsrf = false;
|
||||||
|
|
||||||
public ServerRequestInterface $request;
|
public ServerRequestInterface $request;
|
||||||
|
|
||||||
|
@ -54,7 +56,25 @@ class FormContext implements FormContextInterface
|
||||||
|
|
||||||
public function formSent() : bool
|
public function formSent() : bool
|
||||||
{
|
{
|
||||||
return $this->formSent;
|
$valid = true;
|
||||||
|
|
||||||
|
if ( ! $this->skipCsrf && ($this->formName ?? false) ) {
|
||||||
|
$token = $this->get('picea-ui-form')[$this->formName] ?? false;
|
||||||
|
|
||||||
|
if ( $token ) {
|
||||||
|
if ($this->validateCsrfToken) {
|
||||||
|
$valid = in_array($token, $_SESSION["picea-ui.form:{$this->formName}"] ?? []);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$valid = (bool) $token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->formSent = $valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __set($key, $value)
|
public function __set($key, $value)
|
||||||
|
|
|
@ -5,6 +5,9 @@ namespace Picea\Ui\Method;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
class FormHandler {
|
class FormHandler {
|
||||||
|
const DEFAULT_METHODS = [
|
||||||
|
"DELETE", "PATCH", "POST", "PUT",
|
||||||
|
];
|
||||||
|
|
||||||
public bool $sent = false;
|
public bool $sent = false;
|
||||||
|
|
||||||
|
@ -18,6 +21,8 @@ class FormHandler {
|
||||||
|
|
||||||
protected FormInterface $form;
|
protected FormInterface $form;
|
||||||
|
|
||||||
|
public array $acceptedMethods = self::DEFAULT_METHODS;
|
||||||
|
|
||||||
public function __construct(ServerRequestInterface $request, FormInterface $form, ? FormContextInterface $context = null)
|
public function __construct(ServerRequestInterface $request, FormInterface $form, ? FormContextInterface $context = null)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
|
@ -33,37 +38,14 @@ class FormHandler {
|
||||||
|
|
||||||
$this->request->context = $this->context;
|
$this->request->context = $this->context;
|
||||||
|
|
||||||
$this->formSent();
|
|
||||||
$this->initialize();
|
$this->initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function formSent() : void
|
|
||||||
{
|
|
||||||
if ( false !== $this->context->formSent = $this->sent ) {
|
|
||||||
if ( $this->context->formName ?? false ) {
|
|
||||||
$sent = false;
|
|
||||||
|
|
||||||
$token = $this->context->{'picea-ui-form'}[$this->context->formName] ?? false;
|
|
||||||
|
|
||||||
if ( $token ) {
|
|
||||||
if ($this->validateCsrfToken) {
|
|
||||||
$sent = in_array($token, $_SESSION["picea-ui.form:{$this->context->formName}"] ?? []);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$sent = (bool) $token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->sent = $this->context->formSent = $sent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function initialize() : void
|
protected function initialize() : void
|
||||||
{
|
{
|
||||||
$this->form->initialize($this->context);
|
$this->form->initialize($this->context);
|
||||||
|
|
||||||
if ( $this->sent ) {
|
if ( $this->sent && $this->context->formSent() ) {
|
||||||
if ( $this->form->validate($this->context) ) {
|
if ( $this->form->validate($this->context) ) {
|
||||||
$this->executionStatus = $this->form->execute($this->context);
|
$this->executionStatus = $this->form->execute($this->context);
|
||||||
}
|
}
|
||||||
|
@ -72,9 +54,7 @@ class FormHandler {
|
||||||
|
|
||||||
protected function requestSent() : bool
|
protected function requestSent() : bool
|
||||||
{
|
{
|
||||||
return in_array($this->request->getMethod(), [
|
return in_array(strtoupper($this->request->getMethod()), array_map('strtoupper', $this->acceptedMethods));
|
||||||
"DELETE", "PATCH", "POST", "PUT",
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function honeyPot() : bool
|
protected function honeyPot() : bool
|
||||||
|
|
Loading…
Reference in New Issue