Skip to content

Comments

[WIP/RFC] Use framework expression language service instead of custom one#2289

Merged
soyuka merged 3 commits intoapi-platform:masterfrom
Toflar:use-security-expression-language
Feb 11, 2019
Merged

[WIP/RFC] Use framework expression language service instead of custom one#2289
soyuka merged 3 commits intoapi-platform:masterfrom
Toflar:use-security-expression-language

Conversation

@Toflar
Copy link
Contributor

@Toflar Toflar commented Oct 29, 2018

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

Using the framework security.expression_language service rather than our own one allows us to extend the expression language with our own functions easily. Symfony already provides an easy way to register custom functions in AddExpressionLanguageProvidersPass. ApiPlatform currently does not. But I figured instead of providing our own compiler pass we can just use the built-in security.expression_language, extend that with our is_granted() function and thus at the same time also allow developers to add even more functions. Wdyt?

@Toflar Toflar force-pushed the use-security-expression-language branch 2 times, most recently from 6b0fc67 to 190e85a Compare October 29, 2018 16:08
<services>
<service id="api_platform.security.resource_access_checker" class="ApiPlatform\Core\Security\ResourceAccessChecker" public="false">
<argument type="service" id="api_platform.security.expression_language" on-invalid="null" />
<argument type="service" id="security.expression_language" on-invalid="null" />
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 create an alias api_platform.security.expression_language please? It will be useful for people wanting to inject a custom service.

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="1" />
</service>

<service id="api_platform.security.expression_language_provider" class="ApiPlatform\Core\Security\Core\Authorization\ExpressionLanguageProvider">
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<service id="api_platform.security.expression_language_provider" class="ApiPlatform\Core\Security\Core\Authorization\ExpressionLanguageProvider">
<service id="api_platform.security.expression_language_provider" class="ApiPlatform\Core\Security\Core\Authorization\ExpressionLanguageProvider" public="false">

use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

/**
* Adding ApiPlatform specific Expression Language functions.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Adding ApiPlatform specific Expression Language functions.
* Registers API Platform's Language functions.

*
* @author Yanick Witschi <yanick.witschi@terminal42.ch>
*/
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
final class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface

*/
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
{
public function getFunctions()
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public function getFunctions()
public function getFunctions(): array

public function getFunctions()
{
return [
new ExpressionFunction('is_granted', function ($attributes, $object = 'null') {
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't it conflict with the one registered by SensioFrameworkExtraBundle?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One would just override the other (depending on the order they are called). And as far as I could see the idea was to provide the same logic, right? I mean, we could only register it if the bundle is not loaded if that makes you more comfortable? Or just tell the users to require the framework-extra-bundle if they want this function?

Copy link
Member

Choose a reason for hiding this comment

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

I just want to be sure it works as intended in all cases :)

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 should :)

@Toflar
Copy link
Contributor Author

Toflar commented Oct 30, 2018

Comments addressed :)

@dunglas
Copy link
Member

dunglas commented Nov 5, 2018

@Toflar errors look related to this PR, could you take a look (I'll tag a new release soon). Thanks

@Toflar Toflar force-pushed the use-security-expression-language branch 3 times, most recently from 91a460b to f23ca61 Compare November 6, 2018 12:37
@Toflar
Copy link
Contributor Author

Toflar commented Nov 6, 2018

Done!

$bundles = $container->getParameter('kernel.bundles');
if (isset($bundles['SecurityBundle'])) {
if (class_exists(ExpressionLanguage::class)) {
$loader->load('security_expression_language.xml');
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, symfony/expression-language is in require-dev of symfony/security-bundle: https://github.com/symfony/symfony/blob/b5c6892911fc7454a76528cb0d4d1af4336c7413/src/Symfony/Bundle/SecurityBundle/composer.json#L42

So we still need to check that the ExpressionLanguage component is actually available.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you sure? security.expression_language would not be present so the alias would become invalid and as we use on-invalid="null" on api_platform.security.resource_access_checker that should work. Haven't checked though.

Copy link
Contributor

@teohhanhui teohhanhui Nov 19, 2018

Choose a reason for hiding this comment

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

I'm not sure. But I think we might as well just keep them in a separate file.

@Toflar
Copy link
Contributor Author

Toflar commented Jan 7, 2019

Can I do anything here? I still think the way it is now is correct :)

@soyuka
Copy link
Member

soyuka commented Feb 10, 2019

Can you rebase? LGTM, we should merge this!

@Toflar Toflar force-pushed the use-security-expression-language branch from 0fe5cfc to 59039a5 Compare February 11, 2019 08:36
@Toflar
Copy link
Contributor Author

Toflar commented Feb 11, 2019

Rebased onto master, not sure if I should've gone for the 2.4 branch? The deps=low test fails but apparently that's also the case for master.

@soyuka
Copy link
Member

soyuka commented Feb 11, 2019

Master is fine, yeah don't worry about deps=low I'll try to fix it later, thanks!

@alanpoulain
Copy link
Member

@soyuka the issue with deps=low comes from Composer. It will be resolved in the next version or if you do composer selfupdate --snapshot.

@soyuka soyuka merged commit e1f92d0 into api-platform:master Feb 11, 2019
@Toflar Toflar deleted the use-security-expression-language branch February 11, 2019 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants