-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Workflow] add guard is_valid() method support #23499
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
Conversation
b89df24
to
30c3f13
Compare
/cc @lyrixx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea, but some code need to be updated.
@@ -29,5 +29,13 @@ protected function registerFunctions() | |||
}, function (array $variables, $attributes, $object = null) { | |||
return $variables['auth_checker']->isGranted($attributes, $object); | |||
}); | |||
|
|||
$this->register('is_valid', function ($object = 'null', $groups = 'null') { | |||
return sprintf('$validator->validate(%s, null, %s)', $object, $groups); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should add count() === 0
here too
AuthorizationCheckerInterface $authenticationChecker, | ||
AuthenticationTrustResolverInterface $trustResolver, | ||
ValidatorInterface $validator, | ||
RoleHierarchyInterface $roleHierarchy = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- should be on one line
- could you put the validator at the last position?
- could you make the validator optional to preserve the BC + a runtime exception is the validator is not defined but the user want to use it.
cf7d0d9
to
6293a4c
Compare
👍 |
Hello @lyrixx is there something else i can do ? |
@alain-flaus Nothing ;) I'm just waiting for the "2 days" ;) Actually, could you rebase and push -f ? |
6293a4c
to
adb227f
Compare
@lyrixx ok rebase done. Thanks! |
Sorry, I forgot to ask you to add a note in the CHANGELOG. |
@lyrixx Hi, I updated the CHANGELOG but I'm not sure about my modification, is it ok? |
CHANGELOG-3.3.md
Outdated
@@ -7,6 +7,8 @@ in 3.3 minor versions. | |||
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash | |||
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v3.3.0...v3.3.1 | |||
|
|||
* feature #23499 [Workflow] add guard is_valid() method support |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your need to update this changelog only
The current one is updated automatically.
1e8e0f6
to
c1fc500
Compare
@lyrixx ok done! |
3.4.0 | ||
----- | ||
|
||
* Add guard is_valid() method support |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is_valid()
should be enclosed by backticks
return sprintf('count($validator->validate(%s, null, %s)) === 0', $object, $groups); | ||
}, function (array $variables, $object = null, $groups = null) { | ||
if (!$variables['validator'] instanceof ValidatorInterface) { | ||
throw new RuntimeException('Validator not defined, did you install the component ?'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the space in front of the question mark should be removed
@@ -633,6 +633,7 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde | |||
new Reference('security.authorization_checker'), | |||
new Reference('security.authentication.trust_resolver'), | |||
new Reference('security.role_hierarchy'), | |||
new Reference('validator'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will fail when the Validator component is not installed or the validation
section is not enabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will add :
new Reference('validator', ContainerInterface::NULL_ON_INVALID_REFERENCE),
Should I also add
new Reference('security.role_hierarchy', ContainerInterface::NULL_ON_INVALID_REFERENCE),
As $roleHierarchy
parameter in Symfony\Component\Workflow\EventListener\GuardListener
can be null too ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that should be done on older branches as a bugfix
|
||
public function __construct($configuration, ExpressionLanguage $expressionLanguage, TokenStorageInterface $tokenStorage, AuthorizationCheckerInterface $authenticationChecker, AuthenticationTrustResolverInterface $trustResolver, RoleHierarchyInterface $roleHierarchy = null) | ||
public function __construct($configuration, ExpressionLanguage $expressionLanguage, TokenStorageInterface $tokenStorage, AuthorizationCheckerInterface $authenticationChecker, AuthenticationTrustResolverInterface $trustResolver, RoleHierarchyInterface $roleHierarchy = null, ValidatorInterface $validator = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we shouldn't register a new listener with the validator as this part is not a security related listener
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I may be wrong, but I thought that the "guard" option was designed to protect the execution of the transition and not only from a security point of view.
In this case, this does seem to me problematic that the expresion is_valid is in the guard listener ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My fear is that the GuardListener
could potentially become very big in the future if add support for other things here. Maybe splitting it into a SecurityGuardListener
(as a replacement for the existing one) and a ValidatorGuardListener
could be an idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how many types of conditions can bloc a transistion but yes we can imagine a lot of thing.
Then I could split GuardListener
into SecurityGuardListener
(the same as GuardListener before my PR) and a ValidatorGuardListener
with the new behavior.
In FrameworkExtension, I need to create a new definition for ValidatorGuardListener
.
For the definition id are you ok with :
sprintf('%s.listener.guard.security', $workflowId)
and
sprintf('%s.listener.guard.validator', $workflowId)
And I plug it on the same event ?
sprintf('workflow.%s.guard.%s', $name, $transitionName)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks okay to me, but let's wait for @lyrixx and the other @symfony/deciders to share their opinion before spending time on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think adding a new listener event is a bad idea, you should only use the guard event.
Then, the GuardListener name is not very well chosen indeed. I should have name it ExpressionGuardListener
Finally, splitting it in 2 parts will be hard because you will need to duplicate everything (config in the .yml, .xml etc etc). More over the end user will not be able to mix security stuff and validation stuff in the same expression.
So I'm 👍 with the current implement (except you need to fix issue spotted by @xabbuh)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I made a code review commit but I don't understand why github don't close "is_valid() should be enclosed by backticks" discussion because it's done (you can see it in the files changed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't worry I see it in the diff.
I guess it's because you have an anchor in your URL, so github re-expand it
👍 |
@xabbuh Is that OK for you? |
|
||
$errors = $variables['validator']->validate($object, null, $groups); | ||
|
||
return count($errors) === 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comment. Should this be changed to return 0 === count($errors);
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed ;)
@@ -29,5 +31,17 @@ protected function registerFunctions() | |||
}, function (array $variables, $attributes, $object = null) { | |||
return $variables['auth_checker']->isGranted($attributes, $object); | |||
}); | |||
|
|||
$this->register('is_valid', function ($object = 'null', $groups = 'null') { | |||
return sprintf('count($validator->validate(%s, null, %s)) === 0', $object, $groups); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, should be yoda style
d56974a
to
c193d37
Compare
Failures on AppVeyor are not related. 👍 |
return sprintf('0 === count($validator->validate(%s, null, %s))', $object, $groups); | ||
}, function (array $variables, $object = null, $groups = null) { | ||
if (!$variables['validator'] instanceof ValidatorInterface) { | ||
throw new RuntimeException('Validator not defined, did you install the component?'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is_valid cannot be used as the Validator component is not installed.
'security.authorization_checker', | ||
'security.authentication.trust_resolver', | ||
'security.role_hierarchy', | ||
'validator', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes validator a new "hard" requirement? Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you suggesting to inject null
instead of the validator
service if this one is not available?
If yes, It's a good idea. I will update the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct
c193d37
to
5969d68
Compare
I totally forgot this PR. I rebased it on top of master (I guess it's toot late for 3.4?) |
@@ -589,6 +590,10 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ | |||
throw new LogicException('Cannot guard workflows as the Security component is not installed.'); | |||
} | |||
|
|||
if (!interface_exists(ValidatorInterface::class)) { | |||
throw new LogicException('Cannot guard workflows as the Validator component is not installed.'); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed now, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Fixed.
@@ -9,6 +9,7 @@ CHANGELOG | |||
3.4.0 | |||
----- | |||
|
|||
* Add guard `is_valid()` method support. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
5969d68
to
06d8198
Compare
@lyrixx Can you fix fabbot error and rebase before I merge? Thanks. |
Thank you @alain-flaus. |
…flaus, lyrixx) This PR was merged into the 3.4 branch. Discussion ---------- [Workflow] add guard is_valid() method support | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | Yes | License | MIT Workflow guard configuration support expression language like **is_fully_authenticated()**, **has_role()** or **is_granted()**, etc... I would like to add the support for a new **is_valid()** expression. Configuration allow to validate subject against specific validation groups to check if a transition can be applied. In the next configuration exemple, my issue must validate "affectable" validation group to apply "affect" transistion: ```yaml framework: workflows: issue: marking_store: type: single_state arguments: - state supports: AppBundle\Entity\Issue initial_place: created places: - created - affected - closed transitions: affect: guard: "is_valid(subject, ['affectable'])" from: created to: affected close: from: completed to: closed ``` Commits ------- 06d8198 [Workflow] Added tests for the is_valid() guard expression 9499bc2 [Workflow] Added guard 'is_valid()' method support
@fabpot Sorry, I did not see your message sooner :/ |
Workflow guard configuration support expression language like is_fully_authenticated(), has_role() or is_granted(), etc...
I would like to add the support for a new is_valid() expression.
Configuration allow to validate subject against specific validation groups to check if a transition can be applied.
In the next configuration exemple, my issue must validate "affectable" validation group to apply "affect" transistion: