Skip to content
This repository has been archived by the owner on Sep 23, 2022. It is now read-only.

Add support for Symfony 5.1 #19

Merged
merged 1 commit into from Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 20 additions & 8 deletions .travis.yml
@@ -1,14 +1,26 @@
language: php
php:
- 7.0
- 7.1

matrix:
include:
- php: 7.0
env: 'COMPOSER_FLAGS="--prefer-lowest --prefer-stable"'
- php: 7.1
env: 'COMPOSER_FLAGS="--prefer-lowest --prefer-stable"'
- php: 7.2
env:
- COMPOSER_FLAGS=""
- php: 7.2
env:
- COMPOSER_FLAGS="--prefer-lowest --prefer-stable"
- php: 7.3
env:
- COMPOSER_FLAGS=""
- php: 7.3
env:
- COMPOSER_FLAGS="--prefer-lowest --prefer-stable"
- php: 7.4
env:
- COMPOSER_FLAGS=""
- PHP_CS=true
- php: 7.4
env:
- COMPOSER_FLAGS="--prefer-lowest --prefer-stable"

branches:
only:
Expand All @@ -18,5 +30,5 @@ before_script:
- composer update --prefer-source --dev $COMPOSER_FLAGS

script:
- if [[ "$PHP_CS" == "true" ]]; then bin/php-cs-fixer --diff --dry-run -v fix; fi
- bin/phpspec run -fpretty
- bin/php-cs-fixer --diff --dry-run -v fix
20 changes: 6 additions & 14 deletions README.md
Expand Up @@ -12,25 +12,17 @@ Provide RAD security components
# Installation

```bash
composer require knplabs/rad-security ~2.1
composer require knplabs/rad-security ~4.0
```

```php
class AppKernel
{
function registerBundles()
{
$bundles = array(
//...
new Knp\Rad\Security\Bundle\SecurityBundle(),
//...
);
// config/bundles.php

//...
<?php

return $bundles;
}
}
return [
Knp\Rad\Security\Bundle\SecurityBundle::class => ['all' => true],
];
```

# Use
Expand Down
16 changes: 9 additions & 7 deletions composer.json
Expand Up @@ -9,15 +9,17 @@
}
],
"require": {
"symfony/security": "~3.4||~4.3"
"symfony/security-core": "~5.1",
"symfony/http-kernel": "~5.1"
},
"require-dev": {
"php": ">=7.0.8",
"bossa/phpspec2-expect": "~2.0||~3.0",
"pedrotroller/php-cs-custom-fixer": "~2.17",
"phpspec/phpspec": "~4.0||~5.0||~6.0",
"symfony/dependency-injection": "~3.4||~4.3",
"symfony/event-dispatcher": "~3.4||~4.3"
"php": ">=7.2.5",
"bossa/phpspec2-expect": "~3.0",
"pedrotroller/php-cs-custom-fixer": "~2.23",
"friendsofphp/php-cs-fixer": "^2.16",
"phpspec/phpspec": "~6.0",
"symfony/dependency-injection": "~5.1",
"symfony/http-foundation": "~5.1"
},
"suggest": {
"knplabs/rad-resource-resolver": "Allows to check authorization against resources resolved from the routing."
Expand Down
120 changes: 86 additions & 34 deletions spec/Knp/Rad/Security/EventListener/AuthorizationListenerSpec.php
Expand Up @@ -6,8 +6,10 @@
use PhpSpec\ObjectBehavior;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class AuthorizationListenerSpec extends ObjectBehavior
{
Expand All @@ -21,59 +23,109 @@ function it_is_initializable()
$this->shouldHaveType('Knp\Rad\Security\EventListener\AuthorizationListener');
}

function it_checks_if_user_is_granted(FilterControllerEvent $event, Request $request, ParameterBag $attributes, OwnableInterface $ownable, $checker)
{
$event->getRequest()->willReturn($request);
function it_checks_if_user_is_granted(
HttpKernelInterface $kernel,
Request $request,
ParameterBag $attributes,
OwnableInterface $ownable,
$checker
) {
$event = new ControllerEvent(
$kernel->getWrappedObject(),
function() { return null; },
$request->getWrappedObject(),
null
);

$request->attributes = $attributes;
$attributes->get('_security', array())->willReturn(array(
array('roles' => array('IS_MEMBER', 'ANOTHER_ROLE')),
array('roles' => array('IS_OWNER'), 'subject' => 'group'),
));
$attributes->get('_security', [])->willReturn([
['roles' => ['IS_MEMBER', 'ANOTHER_ROLE']],
['roles' => ['IS_OWNER'], 'subject' => 'group'],
]);
$attributes->has('group')->willReturn(true);
$attributes->get('group')->willReturn($ownable);

$checker->isGranted(array('IS_MEMBER', 'ANOTHER_ROLE'), null)->willReturn(true);
$checker->isGranted(array('IS_OWNER'), $ownable)->willReturn(true);
$checker->isGranted('IS_MEMBER', null)->willReturn(true);
$checker->isGranted('ANOTHER_ROLE', null)->willReturn(false);
$checker->isGranted('IS_OWNER', $ownable)->willReturn(true);

$this->checkIfUserIsGranted($event);
$this
->shouldNotThrow(AccessDeniedException::class)
->during('checkIfUserIsGranted', [$event])
;
}

function it_throws_accept_denied_http_exception_when_it_is_not_authorized(FilterControllerEvent $event, Request $request, ParameterBag $attributes, OwnableInterface $ownable, $checker)
{
$event->getRequest()->willReturn($request);
function it_throws_accept_denied_http_exception_when_it_is_not_authorized(
HttpKernelInterface $kernel,
Request $request,
ParameterBag $attributes,
OwnableInterface $ownable,
$checker
) {
$event = new ControllerEvent(
$kernel->getWrappedObject(),
function() { return null; },
$request->getWrappedObject(),
null
);

$request->attributes = $attributes;
$attributes->get('_security', array())->willReturn(array(
array('roles' => array('IS_MEMBER')),
));
$attributes->get('_security', [])->willReturn([
['roles' => ['IS_MEMBER']],
]);

$checker->isGranted(array('IS_MEMBER'), null)->willReturn(false);
$checker->isGranted('IS_MEMBER', null)->willReturn(false);

$this
->shouldThrow('Symfony\Component\Security\Core\Exception\AccessDeniedException')
->during('checkIfUserIsGranted', array($event))
->shouldThrow(AccessDeniedException::class)
->during('checkIfUserIsGranted', [$event])
;
}

function it_throws_an_exception_when_the_role_parameter_is_not_specified(FilterControllerEvent $event, Request $request, ParameterBag $attributes)
{
$event->getRequest()->willReturn($request);
function it_throws_an_exception_when_the_role_parameter_is_not_specified(
HttpKernelInterface $kernel,
Request $request,
ParameterBag $attributes
) {
$event = new ControllerEvent(
$kernel->getWrappedObject(),
function() { return null; },
$request->getWrappedObject(),
null
);

$request->attributes = $attributes;
$attributes->get('_security', array())->willReturn(array(
array('typo_in_role_parameter' => ''),
));
$attributes->get('_security', [])->willReturn([
['typo_in_role_parameter' => ''],
]);

$this->shouldthrow('RuntimeException')->during('checkIfUserIsGranted', array($event));
$this
->shouldthrow('RuntimeException')
->during('checkIfUserIsGranted', [$event])
;
}

function it_throws_an_exception_when_a_required_object_is_not_found(FilterControllerEvent $event, Request $request, ParameterBag $attributes)
{
$event->getRequest()->willReturn($request);
function it_throws_an_exception_when_a_required_object_is_not_found(
HttpKernelInterface $kernel,
Request $request,
ParameterBag $attributes
) {
$event = new ControllerEvent(
$kernel->getWrappedObject(),
function() { return null; },
$request->getWrappedObject(),
null
);

$request->attributes = $attributes;
$attributes->get('_security', array())->willReturn(array(
array('roles' => array('IS_OWNER'), 'subject' => 'group'),
));
$attributes->get('_security', [])->willReturn([
['roles' => ['IS_OWNER'], 'subject' => 'group'],
]);
$attributes->has('group')->willReturn(false);

$this->shouldThrow('RuntimeException')->during('checkIfUserIsGranted', array($event));
$this
->shouldThrow('RuntimeException')
->during('checkIfUserIsGranted', [$event])
;
}
}
20 changes: 14 additions & 6 deletions src/Knp/Rad/Security/EventListener/AuthorizationListener.php
Expand Up @@ -2,7 +2,7 @@

namespace Knp\Rad\Security\EventListener;

use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;

Expand All @@ -21,12 +21,12 @@ public function __construct(AuthorizationCheckerInterface $checker)
$this->checker = $checker;
}

public function checkIfUserIsGranted(FilterControllerEvent $event)
public function checkIfUserIsGranted(ControllerEvent $event)
{
$request = $event->getRequest();

foreach ($request->attributes->get('_security', array()) as $rule) {
$roles = array();
foreach ($request->attributes->get('_security', []) as $rule) {
$roles = [];

if (isset($rule['roles']) && ! empty($rule['roles'])) {
$roles = $rule['roles'];
Expand All @@ -35,7 +35,7 @@ public function checkIfUserIsGranted(FilterControllerEvent $event)
}

if (is_string($roles)) {
$roles = array($roles);
$roles = [$roles];
}

$subject = null;
Expand All @@ -51,7 +51,15 @@ public function checkIfUserIsGranted(FilterControllerEvent $event)
$subject = $request->attributes->get($subjectName);
}

if ( ! $this->checker->isGranted($roles, $subject)) {
$authorized = false;

foreach ($roles as $role) {
if ($this->checker->isGranted($role, $subject)) {
$authorized = true;
}
}

if ( ! $authorized) {
throw new AccessDeniedException();
}
}
Expand Down