Skip to content

Fixed some issues of the AccessDecisionManager profiler #18934

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

Closed
wants to merge 11 commits into from

Conversation

javiereguiluz
Copy link
Member

@javiereguiluz javiereguiluz commented Jun 1, 2016

Q A
Branch? 3.1
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #19022 https://github.com/symfony/symfony-standard/issues/968 schmittjoh/JMSSecurityExtraBundle#207
License MIT
Doc PR -

@@ -66,7 +66,7 @@ public function load(array $configs, ContainerBuilder $container)
$loader->load('collectors.xml');
$loader->load('guard.xml');

if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) {
if ($container->has('profiler')) {
Copy link
Member

Choose a reason for hiding this comment

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

this is broken, as it will always be false here (DI extensions are isolated from each other). You may need to use a compiler pass instead

Copy link
Member Author

@javiereguiluz javiereguiluz Jun 2, 2016

Choose a reason for hiding this comment

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

This looks overkill to me. Isn't there any other solution? In other extensions, for example in these lines of FrameworkExtension, they use the same code as here:

if ($container->getParameter('kernel.debug')) {
    $loader->load('templating_debug.xml');
    // ...
}

Copy link
Member

@wouterj wouterj Jun 2, 2016

Choose a reason for hiding this comment

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

The big difference is that parameters are copied to the local container passed to Extension#load(), whereas services aren't.

And btw, this can only be done with kernel.* parameters, as these are set by the Kernel. All other parameters will only be available based on the order of the registered bundles in AppKernel: You don't want to depend on the order.

Copy link
Member Author

Choose a reason for hiding this comment

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

@wouterj I don't understand your comment. In any case, I asked why this is wrong:

if ($container->getParameter('kernel.debug')) {
    $loader->load('security_debug.xml');
}

When this is considered right:

if ($container->getParameter('kernel.debug')) {
    $loader->load('templating_debug.xml');
    // ...
}

Copy link
Member

Choose a reason for hiding this comment

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

It's about this:

if ($container->has('profiler')) {
    // ...
}

Versus this:

if ($container->getParameter('kernel.debug')) {
    // ...
}

The $container parameter of Extension::load() is not the actual container, it's a copy. See https://github.com/symfony/dependency-injection/blob/master/Compiler/MergeExtensionConfigurationPass.php#L47-L49 Only the parameters are copied from actual to tmp container, services aren't.

This is why $container->has('profiler') will always return false.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure. I didn't use $container->has('profiler') at first. I used $container->getParameter('kernel.debug') but I was told that it was not completely right. But I still don't understand, so I can't fix it.

Copy link
Member

Choose a reason for hiding this comment

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

@javiereguiluz the issue is that kernel.debug is only the default value for enabling the profiler. It is possible to enable it in non-debug mode.

And this mismatch is precisely one of the issues you have to fix, as the profiler always assumes that the debug access decision manager is there.
The alternative would be to handle properly the absence of this service (storing less info in the profiler panel)

@@ -66,7 +66,7 @@ public function load(array $configs, ContainerBuilder $container)
$loader->load('collectors.xml');
$loader->load('guard.xml');

if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) {
if ($container->getParameter('kernel.debug')) {
$loader->load('security_debug.xml');
Copy link
Member

@yceruto yceruto Jun 7, 2016

Choose a reason for hiding this comment

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

@javiereguiluz I tried this PR and the issue still exists :(

https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml#L13: The data_collector.security service ("which is always loaded" L66) require debug.security.access.decision_manager, so when $container->getParameter('kernel.debug') is false this service isn't loaded:

php bin/console --env=dev --no-debug

  [Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException]
  The service "profiler" has a dependency on a non-existent service "debug.security.access.decision_manager".

The road should be here https://github.com/symfony/symfony-standard/issues/968#issuecomment-223022665:

@stof: ... It should be based on whether the profiler is enabled instead of being based on the debug mode ...

Copy link
Member Author

Choose a reason for hiding this comment

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

Is it OK to load the collectors.xml file unconditionally? Is it really used when debug = false ? If this can be changed, the solution would be trivial: move $loader->load('collectors.xml'); under the if ($container->getParameter('kernel.debug')) condition.

Copy link
Member

Choose a reason for hiding this comment

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

well, if you do it, the security panel would not appear when enabling the profiler in no-debug mode, which might be confusing

Copy link
Member

@yceruto yceruto Jun 10, 2016

Choose a reason for hiding this comment

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

Could we check web_profiler.controller.profiler service definition ? it's defined only if WebProfileBundle is enabled. BUT, this would imply that all panels profile should be loaded only if this "WebProfileBundle" is enabled ? Currenly this is not taken into consideration in others collectors.

Copy link
Member

Choose a reason for hiding this comment

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

@yceruto WebProfilerBundle is not related to enabling the profiler (the bundle does not provide the profiler. It is only about providing a visualization UI).
The proper service would be detecting profiler (coming from FrameworkBundle), but this cannot be done in a DI extension, because DI extension cannot see services defined in other extensions (see the previous discussion)

Copy link
Member

Choose a reason for hiding this comment

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

@stof you're right, then

#18934 (comment)

... Only the parameters are copied from actual to tmp container ...

We can create a new parameter something like profiler.collect into FrameworkExtension::registerProfilerConfiguration ?:

$container->setParameter('profiler.collect', $config['collect']);

and use it here ?

if ($container->hasParameter('profiler.collect') && $container->getParameter('profiler.collect')) {
    $loader->load('collectors.xml');
    $loader->load('security_debug.xml');
}

@javiereguiluz WDYT?

Copy link
Member Author

Choose a reason for hiding this comment

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

@yceruto my guess is that they won't accept to introduce a parameter for this. Let's try to do the compilar pass that @stof suggested in the first place.

@fabpot
Copy link
Member

fabpot commented Jun 16, 2016

@javiereguiluz Can you move this PR forward? Or do you need some help?

@peterrehm
Copy link
Contributor

@javiereguiluz Any update on this? A solution would be awesome.

@javiereguiluz
Copy link
Member Author

@peterrehm I plan to finish this very soon.

@javiereguiluz
Copy link
Member Author

I've updated this with a compiler pass, as @stof suggested.

@@ -66,10 +66,6 @@ public function load(array $configs, ContainerBuilder $container)
$loader->load('collectors.xml');
Copy link
Member

Choose a reason for hiding this comment

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

@javiereguiluz the issue still occurs if profiler service is not defined, so data_collector.security require of debug.security.access.decision_manager

Copy link
Member Author

Choose a reason for hiding this comment

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

Could we solve this via config?

<argument type="service" id="debug.security.access.decision_manager" on-invalid="ignore" />

Copy link
Contributor

Choose a reason for hiding this comment

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

Or maybe just load the collector in debug?

Copy link
Member Author

Choose a reason for hiding this comment

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

@HeahDude apparently we can't do that. See #18934 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, I see another solution, now that the security.access.decision_manager is properly decorated, just pass it to the collector instead of the debug.security.access.decision_manager, this line should ensure everything is fine, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 Let's try that! Thanks.

@javiereguiluz
Copy link
Member Author

Some tests are still failing. Given that a new Symfony 3.1 release is imminent, could someone please help me fix this? Thanks!

@HeahDude
Copy link
Contributor

If passing the security.access.decision_manager instead of the debug.security.access.decision_manager to the collector maybe you can revert the compiler pass and keep the xml config.

if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) {
$loader->load('security_debug.xml');
}
$loader->load('security_debug.xml');
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you remove the debug check?

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@HeahDude HeahDude Jun 29, 2016

Choose a reason for hiding this comment

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

Yes but now the check is done in the collector, so no need to load the debug adm when not in debug mode.

@@ -66,7 +66,7 @@ public function load(array $configs, ContainerBuilder $container)
$loader->load('collectors.xml');
$loader->load('guard.xml');

if ($container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug')) {
if ($container->getParameter('kernel.debug')) {
Copy link
Contributor

Choose a reason for hiding this comment

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

You should keep the check with hasParameter() since some tests are still failing

@HeahDude
Copy link
Contributor

I guess you now need to update the SecurityBundle composer.json to require "symfony/security": "~3.1,>=3.1.2"

@HeahDude
Copy link
Contributor

👍 LGTM now, remaining failures are unrelated.

Status: Reviewed

@@ -10,7 +10,7 @@
<argument type="service" id="security.token_storage" on-invalid="ignore" />
<argument type="service" id="security.role_hierarchy" />
<argument type="service" id="security.logout_url_generator" />
<argument type="service" id="debug.security.access.decision_manager" />
<argument type="service" id="security.access.decision_manager" />
Copy link
Member

@yceruto yceruto Jun 29, 2016

Choose a reason for hiding this comment

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

if the compiler pass was removed then when this argument is changed by debug.security.access.decision_manager ?
I missing something ?

Copy link
Contributor

@HeahDude HeahDude Jun 29, 2016

Choose a reason for hiding this comment

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

@yceruto the service is decorated when debug is on by loading security_debug.xml.

@fabpot
Copy link
Member

fabpot commented Jun 29, 2016

Thank you @javiereguiluz.

fabpot added a commit that referenced this pull request Jun 29, 2016
…aviereguiluz)

This PR was squashed before being merged into the 3.1 branch (closes #18934).

Discussion
----------

Fixed some issues of the AccessDecisionManager profiler

| Q             | A
| ------------- | ---
| Branch?       | 3.1
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #19022 https://github.com/symfony/symfony-standard/issues/968 schmittjoh/JMSSecurityExtraBundle#207
| License       | MIT
| Doc PR        | -

Commits
-------

082f1b5 Fixed some issues of the AccessDecisionManager profiler
@fabpot fabpot closed this Jun 29, 2016
@ioleo
Copy link

ioleo commented Jun 30, 2016

It's in the 3.1.x-dev branch, but not in the 3.1.1 tag :( @fabpot could you tag another patch release?

@peterrehm
Copy link
Contributor

@loostro I think you need to be a bit patient, as @javiereguiluz wrote a new release is around the corner...

@fabpot fabpot mentioned this pull request Jun 30, 2016
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.

10 participants