Skip to content

[Form] Added a cause on when a Csrf Error has occurred on CsrfValidationListener #28564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 1, 2018

Conversation

gmponos
Copy link
Contributor

@gmponos gmponos commented Sep 23, 2018

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #28427
License MIT
Doc PR symfony/symfony-docs

The Csrf error that it is added as a FormError does not have a cause making it hard to filter it out.

  1. I am not sure if this is a bug or a feature.
  2. @xabbuh on the issue you said something about CsrfValidationError. I didn't quite get that. In the current PR you can see what I was thinking about. Let me know your thoughts and continue the discussion here.

@@ -66,7 +67,8 @@ public function preSubmit(FormEvent $event)
$errorMessage = $this->translator->trans($errorMessage, array(), $this->translationDomain);
}

$form->addError(new FormError($errorMessage));
$cause = new ConstraintViolation($errorMessage, null, array(), null, '', null, null, 'csrf');
$form->addError(new FormError($errorMessage, null, array(), null, $cause));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a ConstraintViolation here adds a hard dependency on the Validator component. This is not necessary. A cause of a form error can be arbitrary objects. We should add a new class for that.

Copy link
Contributor Author

@gmponos gmponos Sep 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hear what you are saying but I am a little bit confused.

If I understood correctly you are suggesting this:

$cause = new CsrfValidationError($some_arguments_or_no_arguments_at_all);
$form->addError(new FormError($errorMessage, null, array(), null, $cause));

The reason I went with my implementation is because of this line

The function above implies that all causes are ConstraintViolation objects. Personally I can fulfill my requirements with your suggestion but IMHO I think

  • On this current PR the cause should be a simple string.
  • $cause argument on FormError object should either accept strings, objects that implement the __toString function or a ConstraintViolation object.
  • Besides filtering ConstraintViolations the function findByCodes should also be able to filter causes that are string or objects that implement __toString function.

If you still believe that what you are saying is the way to go I will change my PR accordingly. Let me know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw I do not suggest to implement all these changes at the current PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, any feedback on this... sorry if I am pushing things.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, I suggest to only add the new class that does not depend on the Validator component. IMO we should discuss your other ideas in different issues/PRs afterwards. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I have applied the changes :)

@@ -66,7 +66,7 @@ public function preSubmit(FormEvent $event)
$errorMessage = $this->translator->trans($errorMessage, array(), $this->translationDomain);
}

$form->addError(new FormError($errorMessage));
$form->addError(new FormError($errorMessage, null, array(), null, new CsrfValidationError()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be good to pass the CsrfToken instance as well as the submitted token to CsrfValidationError as that would ease debugging IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... I have my doubts about this... CsrfToken does not always exists. Check the last failing build. It will need some refactoring there making the code I little bit more complex. Do you want me to proceed with the refactoring?

* file that was distributed with this source code.
*/

namespace Symfony\Component\Form\Extension\Csrf\EventListener;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move the class one level up and rename it to ValidationError so that the FQCN reads Symfony\Component\Form\Extension\Csrf\ValidationError?

@xabbuh
Copy link
Member

xabbuh commented Sep 30, 2018

I left two minor comments, but apart from that the changes look good to me. Great work! 👍

$errorMessage = $this->errorMessage;

if (null !== $this->translator) {
$errorMessage = $this->translator->trans($errorMessage, array(), $this->translationDomain);
}

$form->addError(new FormError($errorMessage));
$form->addError(new FormError($errorMessage, null, array(), null, new ValidationError($csrfToken)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isnt $csrfToken the actual cause here? what's the point of getCause()->getCsrfToken() vs. getCause() 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment here. If I understand correctly it seems that CSRF token does not always exist. So I can not set CsrfToken object directly as cause.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now it's declared at L63 :)

@@ -59,14 +60,15 @@ public function preSubmit(FormEvent $event)
if ($form->isRoot() && $form->getConfig()->getOption('compound') && !$postRequestSizeExceeded) {
$data = $event->getData();

if (!isset($data[$this->fieldName]) || !$this->tokenManager->isTokenValid(new CsrfToken($this->tokenId, $data[$this->fieldName]))) {
$csrfToken = new CsrfToken($this->tokenId, $data[$this->fieldName]);
Copy link
Contributor

@ro0NL ro0NL Sep 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$data[$this->fieldName] ?? null

then there's always a valid token object for a cause

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't feel right to me this way. Waiting for @xabbuh feedback.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ro0NL has a good point here. Just having the CsrfToken class as the cause sounds good to me.

$errorMessage = $this->errorMessage;

if (null !== $this->translator) {
$errorMessage = $this->translator->trans($errorMessage, array(), $this->translationDomain);
}

$form->addError(new FormError($errorMessage));
$form->addError(new FormError($errorMessage, null, array(), null, $csrfToken));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the second argument (message template) should be $errorMessage too

@gmponos
Copy link
Contributor Author

gmponos commented Sep 30, 2018

Thank you for the review.. Let's hope the build will pass... Can you check now 😄

Copy link
Contributor

@ro0NL ro0NL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me (with minor comment)

@@ -7,6 +7,7 @@ CHANGELOG
* deprecated the `$scale` argument of the `IntegerToLocalizedStringTransformer`
* added `Symfony\Component\Form\ClearableErrorsInterface`
* deprecated calling `FormRenderer::searchAndRenderBlock` for fields which were already rendered
* added a cause when a CsrfError has occurred
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... CSRF error ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@fabpot
Copy link
Member

fabpot commented Oct 1, 2018

Thank you @gmponos.

@fabpot fabpot merged commit 162d0be into symfony:master Oct 1, 2018
fabpot added a commit that referenced this pull request Oct 1, 2018
… on CsrfValidationListener (gmponos)

This PR was squashed before being merged into the 4.2-dev branch (closes #28564).

Discussion
----------

[Form] Added a cause on when a Csrf Error has occurred on CsrfValidationListener

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #28427
| License       | MIT
| Doc PR        | symfony/symfony-docs

The Csrf error that it is added as a `FormError` does not have a cause making it hard to filter it out.

1. I am not sure if this is a bug or a feature.
2. @xabbuh on the issue you said something about `CsrfValidationError`. I didn't quite get that. In the current PR you can see what I was thinking about. Let me know your thoughts and continue the discussion here.

Commits
-------

162d0be [Form] Added a cause on when a Csrf Error has occurred on CsrfValidationListener
@fabpot
Copy link
Member

fabpot commented Oct 1, 2018

Something went wrong when merging this PR. @gmponos Can you resubmit it again? Sorry for the trouble.

@gmponos
Copy link
Contributor Author

gmponos commented Oct 1, 2018

@fabpot done... I have also squashed the commits. I hope that doesn't cause more trouble.

fabpot added a commit that referenced this pull request Oct 1, 2018
…e FormError object (gmponos)

This PR was merged into the 4.2-dev branch.

Discussion
----------

When a CSRF occures on a Form submit add a cause on the FormError object

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #28427
| License       | MIT
| Doc PR        | symfony/symfony-docs

This is a resubmitted PR of this: #28564

> Something went wrong when merging this PR. @gmponos Can you resubmit it again? Sorry for the trouble.

Commits
-------

e54e94c When a CSRF occures on a Form submit add a cause on the FormError object
@nicolas-grekas nicolas-grekas modified the milestones: next, 4.2 Nov 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants