diff --git a/Security/Authorization/Expression/Ast/GetItemExpression.php b/Security/Authorization/Expression/Ast/GetItemExpression.php index 2df5eb0..38ab4be 100644 --- a/Security/Authorization/Expression/Ast/GetItemExpression.php +++ b/Security/Authorization/Expression/Ast/GetItemExpression.php @@ -18,7 +18,7 @@ namespace JMS\SecurityExtraBundle\Security\Authorization\Expression\Ast; -class GetItemExpression +class GetItemExpression implements ExpressionInterface { public $array; public $key; @@ -28,4 +28,4 @@ public function __construct(ExpressionInterface $array, ExpressionInterface $key $this->array = $array; $this->key = $key; } -} \ No newline at end of file +} diff --git a/Security/Authorization/Expression/ExpressionCompiler.php b/Security/Authorization/Expression/ExpressionCompiler.php index 9b0a6d8..81afeb5 100644 --- a/Security/Authorization/Expression/ExpressionCompiler.php +++ b/Security/Authorization/Expression/ExpressionCompiler.php @@ -274,6 +274,14 @@ public function compilePreconditions(ExpressionInterface $expr) return $this; } + if ($expr instanceof GetItemExpression) { + $this + ->compilePreconditions($expr->array) + ->compilePreconditions($expr->key); + + return $this; + } + if ($expr instanceof GetPropertyExpression) { $this->compilePreconditions($expr->object); @@ -317,7 +325,9 @@ public function compileInternal(ExpressionInterface $expr) if ($expr instanceof GetItemExpression) { $this->compileInternal($expr->array); - $this->code .= '['.$expr->key.']'; + $this->code .= '['; + $this->compileInternal($expr->key); + $this->code .= ']'; return $this; } diff --git a/Tests/Security/Authorization/Expression/GetItemExpressionCompilerTest.php b/Tests/Security/Authorization/Expression/GetItemExpressionCompilerTest.php new file mode 100644 index 0000000..deaad51 --- /dev/null +++ b/Tests/Security/Authorization/Expression/GetItemExpressionCompilerTest.php @@ -0,0 +1,74 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace JMS\SecurityExtraBundle\Tests\Security\Authorization\Expression; + +use JMS\SecurityExtraBundle\Security\Authorization\Expression\Expression; +use JMS\SecurityExtraBundle\Security\Authorization\Expression\ExpressionCompiler; + +class GetItemExpressionCompilerTest extends \PHPUnit_Framework_TestCase +{ + private $compiler; + + public function testCompile() + { + $evaluator = eval($source = $this->compiler->compileExpression(new Expression( + 'object["foo"] == "bar"'))); + + $this->assertTrue($evaluator(array('object' => array('foo' => 'bar')))); + + $this->assertFalse($evaluator(array('object' => array('foo' => 'baz')))); + } + + public function testCompileWithComplexKey() + { + $evaluator = eval($source = $this->compiler->compileExpression(new Expression( + 'object[key] == "bar"'))); + + $this->assertTrue($evaluator(array('object' => array('foo' => 'bar'), 'key' => 'foo'))); + + $this->assertFalse($evaluator(array('object' => array('foo' => 'baz'), 'key' => 'foo'))); + } + + /** + * @expectedException \RuntimeException + */ + public function testCompilePreconditionsForKey() + { + $evaluator = eval($source = $this->compiler->compileExpression(new Expression( + 'object[key] == "bar"'))); + + $evaluator(array('object' => array('foo' => 'bar'))); + } + + /** + * @expectedException \RuntimeException + */ + public function testCompilePreconditionsForArray() + { + $evaluator = eval($source = $this->compiler->compileExpression(new Expression( + 'object[key] == "bar"'))); + + $evaluator(array('key' => 'foo')); + } + + protected function setUp() + { + $this->compiler = new ExpressionCompiler(); + } +}