Skip to content

[SecurityBundle] fix setLogoutOnUserChange calls for context listeners #25272

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 7 commits into from

Conversation

dmaicher
Copy link
Contributor

@dmaicher dmaicher commented Dec 2, 2017

Q A
Branch? 3.4
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #25267
License MIT
Doc PR -

As pointed out in #25267 the setLogoutOnUserChange method calls were added to the parent definition security.context_listener instead of the concrete child definitions security.context_listener.*.

ping @iltar @chalasr

@@ -276,15 +276,19 @@ private function createFirewalls($config, ContainerBuilder $container)
$customUserChecker = true;
}

$configId = 'security.firewall.map.config.'.$name;

list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
Copy link
Member

Choose a reason for hiding this comment

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

Those 2 lines can bu moved back to where they were, right?

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 😉

$configId = 'security.firewall.map.config.'.$name;

list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);

foreach ($listeners as $listener) {
if (0 === strpos($listenerId = (string) $listener, 'security.context_listener.')) {
$container->getDefinition($listenerId)->addMethodCall('setLogoutOnUserChange', array($firewall['logout_on_user_change']));
Copy link
Member

@chalasr chalasr Dec 3, 2017

Choose a reason for hiding this comment

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

Can be done in createContextListener by passing the option value as argument to createFirewall first (it has the whole config), or iterate over $this->contextListeners after the createFirewall loop.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@chalasr done 😉 Will make merging into higher branches a bit harder though 😋

@Xymanek
Copy link

Xymanek commented Dec 3, 2017

How will this work if multiple firewalls share the same context?

@dmaicher
Copy link
Contributor Author

dmaicher commented Dec 3, 2017

@Xymanek hmm I think you are right. That case is still not handled properly 😢

I will look into it.

@dmaicher
Copy link
Contributor Author

dmaicher commented Dec 3, 2017

@iltar @chalasr any idea how to fix this?

Seems ContextListener::$logoutOnUserChange needs some rethinking as indeed the context instance can be shared amongst multiple firewalls.

Within the ContextListener I don't see any way of knowing which firewall(s) its currently handling? So how to decide $logoutOnUserChange per firewall then?

Or we enforce (with an error when validating the config?) that all firewalls that share a context have the same value for logout_on_user_change?

@chalasr
Copy link
Member

chalasr commented Dec 3, 2017

@dmaicher I think it should throw indeed

}

if (isset($this->firewallsByContextKey[$contextKey]) && $this->firewallsByContextKey[$contextKey][1]['logout_on_user_change'] !== $firewall['logout_on_user_change']) {
throw new InvalidConfigurationException(sprintf('Firewalls "%s" and "%s" need to have the same value for option "logout_on_user_change" as they are sharing the context "%s"', $this->firewallsByContextKey[$contextKey][0], $id, $contextKey));
Copy link
Contributor Author

@dmaicher dmaicher Dec 3, 2017

Choose a reason for hiding this comment

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

@chalasr done. There is a tiny chance though that this is a BC break if someone set the option already on some firewalls with a shared context.

But the behavior is wrong anyway with that config then 😋

Copy link
Member

Choose a reason for hiding this comment

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

Current behavior is buggy, fine to me

}

$this->firewallsByContextKey[$contextKey] = array($id, $firewall);
$listeners[] = new Reference($this->createContextListener($container, $contextKey, $firewall['logout_on_user_change']));
Copy link
Member

Choose a reason for hiding this comment

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

must be reached only if the key is set on $firewall. Also I would store the option value only instead of the whole config

Copy link
Contributor Author

Choose a reason for hiding this comment

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

must be reached only if the key is set on $firewall.

Not sure I follow. That line was always reached before as well?

Also I would store the option value only instead of the whole config

👍

Copy link
Member

Choose a reason for hiding this comment

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

Now it's accessing $firewall['logout_on_user_change'] which might be not set.
In this case we should not register the firewall in $firewallsByContextKey, perhaps pass null to createContextListener() in order to not add the method call as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Forgot that it's a bool node, sorry for the noise!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem ;) will update the PR after work

@@ -43,6 +43,7 @@ class SecurityExtension extends Extension
private $factories = array();
private $userProviderFactories = array();
private $expressionLanguage;
private $firewallsByContextKey = array();
Copy link
Member

Choose a reason for hiding this comment

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

can you add a deprec docblock so that we don't forget to remove it in 5.0?

@@ -340,17 +340,6 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
return $firewall;
})
->end()
->validate()
Copy link
Contributor Author

@dmaicher dmaicher Dec 4, 2017

Choose a reason for hiding this comment

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

@chalasr this is now actually not needed anymore since triggering the deprecation is moved and it's not triggered anymore at all if stateless = true or security = false.

Copy link
Member

Choose a reason for hiding this comment

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

good catch!

@@ -43,6 +43,7 @@ class SecurityExtension extends Extension
private $factories = array();
private $userProviderFactories = array();
private $expressionLanguage;
private $logoutOnUserChangeByContextKey = array();
Copy link
Contributor Author

@dmaicher dmaicher Dec 4, 2017

Choose a reason for hiding this comment

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

@chalasr should I add some deprecation info here? Did not see that for private member variables elsewhere?

Copy link
Member

Choose a reason for hiding this comment

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

Let's let it as is and keep it in mind, note for mergers: this prop should be removed when merging in 4.0 (I can take care of the merge)

@chalasr
Copy link
Member

chalasr commented Dec 4, 2017

Thanks for fixing this bug @dmaicher.

chalasr pushed a commit that referenced this pull request Dec 4, 2017
…xt listeners (dmaicher)

This PR was squashed before being merged into the 3.4 branch (closes #25272).

Discussion
----------

[SecurityBundle] fix setLogoutOnUserChange calls for context listeners

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #25267
| License       | MIT
| Doc PR        | -

As pointed out in #25267 the `setLogoutOnUserChange` method calls were added to the parent definition `security.context_listener` instead of the concrete child definitions `security.context_listener.*`.

ping @iltar @chalasr

Commits
-------

4eff146 [SecurityBundle] fix setLogoutOnUserChange calls for context listeners
@fabpot fabpot closed this Dec 4, 2017
This was referenced Dec 4, 2017
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.

7 participants