api-platform / core

The server component of API Platform: hypermedia and GraphQL APIs in minutes
https://api-platform.com
MIT License
2.43k stars 866 forks source link

Security config not parsed in php8 ApiResource attribute #4160

Closed darthf1 closed 3 years ago

darthf1 commented 3 years ago

API Platform version(s) affected: 2.6.3

Description
I was transforming my annotations to attributes, when I stumbled on this issue. When I have a operation with a security config it works in an annotation, but it does not work in an attribute. It looks like the string is transformed to a unicode string (or maybe thats just for logging purposes).

How to reproduce

#[ApiResource(
     'MY_OPERATION' => [
            'method' => 'put',
            'security' => "is_granted('VIEW'), object)",
            'path' => '/my_path/{uuid}/do_something',
            'requirements' => ['uuid' => '%routing.uuid%'],
    ],
)]
class MyClass {}

Doing the quotes the other way around gives the same error:

#[ApiResource(
     'MY_OPERATION' => [
            'method' => 'put',
            'security' => 'is_granted("VIEW"), object)',
            'path' => '/my_path/{uuid}/do_something',
            'requirements' => ['uuid' => '%routing.uuid%'],
    ],
)]
class MyClass {}
{
   "@context":"\/api\/contexts\/Error",
   "@type":"hydra:Error",
   "hydra:title":"An error occurred",
   "hydra:description":"Unexpected \u0022)\u0022 around position 34 for expression `is_granted(\u0027VIEW\u0027), object)`.",
   "trace":[
      {
         "namespace":"",
         "short_class":"",
         "class":"",
         "type":"",
         "function":"",
         "file":"\/root\/vendor\/symfony\/expression-language\/Lexer.php",
         "line":60,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\ExpressionLanguage",
         "short_class":"Lexer",
         "class":"Symfony\\Component\\ExpressionLanguage\\Lexer",
         "type":"-\u003E",
         "function":"tokenize",
         "file":"\/root\/vendor\/symfony\/expression-language\/ExpressionLanguage.php",
         "line":93,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\ExpressionLanguage",
         "short_class":"ExpressionLanguage",
         "class":"Symfony\\Component\\ExpressionLanguage\\ExpressionLanguage",
         "type":"-\u003E",
         "function":"parse",
         "file":"\/root\/vendor\/symfony\/expression-language\/ExpressionLanguage.php",
         "line":67,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\ExpressionLanguage",
         "short_class":"ExpressionLanguage",
         "class":"Symfony\\Component\\ExpressionLanguage\\ExpressionLanguage",
         "type":"-\u003E",
         "function":"evaluate",
         "file":"\/root\/vendor\/api-platform\/core\/src\/Security\/ResourceAccessChecker.php",
         "line":76,
         "args":[

         ]
      },
      {
         "namespace":"ApiPlatform\\Core\\Security",
         "short_class":"ResourceAccessChecker",
         "class":"ApiPlatform\\Core\\Security\\ResourceAccessChecker",
         "type":"-\u003E",
         "function":"isGranted",
         "file":"\/root\/vendor\/api-platform\/core\/src\/Security\/EventListener\/DenyAccessListener.php",
         "line":103,
         "args":[

         ]
      },
      {
         "namespace":"ApiPlatform\\Core\\Security\\EventListener",
         "short_class":"DenyAccessListener",
         "class":"ApiPlatform\\Core\\Security\\EventListener\\DenyAccessListener",
         "type":"-\u003E",
         "function":"checkSecurity",
         "file":"\/root\/vendor\/api-platform\/core\/src\/Security\/EventListener\/DenyAccessListener.php",
         "line":64,
         "args":[

         ]
      },
      {
         "namespace":"ApiPlatform\\Core\\Security\\EventListener",
         "short_class":"DenyAccessListener",
         "class":"ApiPlatform\\Core\\Security\\EventListener\\DenyAccessListener",
         "type":"-\u003E",
         "function":"onSecurity",
         "file":"\/root\/vendor\/symfony\/event-dispatcher\/Debug\/WrappedListener.php",
         "line":117,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\EventDispatcher\\Debug",
         "short_class":"WrappedListener",
         "class":"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener",
         "type":"-\u003E",
         "function":"__invoke",
         "file":"\/root\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php",
         "line":230,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\EventDispatcher",
         "short_class":"EventDispatcher",
         "class":"Symfony\\Component\\EventDispatcher\\EventDispatcher",
         "type":"-\u003E",
         "function":"callListeners",
         "file":"\/root\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php",
         "line":59,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\EventDispatcher",
         "short_class":"EventDispatcher",
         "class":"Symfony\\Component\\EventDispatcher\\EventDispatcher",
         "type":"-\u003E",
         "function":"dispatch",
         "file":"\/root\/vendor\/symfony\/event-dispatcher\/Debug\/TraceableEventDispatcher.php",
         "line":151,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\EventDispatcher\\Debug",
         "short_class":"TraceableEventDispatcher",
         "class":"Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher",
         "type":"-\u003E",
         "function":"dispatch",
         "file":"\/root\/vendor\/symfony\/http-kernel\/HttpKernel.php",
         "line":133,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\HttpKernel",
         "short_class":"HttpKernel",
         "class":"Symfony\\Component\\HttpKernel\\HttpKernel",
         "type":"-\u003E",
         "function":"handleRaw",
         "file":"\/root\/vendor\/symfony\/http-kernel\/HttpKernel.php",
         "line":79,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\HttpKernel",
         "short_class":"HttpKernel",
         "class":"Symfony\\Component\\HttpKernel\\HttpKernel",
         "type":"-\u003E",
         "function":"handle",
         "file":"\/root\/vendor\/symfony\/http-kernel\/Kernel.php",
         "line":195,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\HttpKernel",
         "short_class":"Kernel",
         "class":"Symfony\\Component\\HttpKernel\\Kernel",
         "type":"-\u003E",
         "function":"handle",
         "file":"\/root\/vendor\/symfony\/http-kernel\/HttpKernelBrowser.php",
         "line":63,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\HttpKernel",
         "short_class":"HttpKernelBrowser",
         "class":"Symfony\\Component\\HttpKernel\\HttpKernelBrowser",
         "type":"-\u003E",
         "function":"doRequest",
         "file":"\/root\/vendor\/symfony\/framework-bundle\/KernelBrowser.php",
         "line":159,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Bundle\\FrameworkBundle",
         "short_class":"KernelBrowser",
         "class":"Symfony\\Bundle\\FrameworkBundle\\KernelBrowser",
         "type":"-\u003E",
         "function":"doRequest",
         "file":"\/root\/vendor\/symfony\/browser-kit\/AbstractBrowser.php",
         "line":384,
         "args":[

         ]
      },
      {
         "namespace":"Symfony\\Component\\BrowserKit",
         "short_class":"AbstractBrowser",
         "class":"Symfony\\Component\\BrowserKit\\AbstractBrowser",
         "type":"-\u003E",
         "function":"request",
         "file":"\/root\/vendor\/api-platform\/core\/src\/Bridge\/Symfony\/Bundle\/Test\/Client.php",
         "line":126,
         "args":[

         ]
      },
      {
         "namespace":"ApiPlatform\\Core\\Bridge\\Symfony\\Bundle\\Test",
         "short_class":"Client",
         "class":"ApiPlatform\\Core\\Bridge\\Symfony\\Bundle\\Test\\Client",
         "type":"-\u003E",
         "function":"request",
         "file":"\/root\/tests\/Functional\/Controller\/PopulateProjectTest.php",
         "line":37,
         "args":[

         ]
      },
      {
         "namespace":"App\\Tests\\Functional\\Controller",
         "short_class":"PopulateProjectTest",
         "class":"App\\Tests\\Functional\\Controller\\PopulateProjectTest",
         "type":"-\u003E",
         "function":"testRateLimit",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/Framework\/TestCase.php",
         "line":1527,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\Framework",
         "short_class":"TestCase",
         "class":"PHPUnit\\Framework\\TestCase",
         "type":"-\u003E",
         "function":"runTest",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/Framework\/TestCase.php",
         "line":1133,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\Framework",
         "short_class":"TestCase",
         "class":"PHPUnit\\Framework\\TestCase",
         "type":"-\u003E",
         "function":"runBare",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/Framework\/TestResult.php",
         "line":722,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\Framework",
         "short_class":"TestResult",
         "class":"PHPUnit\\Framework\\TestResult",
         "type":"-\u003E",
         "function":"run",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/Framework\/TestCase.php",
         "line":885,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\Framework",
         "short_class":"TestCase",
         "class":"PHPUnit\\Framework\\TestCase",
         "type":"-\u003E",
         "function":"run",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/Framework\/TestSuite.php",
         "line":677,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\Framework",
         "short_class":"TestSuite",
         "class":"PHPUnit\\Framework\\TestSuite",
         "type":"-\u003E",
         "function":"run",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/Framework\/TestSuite.php",
         "line":677,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\Framework",
         "short_class":"TestSuite",
         "class":"PHPUnit\\Framework\\TestSuite",
         "type":"-\u003E",
         "function":"run",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/Framework\/TestSuite.php",
         "line":677,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\Framework",
         "short_class":"TestSuite",
         "class":"PHPUnit\\Framework\\TestSuite",
         "type":"-\u003E",
         "function":"run",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/TextUI\/TestRunner.php",
         "line":667,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\TextUI",
         "short_class":"TestRunner",
         "class":"PHPUnit\\TextUI\\TestRunner",
         "type":"-\u003E",
         "function":"run",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/TextUI\/Command.php",
         "line":143,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\TextUI",
         "short_class":"Command",
         "class":"PHPUnit\\TextUI\\Command",
         "type":"-\u003E",
         "function":"run",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/src\/TextUI\/Command.php",
         "line":96,
         "args":[

         ]
      },
      {
         "namespace":"PHPUnit\\TextUI",
         "short_class":"Command",
         "class":"PHPUnit\\TextUI\\Command",
         "type":"::",
         "function":"main",
         "file":"\/root\/bin\/.phpunit\/phpunit-9.5-0\/phpunit",
         "line":22,
         "args":[

         ]
      },
      {
         "namespace":"",
         "short_class":"",
         "class":"",
         "type":"",
         "function":"include",
         "file":"\/root\/vendor\/symfony\/phpunit-bridge\/bin\/simple-phpunit.php",
         "line":430,
         "args":[
            [
               "string",
               "\/root\/bin\/.phpunit\/phpunit-9.5-0\/phpunit"
            ]
         ]
      },
      {
         "namespace":"",
         "short_class":"",
         "class":"",
         "type":"",
         "function":"require",
         "file":"\/root\/bin\/phpunit",
         "line":13,
         "args":[
            [
               "string",
               "\/root\/vendor\/symfony\/phpunit-bridge\/bin\/simple-phpunit.php"
            ]
         ]
      }
   ]
}
alanpoulain commented 3 years ago

You are missing a ( in your expression.

darthf1 commented 3 years ago

Wow...

Apologies for the interruption. Thanks for pointing that out.