mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Merge branch add_acl ref #263
Squashed commit of the following: commit e1236655e1514fd207818aeb57789eca0d949453 Merge: c0b349b fb15bd3 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Tue Jun 30 09:51:35 2015 +0200 Merge remote-tracking branch 'origin/master' into add_acl In order to prepare merging of add_acl to master Conflicts: composer.json commit c0b349bb5f31fe79c84f82d4dd6658c9e90ef728 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Tue Jun 30 00:40:13 2015 +0200 fix infos in composer.json [ci skip] commit 106bbf56a5060efd2a89232f278692eeb57e3092 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Mon Jun 29 22:58:48 2015 +0200 add username and password to client auth options [ci skip] commit c4990972711850616aa1426394884223d63b504f Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Mon Jun 29 22:22:20 2015 +0200 fix quoting in timelinebuilder commit 1db7cbea5a0fb0e8d396f8c9d8dc01240b47e96f Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Thu Jun 25 22:43:46 2015 +0200 remove data_class to allow edit form commit 7c999279310b5e2b9ecef8a9b5001c71910a822d Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Wed Jun 24 22:33:42 2015 +0200 fix doc for AppendScopeChoiceTypeTrait commit 839d4c43bf6f463e705b47d5dbc0cdf7853db0b6 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Wed Jun 24 22:30:13 2015 +0200 refactor: move scope field to a trait Example usage : ``` class AbcType extends Symfony\Component\Form\AbstractType { use AppendScopeChoiceTypeTrait; protected $authorizationHelper; protected $translatableStringHelper; protected $user; public function __construct(AuthorizationHelper $helper, TokenStorageInterface $tokenStorage, TranslatableStringHelper $translatableStringHelper) { $this->authorizationHelper = $helper; $this->user = $tokenStorage->getToken()->getUser(); $this->translatableStringHelper = $translatableStringHelper; } public function buildForm(FormBuilder $builder, array $options) { // ... add your form there // append the scope using FormEvents: PRE_SET_DATA $this->appendScopeChoices($builder, $options['role'], $options['center'], $this->user, $this->authorizationHelper, $this->translatableStringHelper); } public function configureOptions(OptionsResolver $resolver) { // ... add your options // add an option 'role' and 'center' to your form (optional) $this->appendScopeChoicesOptions($resolver); } } ``` [ci skip] commit a1ac530f343146eee12b5982e4e6fceb6dc1da66 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Wed Jun 24 00:24:30 2015 +0200 remove unused statements commit 74f0a4ce5dfdfa4f8fc39ce1cfe726d945e9bdec Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Wed Jun 24 00:09:47 2015 +0200 add missing unused statement commit b3a49f2de8758b51c57af6ff0437f30b2fdef72e Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Tue Jun 23 23:58:57 2015 +0200 remove ScopeType strategy and fix autorization helper commit aaa70b5eeae76b0950110f51b8274e08bef10576 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Tue Jun 23 21:35:06 2015 +0200 create scope type commit 8f5b2b23c9448b8c8e752e46bdd7f9f721054a98 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 19 18:13:54 2015 +0200 add getREachableCenter method + test on Autho.Helper commit ab2ccb8c287f9aef12912ea9b7f5dc4998209d77 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 19 17:27:22 2015 +0200 remove debug information [ci skip] commit 9d481c07966a5d769d1418bb366bd6b1ea9d4f76 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 19 17:24:57 2015 +0200 fix role hierarchy Now we test effectively that a user has access, not that a role may grant access commit f4b17d0ae398fd6c26d4907377761e9f15d36a90 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Thu Jun 18 02:08:55 2015 +0200 fix trait conflicts traits does not share the same instance of prophet any more commit baac8ce97ba0acd4c4fe6f03278f7a0d30da28ad Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Thu Jun 18 01:56:39 2015 +0200 try to fix trait error in zend strict mode (used by travis) commit 7b9fa4b14bde72c7036a29c03a0c6cca3c7e6c74 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Thu Jun 18 01:24:09 2015 +0200 fix error on trait hierarchy (should be) commit f8b3451089f7017653bf8d280b640356df6a1841 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Thu Jun 18 01:03:04 2015 +0200 add userHasAccess method to AuthorizationHelper This method may be used in voter to check access. It supports both hasCenterInterface and HasScopeInterface and check all required permission. commit 9ad9f624a0aa73ca2e639fd68fe4d5559da2bbd7 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Thu Jun 18 01:01:16 2015 +0200 add utilities to generate prophesized entities entities - User (with permissions) - Center - Scope may be generated by trait/methods This ease test writing about acl commit 16008b9e64bb7f551319abea494db1c1c5a12b82 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 12 22:42:46 2015 +0200 add test to CenterType commit 55e2c64aba9714caf09df8dbc9595980826b296a Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 12 20:50:05 2015 +0200 first implementation of test on CenterType [TRANSFER][ci skip] commit 548fb24927cc470794a51d81f1ba6af52237363f Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Wed Jun 10 21:15:52 2015 +0200 add center type the center type is hidden if the current user can reach only one center, and is `entity` type if the user can reach multiple centers commit 024e3ef8d969d25560406864d86768a260ef4402 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Mon Jun 8 00:28:51 2015 +0200 add first impl of Access Model - first classes and interfaces - authorizationHelper + test - rewrite loadUser to have multi-center commit bc5ae70c83c39a0a738e78313e33020fc284f456 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Sun Jun 7 22:11:13 2015 +0200 make deprecations message not fail tests commit ab9308ed62e45171e9d355ec033b0862b9274e07 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Sat Jun 6 10:19:19 2015 +0200 introducting phpunit-bridge to handle deprecation warnings commit 5b7a43c4d058af58578c30120670c5be5b11cfd8 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 5 12:49:23 2015 +0200 fix options resolver deprecation commit a5b4e5743f790c16dfd04e5068c5ecca9c2b1583 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 5 12:36:17 2015 +0200 remove warning about deprecation in phpunit commit 56621767936df1ea1293c49ae06380d7735c8d6c Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 5 11:59:50 2015 +0200 fix pattern deprecation in routing/test pattern=> path commit 17d40fc5294b245d7377572a8c918abab2484985 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 5 11:40:59 2015 +0200 fix deprecation of pattern in routing pattern => path in routing commit 6a33752c6439bd9dbc707df010ce1d8765eeb5fe Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 5 11:21:18 2015 +0200 fix twig.form.resources deprecation the new key is twig.form_themes commit adf03eb819f2d443f87d7b744f59a5adf51d2b31 Author: Julien Fastré <julien.fastre@champs-libres.coop> Date: Fri Jun 5 10:56:51 2015 +0200 switch to symfony 2.7 [ci-skip]
This commit is contained in:
parent
fb15bd336c
commit
8ac41a15b6
@ -32,31 +32,54 @@ class LoadUsers extends AbstractFixture implements OrderedFixtureInterface, Cont
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public static $refs = array();
|
||||
public static $refs = array(
|
||||
'center a_social' => array(
|
||||
'groupCenterRefs' => ['centerA_permission_group_social']
|
||||
),
|
||||
'center a_administrative' => array(
|
||||
'groupCenterRefs' => ['centerA_permission_group_administrative']
|
||||
),
|
||||
'center a_direction' => array(
|
||||
'groupCenterRefs' => ['centerA_permission_group_direction']
|
||||
),
|
||||
'center b_social' => array(
|
||||
'groupCenterRefs' => ['centerB_permission_group_social']
|
||||
),
|
||||
'center b_administrative' => array(
|
||||
'groupCenterRefs' => ['centerB_permission_group_administrative']
|
||||
),
|
||||
'center b_direction' => array(
|
||||
'groupCenterRefs' => ['centerB_permission_group_direction']
|
||||
),
|
||||
'multi_center' => array(
|
||||
'groupCenterRefs' => ['centerA_permission_group_social',
|
||||
'centerB_permission_group_social']
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
public function load(ObjectManager $manager)
|
||||
{
|
||||
foreach(LoadCenters::$refs as $centerRef) {
|
||||
foreach(LoadPermissionsGroup::$refs as $permissionGroupRef) {
|
||||
$user = new User();
|
||||
|
||||
$permissionGroup = $this->getReference($permissionGroupRef);
|
||||
$center = $this->getReference($centerRef);
|
||||
$username = strtolower($center->getName().'_'.$permissionGroup->getName());
|
||||
|
||||
$user->setUsername($username)
|
||||
->setPassword($this->container->get('security.encoder_factory')
|
||||
foreach (self::$refs as $username => $params) {
|
||||
|
||||
$user = new User();
|
||||
|
||||
$user->setUsername($username)
|
||||
->setPassword(
|
||||
$this->container->get('security.encoder_factory')
|
||||
->getEncoder($user)
|
||||
->encodePassword('password', $user->getSalt()));
|
||||
$user->addGroupCenter($this->getReference($centerRef.'_'.$permissionGroupRef));
|
||||
|
||||
$manager->persist($user);
|
||||
$this->addReference($username, $user);
|
||||
static::$refs[] = $user->getUsername();
|
||||
echo "Creating user with username '".$user->getUsername()."' and password 'password'.. \n";
|
||||
->encodePassword('password', $user->getSalt())
|
||||
);
|
||||
|
||||
foreach ($params['groupCenterRefs'] as $groupCenterRef) {
|
||||
$user->addGroupCenter($this->getReference($groupCenterRef));
|
||||
}
|
||||
|
||||
echo 'Creating user ' . $username ."... \n";
|
||||
$manager->persist($user);
|
||||
$this->addReference($username, $user);
|
||||
}
|
||||
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,7 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface
|
||||
'name' => $config['installation_name']),
|
||||
'available_languages' => $config['available_languages']
|
||||
),
|
||||
'form' => array(
|
||||
'resources' => array('ChillMainBundle:Form:fields.html.twig'))
|
||||
'form_themes' => array('ChillMainBundle:Form:fields.html.twig')
|
||||
);
|
||||
$container->prependExtensionConfig('twig', $twigConfig);
|
||||
|
||||
|
@ -21,7 +21,6 @@ namespace Chill\MainBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Add services taggued with `name: chill.timeline` to
|
||||
|
@ -76,6 +76,11 @@ class Center
|
||||
$this->groupCenters->add($groupCenter);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Country
|
||||
*/
|
||||
|
36
Entity/HasCenterInterface.php
Normal file
36
Entity/HasCenterInterface.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
/**
|
||||
* Interface for entities which may be linked to a center
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface HasCenterInterface
|
||||
{
|
||||
/**
|
||||
* the linked center
|
||||
*
|
||||
* @return Center
|
||||
*/
|
||||
public function getCenter();
|
||||
}
|
35
Entity/HasScopeInterface.php
Normal file
35
Entity/HasScopeInterface.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
/**
|
||||
* Interface for entities which have a scop
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface HasScopeInterface
|
||||
{
|
||||
/**
|
||||
* Return the linked scope
|
||||
*
|
||||
* @return Scope
|
||||
*/
|
||||
public function getScope();
|
||||
}
|
153
Form/Type/AppendScopeChoiceTypeTrait.php
Normal file
153
Form/Type/AppendScopeChoiceTypeTrait.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
* Copyright (C) 2015 Champs Libres <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Chill\MainBundle\Form\Type\DataTransformer\ScopeTransformer;
|
||||
|
||||
/**
|
||||
* Trait to add an input with reachable scope for a given center and role.
|
||||
*
|
||||
* Example usage :
|
||||
*
|
||||
* ```
|
||||
* class AbcType extends Symfony\Component\Form\AbstractType
|
||||
* {
|
||||
* use AppendScopeChoiceTypeTrait;
|
||||
* protected $authorizationHelper;
|
||||
* protected $translatableStringHelper;
|
||||
* protected $user;
|
||||
* protected $om;
|
||||
*
|
||||
* public function __construct(AuthorizationHelper $helper,
|
||||
* TokenStorageInterface $tokenStorage,
|
||||
* TranslatableStringHelper $translatableStringHelper,
|
||||
* ObjectManager $om)
|
||||
* {
|
||||
* $this->authorizationHelper = $helper;
|
||||
* $this->user = $tokenStorage->getToken()->getUser();
|
||||
* $this->translatableStringHelper = $translatableStringHelper;
|
||||
* $this->om = $om;
|
||||
* }
|
||||
*
|
||||
* public function buildForm(FormBuilder $builder, array $options)
|
||||
* {
|
||||
* // ... add your form there
|
||||
*
|
||||
* // append the scope using FormEvents: PRE_SET_DATA
|
||||
* $this->appendScopeChoices($builder, $options['role'],
|
||||
* $options['center'], $this->user, $this->authorizationHelper,
|
||||
* $this->translatableStringHelper, $this->om);
|
||||
* }
|
||||
*
|
||||
* public function configureOptions(OptionsResolver $resolver)
|
||||
* {
|
||||
* // ... add your options
|
||||
*
|
||||
* // add an option 'role' and 'center' to your form (optional)
|
||||
* $this->appendScopeChoicesOptions($resolver);
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @author Champs Libres <info@champs-libres.coop>
|
||||
*/
|
||||
trait AppendScopeChoiceTypeTrait
|
||||
{
|
||||
/**
|
||||
* Append a scope choice field, with the scopes reachable by given
|
||||
* user for the given role and center.
|
||||
*
|
||||
* The field is added on event FormEvents::PRE_SET_DATA
|
||||
*
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param Role $role
|
||||
* @param Center $center
|
||||
* @param User $user
|
||||
* @param AuthorizationHelper $authorizationHelper
|
||||
* @param TranslatableStringHelper $translatableStringHelper
|
||||
* @param string $name
|
||||
*/
|
||||
protected function appendScopeChoices(FormBuilderInterface $builder,
|
||||
Role $role, Center $center, User $user,
|
||||
AuthorizationHelper $authorizationHelper,
|
||||
TranslatableStringHelper $translatableStringHelper,
|
||||
ObjectManager $om, $name = 'scope')
|
||||
{
|
||||
$reachableScopes = $authorizationHelper
|
||||
->getReachableScopes($user, $role, $center);
|
||||
|
||||
$choices = array();
|
||||
foreach($reachableScopes as $scope) {
|
||||
$choices[$scope->getId()] = $translatableStringHelper
|
||||
->localize($scope->getName());
|
||||
}
|
||||
|
||||
$dataTransformer = new ScopeTransformer($om);
|
||||
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA,
|
||||
function (FormEvent $event) use ($choices, $name, $dataTransformer, $builder) {
|
||||
$form = $event->getForm();
|
||||
$form->add(
|
||||
$builder
|
||||
->create($name, 'choice', array(
|
||||
'choices' => $choices,
|
||||
'auto_initialize' => false
|
||||
)
|
||||
)
|
||||
->addModelTransformer($dataTransformer)
|
||||
->getForm()
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a `role` and `center` option to the form.
|
||||
*
|
||||
* The allowed types are :
|
||||
* - Chill\MainBundle\Entity\Center for center
|
||||
* - Symfony\Component\Security\Core\Role\Role for role
|
||||
*
|
||||
* @param OptionsResolver $resolver
|
||||
*/
|
||||
public function appendScopeChoicesOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setRequired(array('center', 'role'))
|
||||
->setAllowedTypes(array(
|
||||
'center' => 'Chill\MainBundle\Entity\Center',
|
||||
'role' => 'Symfony\Component\Security\Core\Role\Role'
|
||||
))
|
||||
;
|
||||
}
|
||||
|
||||
}
|
138
Form/Type/CenterType.php
Normal file
138
Form/Type/CenterType.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Form\Type\DataTransformer\CenterTransformer;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class CenterType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* The user linked with this type.
|
||||
*
|
||||
* @var \Chill\MainBundle\Entity\User
|
||||
*/
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* associative array where keys are center.id and
|
||||
* value are center objects
|
||||
*
|
||||
* @var Center[]
|
||||
*/
|
||||
protected $reachableCenters = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var CenterTransformer
|
||||
*/
|
||||
protected $transformer;
|
||||
|
||||
public function __construct(TokenStorage $tokenStorage,
|
||||
CenterTransformer $transformer)
|
||||
{
|
||||
$this->user = $tokenStorage->getToken()->getUser();
|
||||
$this->transformer = $transformer;
|
||||
$this->prepareReachableCenterByUser();
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'center';
|
||||
}
|
||||
|
||||
/**
|
||||
* return a 'hidden' field if only one center is available.
|
||||
*
|
||||
* Return a 'choice' field if more than one center is available.
|
||||
*
|
||||
* @return string
|
||||
* @throws \RuntimeException if the user is not associated with any center
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
$nbReachableCenters = count($this->reachableCenters);
|
||||
|
||||
if ($nbReachableCenters === 0) {
|
||||
throw new \RuntimeException("The user is not associated with "
|
||||
. "any center. Associate user with a center");
|
||||
} elseif ($nbReachableCenters === 1) {
|
||||
return 'hidden';
|
||||
} else {
|
||||
return 'entity';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* configure default options, i.e. add choices if user can reach multiple
|
||||
* centers.
|
||||
*
|
||||
* @param OptionsResolver $resolver
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
if (count($this->reachableCenters) > 1) {
|
||||
$resolver->setDefault('class', 'Chill\MainBundle\Entity\Center');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add a data transformer if user can reach only one center
|
||||
*
|
||||
* @param FormBuilderInterface $builder
|
||||
* @param array $options
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
if ($this->getParent() === 'hidden') {
|
||||
$builder->addModelTransformer($this->transformer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* populate reachableCenters as an associative array where
|
||||
* keys are center.id and value are center entities.
|
||||
*
|
||||
*/
|
||||
private function prepareReachableCenterByUser()
|
||||
{
|
||||
$groupCenters = $this->user->getGroupCenters();
|
||||
|
||||
foreach ($groupCenters as $groupCenter) {
|
||||
|
||||
$center = $groupCenter->getCenter();
|
||||
|
||||
if (!array_key_exists($center->getId(),
|
||||
$this->reachableCenters)) {
|
||||
$this->reachableCenters[$center->getId()] = $center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
70
Form/Type/DataTransformer/CenterTransformer.php
Normal file
70
Form/Type/DataTransformer/CenterTransformer.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type\DataTransformer;
|
||||
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
|
||||
/**
|
||||
* Transform a center object to his id, and vice-versa
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class CenterTransformer implements DataTransformerInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var ObjectManager
|
||||
*/
|
||||
private $om;
|
||||
|
||||
public function __construct(ObjectManager $om)
|
||||
{
|
||||
$this->om = $om;
|
||||
}
|
||||
|
||||
public function reverseTransform($id)
|
||||
{
|
||||
if ($id === NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$center = $this->om->getRepository('ChillMainBundle:Center')
|
||||
->find($id);
|
||||
|
||||
if ($center === NULL) {
|
||||
throw new TransformationFailedException(sprintf(
|
||||
'No center found with id %d', $id));
|
||||
}
|
||||
|
||||
return $center;
|
||||
}
|
||||
|
||||
public function transform($center)
|
||||
{
|
||||
if ($center === NULL) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $center->getId();
|
||||
}
|
||||
|
||||
}
|
77
Form/Type/DataTransformer/ScopeTransformer.php
Normal file
77
Form/Type/DataTransformer/ScopeTransformer.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type\DataTransformer;
|
||||
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class ScopeTransformer implements DataTransformerInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var ObjectManager
|
||||
*/
|
||||
protected $om;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var TranslatableStringHelper
|
||||
*/
|
||||
protected $helper;
|
||||
|
||||
public function __construct(ObjectManager $om)
|
||||
{
|
||||
$this->om = $om;
|
||||
}
|
||||
|
||||
public function transform($scope)
|
||||
{
|
||||
if ($scope === NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $scope->getId();
|
||||
}
|
||||
|
||||
public function reverseTransform($id)
|
||||
{
|
||||
if ($id == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$scope = $this->om->getRepository('ChillMainBundle:Scope')
|
||||
->find($id);
|
||||
|
||||
if ($scope === NULL) {
|
||||
throw new TransformationFailedException(sprintf("The scope with id "
|
||||
. "'%d' were not found", $id));
|
||||
}
|
||||
|
||||
return $scope;
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* Extends choice to allow adding select2 library on widget
|
||||
@ -40,9 +40,9 @@ class Select2ChoiceType extends AbstractType
|
||||
return 'choice';
|
||||
}
|
||||
|
||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->replaceDefaults(
|
||||
$resolver->setDefaults(
|
||||
array('attr' => array('class' => 'select2 '))
|
||||
);
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Chill\MainBundle\Form\Type\DataTransformer\ObjectToIdTransformer;
|
||||
|
@ -22,7 +22,6 @@ namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
use Chill\MainBundle\Entity\Language;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Chill\MainBundle\Form\Type\DataTransformer\MultipleObjectsToIdTransformer;
|
||||
|
@ -1,16 +1,16 @@
|
||||
root:
|
||||
pattern: /
|
||||
path: /
|
||||
defaults:
|
||||
_controller: FrameworkBundle:Redirect:urlRedirect
|
||||
path: /homepage
|
||||
permanent: true
|
||||
|
||||
chill_main_homepage_without_locale:
|
||||
pattern: /homepage
|
||||
path: /homepage
|
||||
defaults: { _controller: ChillMainBundle:Default:indexWithoutLocale }
|
||||
|
||||
chill_main_homepage:
|
||||
pattern: /{_locale}/homepage
|
||||
path: /{_locale}/homepage
|
||||
defaults: { _controller: ChillMainBundle:Default:index }
|
||||
options:
|
||||
menus:
|
||||
@ -20,7 +20,7 @@ chill_main_homepage:
|
||||
icons: [home]
|
||||
|
||||
chill_main_export_index:
|
||||
pattern: /{_locale}/export
|
||||
path: /{_locale}/export
|
||||
defaults: { _controller: ChillMainBundle:Export:index }
|
||||
options:
|
||||
menus:
|
||||
@ -30,7 +30,7 @@ chill_main_export_index:
|
||||
icons: [upload]
|
||||
|
||||
chill_main_admin_central:
|
||||
pattern: /{_locale}/admin
|
||||
path: /{_locale}/admin
|
||||
defaults: { _controller: ChillMainBundle:Admin:index }
|
||||
options:
|
||||
menus:
|
||||
@ -40,7 +40,7 @@ chill_main_admin_central:
|
||||
icons: [gears]
|
||||
|
||||
chill_main_search:
|
||||
pattern: /{_locale}/search
|
||||
path: /{_locale}/search
|
||||
defaults: { _controller: ChillMainBundle:Search:search }
|
||||
|
||||
login:
|
||||
|
@ -81,6 +81,19 @@ services:
|
||||
- "@doctrine.orm.entity_manager"
|
||||
tags:
|
||||
- { name: form.type, alias: select2_chill_language }
|
||||
|
||||
chill.main.form.type.center:
|
||||
class: Chill\MainBundle\Form\Type\CenterType
|
||||
arguments:
|
||||
- "@security.token_storage"
|
||||
- "@chill.main.form.data_transformer.center_transformer"
|
||||
tags:
|
||||
- { name: form.type, alias: center }
|
||||
|
||||
chill.main.form.data_transformer.center_transformer:
|
||||
class: Chill\MainBundle\Form\Type\DataTransformer\CenterTransformer
|
||||
arguments:
|
||||
- "@doctrine.orm.entity_manager"
|
||||
|
||||
chill.main.search_provider:
|
||||
class: Chill\MainBundle\Search\SearchProvider
|
||||
@ -91,3 +104,8 @@ services:
|
||||
- "@doctrine.orm.entity_manager"
|
||||
calls:
|
||||
- [ setContainer, ["@service_container"]]
|
||||
|
||||
chill.main.security.authorization.helper:
|
||||
class: Chill\MainBundle\Security\Authorization\AuthorizationHelper
|
||||
arguments:
|
||||
- "@security.role_hierarchy"
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Chill\MainBundle\Routing;
|
||||
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
36
Security/Authorization/AbstractChillVoter.php
Normal file
36
Security/Authorization/AbstractChillVoter.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
|
||||
|
||||
/**
|
||||
* Voter for Chill software.
|
||||
*
|
||||
* This abstract Voter provide generic methods to handle object specific to Chill
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
abstract class AbstractChillVoter extends AbstractVoter implements ChillVoterInterface
|
||||
{
|
||||
|
||||
|
||||
}
|
209
Security/Authorization/AuthorizationHelper.php
Normal file
209
Security/Authorization/AuthorizationHelper.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||
use Chill\MainBundle\Entity\HasScopeInterface;
|
||||
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
|
||||
/**
|
||||
* Helper for authorizations.
|
||||
*
|
||||
* Provides methods for user and entities information.
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class AuthorizationHelper
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var RoleHierarchyInterface
|
||||
*/
|
||||
protected $roleHierarchy;
|
||||
|
||||
protected $existingRoles = array('CHILL_MASTER_ROLE', 'CHILL_PERSON_SEE',
|
||||
'CHILL_PERSON_UPDATE',);
|
||||
|
||||
public function __construct(RoleHierarchyInterface $roleHierarchy)
|
||||
{
|
||||
$this->roleHierarchy = $roleHierarchy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a user is active on this center
|
||||
*
|
||||
* @param User $user
|
||||
* @param Center $center
|
||||
* @return bool
|
||||
*/
|
||||
public function userCanReachCenter(User $user, Center $center)
|
||||
{
|
||||
foreach ($user->getGroupCenters() as $groupCenter) {
|
||||
if ($center->getId() === $groupCenter->getCenter()->getId()) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Determines if the user has access to the given entity.
|
||||
*
|
||||
* if the entity implements Chill\MainBundle\Entity\HasScopeInterface,
|
||||
* the scope is taken into account.
|
||||
*
|
||||
* @param User $user
|
||||
* @param HasCenterInterface $entity the entity may also implement HasScopeInterface
|
||||
* @param string|Role $attribute
|
||||
* @return boolean true if the user has access
|
||||
*/
|
||||
public function userHasAccess(User $user, HasCenterInterface $entity, $attribute)
|
||||
{
|
||||
|
||||
$center = $entity->getCenter();
|
||||
|
||||
if (!$this->userCanReachCenter($user, $center)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$role = ($attribute instanceof Role) ? $attribute : new Role($attribute);
|
||||
|
||||
foreach ($user->getGroupCenters() as $groupCenter){
|
||||
//filter on center
|
||||
if ($groupCenter->getCenter()->getId() === $entity->getCenter()->getId()) {
|
||||
//iterate on permissionGroup
|
||||
foreach($groupCenter->getPermissionGroups() as $permissionGroup) {
|
||||
//iterate on roleScopes
|
||||
foreach($permissionGroup->getRoleScopes() as $roleScope) {
|
||||
//check that the role allow to reach the required role
|
||||
if ($this->isRoleReached($role,
|
||||
new Role($roleScope->getRole()))){
|
||||
//if yes, we have a right on something...
|
||||
// perform check on scope if necessary
|
||||
if ($entity instanceof HasScopeInterface) {
|
||||
$scope = $entity->getScope();
|
||||
if ($scope->getId() === $roleScope
|
||||
->getScope()->getId()) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reachable Centers for the given user, role,
|
||||
* and optionnaly Scope
|
||||
*
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param null|Scope $scope
|
||||
* @return Center[]
|
||||
*/
|
||||
public function getReachableCenters(User $user, Role $role, Scope $scope = null)
|
||||
{
|
||||
$centers = array();
|
||||
|
||||
foreach ($user->getGroupCenters() as $groupCenter){
|
||||
//iterate on permissionGroup
|
||||
foreach($groupCenter->getPermissionGroups() as $permissionGroup) {
|
||||
//iterate on roleScopes
|
||||
foreach($permissionGroup->getRoleScopes() as $roleScope) {
|
||||
//check that the role is in the reachable roles
|
||||
if ($this->isRoleReached($role,
|
||||
new Role($roleScope->getRole()))) {
|
||||
if ($scope === null) {
|
||||
$centers[] = $groupCenter->getCenter();
|
||||
break 2;
|
||||
} else {
|
||||
if ($scope->getId() == $roleScope->getScope()->getId()){
|
||||
$centers[] = $groupCenter->getCenter();
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $centers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all reachable scope for a given user, center and role
|
||||
*
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param Center $center
|
||||
* @return Scope[]
|
||||
*/
|
||||
public function getReachableScopes(User $user, Role $role, Center $center)
|
||||
{
|
||||
$scopes = array();
|
||||
|
||||
foreach ($user->getGroupCenters() as $groupCenter){
|
||||
if ($center->getId() === $groupCenter->getCenter()->getId()) {
|
||||
//iterate on permissionGroup
|
||||
foreach($groupCenter->getPermissionGroups() as $permissionGroup) {
|
||||
//iterate on roleScopes
|
||||
foreach($permissionGroup->getRoleScopes() as $roleScope) {
|
||||
//check that the role is in the reachable roles
|
||||
if ($this->isRoleReached($role,
|
||||
new Role($roleScope->getRole()))) {
|
||||
|
||||
$scopes[] = $roleScope->getScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $scopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a parent role may give access to a given child role
|
||||
*
|
||||
* @param Role $childRole The role we want to test if he is reachable
|
||||
* @param Role $parentRole The role which should give access to $childRole
|
||||
* @return boolean true if the child role is granted by parent role
|
||||
*/
|
||||
protected function isRoleReached(Role $childRole, Role $parentRole)
|
||||
{
|
||||
$reachableRoles = $this->roleHierarchy
|
||||
->getReachableRoles([$parentRole]);
|
||||
|
||||
return in_array($childRole, $reachableRoles);
|
||||
}
|
||||
}
|
30
Security/Authorization/ChillVoterInterface.php
Normal file
30
Security/Authorization/ChillVoterInterface.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
/**
|
||||
* Provides methods for compiling voter and build admin role fields.
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface ChillVoterInterface
|
||||
{
|
||||
|
||||
}
|
59
Test/PrepareCenterTrait.php
Normal file
59
Test/PrepareCenterTrait.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Test;
|
||||
|
||||
|
||||
/**
|
||||
* A trait to prepare center
|
||||
*
|
||||
* **Usage :** You must set up trait with `setUpTrait` before use
|
||||
* and use tearDownTrait after usage.
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait PrepareCenterTrait
|
||||
{
|
||||
|
||||
private $centerProphet;
|
||||
|
||||
/**
|
||||
* prepare a mocked center, with and id and name given
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $name
|
||||
* @return \Chill\MainBundle\Entity\Center
|
||||
*/
|
||||
protected function prepareCenter($id, $name)
|
||||
{
|
||||
|
||||
if ($this->centerProphet === NULL) {
|
||||
$this->centerProphet = new \Prophecy\Prophet();
|
||||
}
|
||||
|
||||
$center = $this->centerProphet->prophesize();
|
||||
$center->willExtend('\Chill\MainBundle\Entity\Center');
|
||||
$center->getId()->willReturn($id);
|
||||
$center->getName()->willReturn($name);
|
||||
|
||||
return $center->reveal();
|
||||
}
|
||||
|
||||
}
|
57
Test/PrepareScopeTrait.php
Normal file
57
Test/PrepareScopeTrait.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Test;
|
||||
|
||||
/**
|
||||
* A trait to prepare center
|
||||
*
|
||||
* **Usage :** You must set up trait with `setUpTrait` before use
|
||||
* and use tearDownTrait after usage.
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait PrepareScopeTrait
|
||||
{
|
||||
private $scopeProphet;
|
||||
|
||||
/**
|
||||
* prepare a mocked center, with and id and name given
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $name
|
||||
* @return \Chill\MainBundle\Entity\Center
|
||||
*/
|
||||
protected function prepareScope($id, $name)
|
||||
{
|
||||
|
||||
if ($this->scopeProphet === NULL) {
|
||||
$this->scopeProphet = new \Prophecy\Prophet();
|
||||
}
|
||||
|
||||
$scope = $this->scopeProphet->prophesize();
|
||||
$scope->willExtend('\Chill\MainBundle\Entity\Scope');
|
||||
$scope->getId()->willReturn($id);
|
||||
$scope->getName()->willReturn($name);
|
||||
|
||||
return $scope->reveal();
|
||||
}
|
||||
}
|
85
Test/PrepareUserTrait.php
Normal file
85
Test/PrepareUserTrait.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Test;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\GroupCenter;
|
||||
use Chill\MainBundle\Entity\RoleScope;
|
||||
use Chill\MainBundle\Entity\PermissionsGroup;
|
||||
|
||||
/**
|
||||
* A trait to prepare user with permission. May be used
|
||||
* within tests.
|
||||
*
|
||||
* **Usage : ** You must set up trait with `setUpTrait` before use
|
||||
* and use tearDownTrait after usage.
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait PrepareUserTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* prepare a user with correct permissions
|
||||
*
|
||||
* Example of permissions:
|
||||
* ```
|
||||
* array(
|
||||
* array( 'center' => $centerA, 'permissionsGroup' => array(
|
||||
* [ 'role' => 'CHILL_REPORT_SEE', 'scope' => $scopeA]
|
||||
* ),
|
||||
* array( 'center' => $centerB, 'permissionsGroup' => array(
|
||||
* [ 'role' => 'CHILL_ACTIVITY_UPDATE', 'scope' => $scopeB]
|
||||
* )
|
||||
* )
|
||||
* ```
|
||||
* Scope must be an int. Scope created have this int as id, and the
|
||||
* int converted to string as name.
|
||||
*
|
||||
*
|
||||
* @param array $permissions an array of permissions, with key 'center' for the center and key 'attrs' for an array of ['role' => (string), 'scope' => (int)]
|
||||
* @return User
|
||||
* @throws \LogicException if the trait is not set up
|
||||
*/
|
||||
protected function prepareUser(array $permissions)
|
||||
{
|
||||
$user = new User();
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
$groupCenter = (new GroupCenter())
|
||||
->setCenter($permission['center']);
|
||||
$permissionGroup = new PermissionsGroup();
|
||||
foreach ($permission['permissionsGroup'] as $pg) {
|
||||
|
||||
$roleScope = (new RoleScope())
|
||||
->setRole($pg['role'])
|
||||
->setScope($pg['scope']);
|
||||
;
|
||||
$permissionGroup->addRoleScope($roleScope);
|
||||
$groupCenter->addPermissionGroup($permissionGroup);
|
||||
}
|
||||
$user->addGroupCenter($groupCenter);
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
}
|
53
Test/ProphecyTrait.php
Normal file
53
Test/ProphecyTrait.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Test;
|
||||
|
||||
/**
|
||||
* a trait to prepare prophecy
|
||||
*
|
||||
* **Usage : ** You must set up trait with `setUpTrait` before use
|
||||
* and use tearDownTrait after usage.
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
trait ProphecyTrait
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \Prophecy\Prophet()
|
||||
*/
|
||||
private $prophet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \Prophecy\Prophet
|
||||
*/
|
||||
public function getProphet()
|
||||
{
|
||||
if ($this->prophet === NULL) {
|
||||
$this->prophet = new \Prophecy\Prophet();
|
||||
}
|
||||
|
||||
return $this->prophet;
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,8 @@ framework:
|
||||
storage_id: session.storage.filesystem
|
||||
|
||||
security:
|
||||
role_hierarchy:
|
||||
CHILL_MASTER_ROLE: [CHILL_INHERITED_ROLE_1]
|
||||
providers:
|
||||
users:
|
||||
entity:
|
||||
|
@ -2,7 +2,7 @@ hello_bundle:
|
||||
resource: "@ChillMainBundle/Resources/config/routing.yml"
|
||||
|
||||
chill_main_dummy_0:
|
||||
pattern: /dummy
|
||||
path: /dummy
|
||||
defaults: { _controller: ChillMainBundle:Default:index }
|
||||
options:
|
||||
menus:
|
||||
@ -15,7 +15,7 @@ chill_main_dummy_0:
|
||||
label: test dummy 1
|
||||
|
||||
chill_main_dummy_1:
|
||||
pattern: /dummy1
|
||||
path: /dummy1
|
||||
defaults: { _controller: ChillMainBundle:Default:index }
|
||||
options:
|
||||
menus:
|
||||
@ -25,7 +25,7 @@ chill_main_dummy_1:
|
||||
helper: 'great helper'
|
||||
|
||||
chill_main_dummy_2:
|
||||
pattern: /dummy2/{param}
|
||||
path: /dummy2/{param}
|
||||
defaults: {_controller: ChillMainBundle:Default:index }
|
||||
options:
|
||||
menus:
|
||||
|
153
Tests/Form/Type/CenterTypeTest.php
Normal file
153
Tests/Form/Type/CenterTypeTest.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\Test\TypeTestCase;
|
||||
use Chill\MainBundle\Form\Type\CenterType;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\GroupCenter;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class CenterTypeTest extends TypeTestCase
|
||||
{
|
||||
/**
|
||||
* Test that a user which can reach only one center
|
||||
* render as an hidden field
|
||||
*/
|
||||
public function testUserCanReachSingleCenter()
|
||||
{
|
||||
//prepare user
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$groupCenter = (new GroupCenter())
|
||||
->setCenter($center)
|
||||
;
|
||||
$user = (new User())
|
||||
->addGroupCenter($groupCenter);
|
||||
|
||||
$type = $this->prepareType($user);
|
||||
|
||||
$this->assertEquals('hidden', $type->getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a user which can reach only one center
|
||||
* render as an hidden field
|
||||
*/
|
||||
public function testUserCanReachMultipleSameCenter()
|
||||
{
|
||||
//prepare user
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$groupCenterA = (new GroupCenter())
|
||||
->setCenter($center)
|
||||
;
|
||||
$groupCenterB = (new GroupCenter())
|
||||
->setCenter($center)
|
||||
;
|
||||
$user = (new User())
|
||||
->addGroupCenter($groupCenterA)
|
||||
->addGroupCenter($groupCenterB);
|
||||
|
||||
$type = $this->prepareType($user);
|
||||
|
||||
$this->assertEquals('hidden', $type->getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a user which can reach multiple center
|
||||
* make CenterType render as "entity" type.
|
||||
*/
|
||||
public function testUserCanReachMultipleCenters()
|
||||
{
|
||||
//prepare user
|
||||
$centerA = $this->prepareCenter(1, 'centerA');
|
||||
$centerB = $this->prepareCenter(2, 'centerB');
|
||||
$groupCenterA = (new GroupCenter())
|
||||
->setCenter($centerA)
|
||||
;
|
||||
$groupCenterB = (new GroupCenter())
|
||||
->setCenter($centerB)
|
||||
;
|
||||
$user = (new User())
|
||||
->addGroupCenter($groupCenterA)
|
||||
->addGroupCenter($groupCenterB)
|
||||
;
|
||||
|
||||
$type = $this->prepareType($user);
|
||||
|
||||
$this->assertEquals('entity', $type->getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* prepare a mocked center, with and id and name given
|
||||
*
|
||||
* @param int $id
|
||||
* @param string $name
|
||||
* @return \Chill\MainBundle\Entity\Center
|
||||
*/
|
||||
private function prepareCenter($id, $name)
|
||||
{
|
||||
$prophet = new \Prophecy\Prophet;
|
||||
|
||||
$prophecyCenter = $prophet->prophesize();
|
||||
$prophecyCenter->willExtend('\Chill\MainBundle\Entity\Center');
|
||||
$prophecyCenter->getId()->willReturn($id);
|
||||
$prophecyCenter->getName()->willReturn($name);
|
||||
|
||||
return $prophecyCenter->reveal();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* prepare the type with mocked center transformer and token storage
|
||||
*
|
||||
* @param User $user the user for wich the form will be prepared
|
||||
* @return CenterType
|
||||
*/
|
||||
private function prepareType(User $user)
|
||||
{
|
||||
$prophet = new \Prophecy\Prophet;
|
||||
|
||||
//create a center transformer
|
||||
$centerTransformerProphecy = $prophet->prophesize();
|
||||
$centerTransformerProphecy
|
||||
->willExtend('Chill\MainBundle\Form\Type\DataTransformer\CenterTransformer');
|
||||
$transformer = $centerTransformerProphecy->reveal();
|
||||
|
||||
$tokenProphecy = $prophet->prophesize();
|
||||
$tokenProphecy
|
||||
->willImplement('\Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
|
||||
$tokenProphecy->getUser()->willReturn($user);
|
||||
$token = $tokenProphecy->reveal();
|
||||
|
||||
$tokenStorageProphecy = $prophet->prophesize();
|
||||
$tokenStorageProphecy
|
||||
->willExtend('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage');
|
||||
$tokenStorageProphecy->getToken()->willReturn($token);
|
||||
$tokenStorage = $tokenStorageProphecy->reveal();
|
||||
|
||||
return new CenterType($tokenStorage, $transformer);
|
||||
}
|
||||
|
||||
}
|
448
Tests/Security/Authorization/AuthorizationHelperTest.php
Normal file
448
Tests/Security/Authorization/AuthorizationHelperTest.php
Normal file
@ -0,0 +1,448 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Tests\Security\Authorization;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
use Chill\MainBundle\Test\PrepareUserTrait;
|
||||
use Chill\MainBundle\Test\PrepareCenterTrait;
|
||||
use Chill\MainBundle\Test\PrepareScopeTrait;
|
||||
use Chill\MainBundle\Test\ProphecyTrait;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class AuthorizationHelperTest extends KernelTestCase
|
||||
{
|
||||
|
||||
use PrepareUserTrait, PrepareCenterTrait, PrepareScopeTrait, ProphecyTrait;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
static::bootKernel();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \Chill\MainBundle\Security\Authorization\AuthorizationHelper
|
||||
*/
|
||||
private function getAuthorizationHelper()
|
||||
{
|
||||
return static::$kernel->getContainer()
|
||||
->get('chill.main.security.authorization.helper')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function userCanReach of helper.
|
||||
*
|
||||
* A user can reach center => the function should return true.
|
||||
*/
|
||||
public function testUserCanReachCenter_UserShouldReach()
|
||||
{
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $center, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'ANY_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
|
||||
$this->assertTrue($helper->userCanReachCenter($user, $center));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function userCanReach of helper
|
||||
*
|
||||
* A user can not reachcenter =>W the function should return false
|
||||
*/
|
||||
public function testUserCanReachCenter_UserShouldNotReach()
|
||||
{
|
||||
$centerA = $this->prepareCenter(1, 'center');
|
||||
$centerB = $this->prepareCenter(2, 'centerB');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $centerA, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'ANY_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
|
||||
$this->assertFalse($helper->userCanReachCenter($user, $centerB));
|
||||
|
||||
}
|
||||
|
||||
public function testUserHasAccess_shouldHaveAccess_EntityWithoutScope()
|
||||
{
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $center, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'CHILL_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->getCenter()->willReturn($center);
|
||||
|
||||
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(),
|
||||
'CHILL_ROLE'));
|
||||
}
|
||||
|
||||
public function testUserHasAccess_ShouldHaveAccessWithInheritance_EntityWithoutScope()
|
||||
{
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $center, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'CHILL_MASTER_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->getCenter()->willReturn($center);
|
||||
|
||||
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(),
|
||||
'CHILL_INHERITED_ROLE_1'));
|
||||
}
|
||||
|
||||
|
||||
public function testuserHasAccess_UserHasNoRole_EntityWithoutScope()
|
||||
{
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $center, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'ANY_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->getCenter()->willReturn($center);
|
||||
|
||||
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that a user has no access on a entity, but is granted on the same role
|
||||
* on another center
|
||||
*/
|
||||
public function testUserHasAccess_userHasNoRole_UserHasRoleOnAnotherCenter_EntityWithoutScope()
|
||||
{
|
||||
$centerA = $this->prepareCenter(1, 'center');
|
||||
$centerB = $this->prepareCenter(2, 'centerB');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $centerA, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'ANY_ROLE']
|
||||
),
|
||||
array(
|
||||
'centerB' => $centerB, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'ANY_ROLE'],
|
||||
['scope' => $scope, 'role' => 'CHILL_ROLE']
|
||||
)
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->getCenter()->willReturn($centerA);
|
||||
|
||||
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
||||
}
|
||||
|
||||
public function testtestUserHasAccess_UserShouldHaveAccess_EntityWithScope()
|
||||
{
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $center, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'CHILL_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
|
||||
$entity->getCenter()->willReturn($center);
|
||||
$entity->getScope()->willReturn($scope);
|
||||
|
||||
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
||||
}
|
||||
|
||||
public function testUserHasAccess_UserHasNoRole_EntityWithScope()
|
||||
{
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $center, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'CHILL_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
|
||||
$entity->getCenter()->willReturn($center);
|
||||
$entity->getScope()->willReturn($scope);
|
||||
|
||||
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'ANOTHER_ROLE'));
|
||||
}
|
||||
|
||||
public function testUserHasAccess_UserHasNoCenter_EntityWithScope()
|
||||
{
|
||||
$centerA = $this->prepareCenter(1, 'center'); //the user will have this center
|
||||
$centerB = $this->prepareCenter(2, 'centerB'); //the entity will have another center
|
||||
$scope = $this->prepareScope(1, 'default');
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $centerA, 'permissionsGroup' => array(
|
||||
['scope' => $scope, 'role' => 'CHILL_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
|
||||
$entity->getCenter()->willReturn($centerB);
|
||||
$entity->getScope()->willReturn($scope);
|
||||
|
||||
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
||||
}
|
||||
|
||||
public function testUserHasAccess_UserHasNoScope_EntityWithScope()
|
||||
{
|
||||
$center = $this->prepareCenter(1, 'center');
|
||||
$scopeA = $this->prepareScope(1, 'default'); //the entity will have this scope
|
||||
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
|
||||
$user = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $center, 'permissionsGroup' => array(
|
||||
['scope' => $scopeB, 'role' => 'CHILL_ROLE']
|
||||
)
|
||||
)
|
||||
));
|
||||
$helper = $this->getAuthorizationHelper();
|
||||
$entity = $this->getProphet()->prophesize();
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
|
||||
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
|
||||
$entity->getCenter()->willReturn($center);
|
||||
$entity->getScope()->willReturn($scopeA);
|
||||
|
||||
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @dataProvider dataProvider_getReachableCenters
|
||||
* @param Center $shouldHaveCenter
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param Scope $scope
|
||||
*/
|
||||
public function testGetReachableCenters($test, $result, $msg)
|
||||
{
|
||||
$this->assertEquals($test, $result, $msg);
|
||||
}
|
||||
|
||||
public function dataProvider_getReachableCenters()
|
||||
{
|
||||
$this->setUp();
|
||||
$centerA = $this->prepareCenter(1, 'center A');
|
||||
$centerB = $this->prepareCenter(2, 'center B');
|
||||
$scopeA = $this->prepareScope(1, 'scope default');
|
||||
$scopeB = $this->prepareScope(2, 'scope B');
|
||||
$scopeC = $this->prepareScope(3, 'scope C');
|
||||
|
||||
$userA = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $centerA,
|
||||
'permissionsGroup' => array(
|
||||
['scope' => $scopeB, 'role' => 'CHILL_ROLE_1'],
|
||||
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2']
|
||||
)
|
||||
),
|
||||
array(
|
||||
'center' => $centerB,
|
||||
'permissionsGroup' => array(
|
||||
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
|
||||
['scope' => $scopeC, 'role' => 'CHILL_ROLE_2']
|
||||
)
|
||||
)
|
||||
|
||||
));
|
||||
|
||||
$ah = $this->getAuthorizationHelper();
|
||||
|
||||
return array(
|
||||
// without scopes
|
||||
array(
|
||||
true,
|
||||
in_array($centerA, $ah->getReachableCenters($userA,
|
||||
new Role('CHILL_ROLE_1'), null)),
|
||||
'center A should be available for userA, with role 1 '
|
||||
),
|
||||
array(
|
||||
true,
|
||||
in_array($centerA, $ah->getReachableCenters($userA,
|
||||
new Role('CHILL_ROLE_2'), null)),
|
||||
'center A should be available for userA, with role 2 '
|
||||
),
|
||||
array(
|
||||
true,
|
||||
in_array($centerB, $ah->getReachableCenters($userA,
|
||||
new Role('CHILL_ROLE_2'), null)),
|
||||
'center A should be available for userA, with role 2 '
|
||||
),
|
||||
array(
|
||||
false,
|
||||
in_array($centerB, $ah->getReachableCenters($userA,
|
||||
new Role('CHILL_ROLE_1'), null)),
|
||||
'center B should NOT be available for userA, with role 1 '
|
||||
),
|
||||
// with scope
|
||||
array(
|
||||
true,
|
||||
in_array($centerA, $ah->getReachableCenters($userA,
|
||||
new Role('CHILL_ROLE_1'), $scopeB)),
|
||||
'center A should be available for userA, with role 1, scopeC '
|
||||
),
|
||||
array(
|
||||
false,
|
||||
in_array($centerA, $ah->getReachableCenters($userA,
|
||||
new Role('CHILL_ROLE_2'), $scopeC)),
|
||||
'center A should NOT be available for userA, with role 2, scopeA '
|
||||
),
|
||||
array(
|
||||
true,
|
||||
in_array($centerB, $ah->getReachableCenters($userA,
|
||||
new Role('CHILL_ROLE_2'), $scopeA)),
|
||||
'center B should be available for userA, with role 2, scopeA '
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @dataProvider dataProvider_getReachableScopes
|
||||
* @param boolean $expectedResult
|
||||
* @param Scope $testedScope
|
||||
* @param User $user
|
||||
* @param Role $role
|
||||
* @param Center $center
|
||||
* @param string $message
|
||||
*/
|
||||
public function testGetReachableScopes($expectedResult, Scope $testedScope,
|
||||
User $user, Role $role, Center $center, $message)
|
||||
{
|
||||
$reachableScopes = $this->getAuthorizationHelper()
|
||||
->getReachableScopes($user, $role, $center);
|
||||
|
||||
$this->assertEquals($expectedResult, in_array($testedScope, $reachableScopes),
|
||||
$message);
|
||||
}
|
||||
|
||||
public function dataProvider_getReachableScopes()
|
||||
{
|
||||
$centerA = $this->prepareCenter(1, 'center A');
|
||||
$centerB = $this->prepareCenter(2, 'center B');
|
||||
$scopeA = $this->prepareScope(1, 'scope default');
|
||||
$scopeB = $this->prepareScope(2, 'scope B');
|
||||
$scopeC = $this->prepareScope(3, 'scope C');
|
||||
|
||||
$userA = $this->prepareUser(array(
|
||||
array(
|
||||
'center' => $centerA,
|
||||
'permissionsGroup' => array(
|
||||
['scope' => $scopeB, 'role' => 'CHILL_ROLE_1'],
|
||||
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2']
|
||||
)
|
||||
),
|
||||
array(
|
||||
'center' => $centerB,
|
||||
'permissionsGroup' => array(
|
||||
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
|
||||
['scope' => $scopeC, 'role' => 'CHILL_ROLE_2'],
|
||||
['scope' => $scopeB, 'role' => 'CHILL_ROLE_2']
|
||||
)
|
||||
)
|
||||
|
||||
));
|
||||
|
||||
return array(
|
||||
array(
|
||||
true,
|
||||
$scopeA,
|
||||
$userA,
|
||||
new Role('CHILL_ROLE_2'),
|
||||
$centerA,
|
||||
"Assert that a scope is found within accessible scopes"
|
||||
),
|
||||
array(
|
||||
false,
|
||||
$scopeB,
|
||||
$userA,
|
||||
new Role('CHILL_ROLE_2'),
|
||||
$centerA,
|
||||
"Assert that a scope not reachable is NOT found within accessible scopes"
|
||||
),
|
||||
array(
|
||||
false,
|
||||
$scopeB,
|
||||
$userA,
|
||||
new Role('CHILL_ROLE_1'),
|
||||
$centerB,
|
||||
"Assert that a scope not reachable is not found within accessible scopes."
|
||||
. " Trying on filter centering"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -36,11 +36,12 @@ class TestHelper
|
||||
* @param WebTestCase $testCase
|
||||
* @return \Symfony\Component\BrowserKit\Client authenticated client
|
||||
*/
|
||||
public static function getAuthenticatedClientOptions()
|
||||
public static function getAuthenticatedClientOptions($username = 'center a_social',
|
||||
$password = 'password')
|
||||
{
|
||||
return array(
|
||||
'PHP_AUTH_USER' => 'center a_social',
|
||||
'PHP_AUTH_PW' => 'password',
|
||||
'PHP_AUTH_USER' => $username,
|
||||
'PHP_AUTH_PW' => $password,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -150,8 +150,8 @@ class TimelineBuilder implements ContainerAwareInterface
|
||||
$data = $provider->fetchQuery($context, $args);
|
||||
|
||||
return sprintf(
|
||||
'SELECT "%s" AS id, '
|
||||
. '"%s" AS "date", '
|
||||
'SELECT %s AS id, '
|
||||
. '%s AS "date", '
|
||||
. "'%s' AS type "
|
||||
. 'FROM %s '
|
||||
. 'WHERE %s',
|
||||
|
@ -3,8 +3,14 @@
|
||||
"license": "AGPL-3.0",
|
||||
"type": "symfony-bundle",
|
||||
"description": "The main bundle for the Chill App",
|
||||
"keywords" : ["chill", "social work"],
|
||||
"homepage" : "https://github.com/Chill-project/Main",
|
||||
"keywords" : ["chill", "social work", "software for social service"],
|
||||
"homepage" : "http://chill.social",
|
||||
"support": {
|
||||
"email": "dev@lists.chill.social",
|
||||
"issues": "https://redmine.champs-libres.coop/projects/chillmain/issues",
|
||||
"sources": "https://github.com/chill-project/main",
|
||||
"docs": "http://chill.readthedocs.org"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Chill\\MainBundle\\": "" }
|
||||
},
|
||||
@ -20,9 +26,9 @@
|
||||
"twig/extensions": "~1.0",
|
||||
"symfony/assetic-bundle": "~2.3",
|
||||
"symfony/monolog-bundle": "~2.4",
|
||||
"symfony/framework-bundle": "2.5.*",
|
||||
"symfony/yaml": "2.5.*",
|
||||
"symfony/symfony": "2.5.*",
|
||||
"symfony/framework-bundle": "~2.7",
|
||||
"symfony/yaml": "~2.7",
|
||||
"symfony/symfony": "~2.7",
|
||||
"doctrine/dbal": "~2.5",
|
||||
"doctrine/orm": "~2.4",
|
||||
"doctrine/common": "~2.4",
|
||||
@ -34,7 +40,8 @@
|
||||
"require-dev": {
|
||||
"symfony/dom-crawler": "2.5",
|
||||
"doctrine/doctrine-fixtures-bundle": "~2.2",
|
||||
"symfony/security": "~2.5"
|
||||
"symfony/security": "~2.5",
|
||||
"symfony/phpunit-bridge": "^2.7"
|
||||
},
|
||||
"scripts": {
|
||||
"post-install-cmd": [
|
||||
|
@ -18,5 +18,6 @@
|
||||
</filter>
|
||||
<php>
|
||||
<server name="KERNEL_DIR" value="./Tests/Fixtures/App/" />
|
||||
<env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
|
||||
</php>
|
||||
</phpunit>
|
||||
|
Loading…
x
Reference in New Issue
Block a user