Merge add_ui_permission into master

refs #573

Squashed commit of the following:

commit f0974ee386050e34495eecd29c69bee50644309a
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 21:34:50 2015 +0200

    center validation

    name must be between 3 and 50 characters and not blank

commit 359b79f6674e3665df3213b04a9b4b69bcdb1537
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 21:26:11 2015 +0200

    RoleScope: scope absence validation if role does not require it

commit 40d7930699a9b48d31f151d0febb46de5b356192
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 21:09:47 2015 +0200

    improve welcome message

commit 72298510f99699c4dd501ef589f5997a28d0884d
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 21:06:16 2015 +0200

    layout of center

commit 9ac6ae7dae38bd7c2ac3ab5a0bfd3753d13ca294
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 17:41:37 2015 +0200

    layout of circles

commit 5fc27ae078ca422ff44367198492aebbbb49a38a
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 17:34:45 2015 +0200

    Merge modification from origin/master

    commit 7ed87b92fc4a3941a07b3295ee55b8fe2c1a96fe
    Author: Julien Fastré <julien@fastre.info>
    Date:   Mon Sep 14 15:43:29 2015 +0200

        adding signature (proof of concept)

    commit 2e2b8f5c8557cdd8be00372b5e3e43b0b9bad1f6
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Sep 1 16:51:39 2015 +0200

        Search result with a padding

    commit 7dc3514e00c16ac74beb4c7486d1a202510294f5
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Wed Aug 26 13:29:17 2015 +0200

        Blue as default color for table header

    commit 2b45d4cec5028abe7d49d44da4fa937a2b1ecddf
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Wed Aug 26 13:15:53 2015 +0200

        Tables as Thibault design

    commit deb12a117d6eed7cef602d2e2723009f142eb78f
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Aug 25 19:51:15 2015 +0200

        Improving the navigation bar

    commit 8c3ea5b8667fd3aa40fa0d311f8d80a2a0c905b5
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Aug 25 18:29:34 2015 +0200

        Adding class for colors

    commit 251f51bab2ce82c2eb78e30d345075e8bbb9b02b
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Aug 25 17:31:22 2015 +0200

        Menu person as thibautl propose

    commit 2457ff021a6ff7a324ebadd163880838ec16be4d
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Aug 25 17:29:51 2015 +0200

        updating select2

    commit d339b70f2d5190dcfd4a210e338c8910430d2e48
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Aug 25 17:29:16 2015 +0200

        updating select2

    commit 767a72e3cfd49acdd3fdacc68b5f041571b99780
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Aug 25 17:28:50 2015 +0200

        Refactoring : removing useless line return

    commit 5bb74ab09e1933f97eb8d897e5f5791c791c7a56
    Author: Marc Ducobu <marc@champs-libres.coop>
    Date:   Tue Aug 25 13:31:48 2015 +0200

        Removing css specific for the person bundle

commit ca8a597b3c858d27f59346e841f2cbded4b66e9b
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 17:33:14 2015 +0200

    add correct key for flash messages

commit b3fc4c1b7eea6bc87459a290b295a7c54c550da4
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 17:32:22 2015 +0200

    set a flash message to correct level

commit 3425de79c029039a8df4657b7cc672359199dbf5
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 17:24:28 2015 +0200

    layout of permissions group + translations

commit 670d7f64fa6e1073015810bc92f0a11def9bef4b
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 16:41:46 2015 +0200

    layout of user (include translations)

commit ed8a7fdebe91a8c94ae3338c756796758de184a2
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 11:49:13 2015 +0200

    rename route entries prefix for center with "admin_center"

commit d1d229e4e13d3fcd3ab70319ae04062a691344ff
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 20 11:39:48 2015 +0200

    add menu for permissions management

commit 972cc15ae370a0faab58d26c9fcdf6e36cc19077
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Fri Sep 18 21:10:04 2015 +0200

    add logger to tests fixtures

commit b8b34b090acd3971098349a5e5d2e8d608714a4f
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Fri Sep 18 17:12:45 2015 +0200

    allow blank roles scopes in show action

commit 3673c60de4b4a5d8f7f72638a10209fe53084b16
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Fri Sep 18 17:05:15 2015 +0200

    allow role scope without scope required

    Some roles doesn't need to be associated with a scope.

    Example: CHILL_PERSON_SEE, ... => The person aren't associated with a scope.

    Now we may check if a role must be associated with a scope.

commit e14cda12a412b2c2af54e662db5925a99f594cd7
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Fri Sep 18 11:33:49 2015 +0200

    add user creation

    The form UserType receive a new parameter: 'is_creation' (boolean). If
    'is_creation' is true, (false by default) the field "enabled" is removed
    (new users are enabled by default) and a field "password" ask for a
    password.

commit d4f59a01a708e5d310a8e99fe2796292bc8da121
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Fri Sep 18 11:04:40 2015 +0200

    add possibility to change password

commit cdddfffd3dcde9f673f0042f8eb55b90d76412f5
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Sep 17 23:18:21 2015 +0200

    mark test empty to avoid failure

commit 82eee24a5d4b71a3deef7dc250ae8a747569d892
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Sep 17 22:34:23 2015 +0200

    remove & add groupCenter to user + validation

    The validation check that groupCenter are associated only once to the
    user.

commit 7e774de4d1c72cc3ba5d221251aa505653c06621
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Sep 17 22:25:02 2015 +0200

    remove deprecated key

commit aeb7bf5ef56bf4e4939400b85e9393b72c2e1658
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Wed Sep 16 22:28:13 2015 +0200

    correct generated code for user entity

    * index view
    * show a user
    * edit a user: general form + remove a group center

commit 6d8e1bba6e163c7dc93bc05a74cdb9dd839f8749
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Sep 15 21:14:48 2015 +0200

    add message if group does not have any permissions

commit 6a3a2938c3066c95b2672a88f244c3c9ea7bff64
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Mon Sep 14 00:43:40 2015 +0200

    set role declaration in compiler pass

    This should ease development.

    The role are now declared into the bundle and not in configuration. The
    role can be added alongside with voters.

    To declare role, add a service which implements
    `Chill\MainBundle\Security\ProvideRoleInterface` and declare the service
    with a tag `chill.role`

    <pre>
    my_service:
       # ...
       tags:
          - { name: chill.role }
    </pre>

commit fe28360e9253493c91ab2c02cdbad7a36f76047c
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 13 23:55:39 2015 +0200

    add validation for permissions group

    * name must be max 50 and not empty
    * the same role scope must be present only once

commit 2e2653f43388e65379c2285db1354a32c683cd65
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 13 22:23:28 2015 +0200

    fix permission group new/creation

    * Layout of "new" form
    * after "new" form posting, the "create" action redirect to edit form
    * (to add roleScopes to the new permissionsgroup)

commit fbe97c882e1bbf06668a02effed5996777c8020e
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sat Sep 12 14:20:29 2015 +0200

    change strategy to keep roleScope uniques

    The form 'permissiongroupType' doesn't handle link to role scope any
    more.

    Those link are handled by the controller, which generate a form to
    add/delete link between roleScopes and permissionsGroup.

commit e11fe7644312ae25b46202b9f0733823e75ffa9d
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Sun Sep 6 23:00:37 2015 +0200

    the controller prevent creation of duplicated/update of roleScopes

commit 81c8b12fa4d2f2ae88206a4a5086b13615462b74
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Fri Sep 4 17:25:39 2015 +0200

    add persistance for allowing new role_scopes

commit 912b004daf0b3f1208ef1e11b2424f88ea78a90a
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Mon Aug 31 23:49:11 2015 +0200

    fix generated code of CRUD permissionsgroup

    + add a ComposedRoleScopeType to prepare creation "on the fly" of RoleScopes.

    + add a new parameter chill.available_roles to let other bundle declare their roles.

commit baf970538fbac4ff778540e23aa70efff3937883
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Aug 27 15:19:30 2015 +0200

    Remove deletion of PermissionsGroup from autogenerated code

commit c5774bf5564d8279f9fcab15b61823857f438387
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Aug 27 15:11:36 2015 +0200

    replace setDefaultOptions by configureOptions

    setDefaultOptions will be removed in symfony 3.0

commit 8bef7328203c2d0e635b51fac901a520330d6cd2
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Aug 27 14:55:32 2015 +0200

    Fix auto-generated CRUD for Center

    Add ChillMainBundle layout, translations, ...

commit 9d6e77e15d50e797570ccb8ca56d035ce752cc80
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Aug 27 09:10:05 2015 +0200

    remove delete methods, url, link for center

    Centers cannot be deleted.

commit 1fdedd56329dd4f58d7d0460ef197ab17f7db755
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Thu Aug 27 09:08:32 2015 +0200

    remove delete url on scope

commit ef371fac696e521e8570ca63c868421f0dd02af2
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Aug 25 16:50:30 2015 +0200

    fix auto-generation for scope/circle

commit eb67639673543f8153308b2fa863047ec0eeddc3
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Aug 25 16:21:01 2015 +0200

    add autogenerated crud for entity permissionGroup

commit 38c8a60f56e0870f5c196daa7e1d6851ea6edb8e
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Aug 25 16:19:46 2015 +0200

    add autogenerated user entity

commit 554ca141bba6b1a4da81f9fe806d02c369221bea
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Aug 25 16:18:35 2015 +0200

    add autogenerated crud for scopes

commit 0cfb587f15df979e6f61e4363b42d443034580fd
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Aug 25 16:17:22 2015 +0200

    add auto-generated crud for center

commit 65651dd8ffda02869117ee5fd782b50bf4aa5219
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Aug 25 15:27:37 2015 +0200

    remove deprecated function in groupCenter

    GroupCenter::addPermissionGroup and getPermissionGroups is now removed.

commit f957aa416ff610c29917367ff5b6e81467e7dd95
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Tue Aug 25 14:46:58 2015 +0200

    set correct association in permissionGroup

commit 5852c169385c908eecc952155d73de4db506274b
Author: Julien Fastré <julien.fastre@champs-libres.coop>
Date:   Fri Aug 21 12:37:43 2015 +0200

    association between groupCenter <->PermissionGroup is oneToMany

    One groupCenter may have ONLY one permissionGroup

    including the migration file. During migration a script ensure that no
    data is lost in permissions.
This commit is contained in:
Julien Fastré 2015-09-20 21:38:24 +02:00
parent 7ed87b92fc
commit 841c1ca625
66 changed files with 3593 additions and 81 deletions

3
.gitignore vendored
View File

@ -29,4 +29,5 @@ Resources/node_modules/
Resources/public/sass/*
!Resources/public/sass/_custom.scss
!Resources/public/sass/_timeline.scss
!Resources/public/sass/custom/
!Resources/public/sass/custom/

View File

@ -7,6 +7,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Chill\MainBundle\DependencyInjection\SearchableServicesCompilerPass;
use Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass;
use Chill\MainBundle\DependencyInjection\TimelineCompilerClass;
use Chill\MainBundle\DependencyInjection\RoleProvidersCompilerPass;
class ChillMainBundle extends Bundle
{
@ -16,5 +17,6 @@ class ChillMainBundle extends Bundle
$container->addCompilerPass(new SearchableServicesCompilerPass());
$container->addCompilerPass(new ConfigConsistencyCompilerPass());
$container->addCompilerPass(new TimelineCompilerClass());
$container->addCompilerPass(new RoleProvidersCompilerPass);
}
}

View File

@ -37,4 +37,9 @@ class AdminController extends Controller {
return $this->render('ChillMainBundle:Admin:layout.html.twig');
}
public function indexPermissionsAction()
{
return $this->render('ChillMainBundle:Admin:layout_permissions.html.twig');
}
}

View File

@ -0,0 +1,176 @@
<?php
namespace Chill\MainBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Form\CenterType;
/**
* Center controller.
*
*/
class CenterController extends Controller
{
/**
* Lists all Center entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:Center')->findAll();
return $this->render('ChillMainBundle:Center:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new Center entity.
*
*/
public function createAction(Request $request)
{
$center = new Center();
$form = $this->createCreateForm($center);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($center);
$em->flush();
return $this->redirect($this->generateUrl('admin_center_show', array('id' => $center->getId())));
}
return $this->render('ChillMainBundle:Center:new.html.twig', array(
'entity' => $center,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a Center entity.
*
* @param Center $center The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Center $center)
{
$form = $this->createForm(new CenterType(), $center, array(
'action' => $this->generateUrl('admin_center_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Center entity.
*
*/
public function newAction()
{
$center = new Center();
$form = $this->createCreateForm($center);
return $this->render('ChillMainBundle:Center:new.html.twig', array(
'entity' => $center,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Center entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$center = $em->getRepository('ChillMainBundle:Center')->find($id);
if (!$center) {
throw $this->createNotFoundException('Unable to find Center entity.');
}
return $this->render('ChillMainBundle:Center:show.html.twig', array(
'entity' => $center
));
}
/**
* Displays a form to edit an existing Center entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$center = $em->getRepository('ChillMainBundle:Center')->find($id);
if (!$center) {
throw $this->createNotFoundException('Unable to find Center entity.');
}
$editForm = $this->createEditForm($center);
return $this->render('ChillMainBundle:Center:edit.html.twig', array(
'entity' => $center,
'edit_form' => $editForm->createView()
));
}
/**
* Creates a form to edit a Center entity.
*
* @param Center $center The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Center $center)
{
$form = $this->createForm(new CenterType(), $center, array(
'action' => $this->generateUrl('admin_center_update', array('id' => $center->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Center entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$center = $em->getRepository('ChillMainBundle:Center')->find($id);
if (!$center) {
throw $this->createNotFoundException('Unable to find Center entity.');
}
$editForm = $this->createEditForm($center);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('admin_center_edit', array('id' => $id)));
}
return $this->render('ChillMainBundle:Center:edit.html.twig', array(
'entity' => $center,
'edit_form' => $editForm->createView()
));
}
}

View File

@ -0,0 +1,447 @@
<?php
namespace Chill\MainBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chill\MainBundle\Entity\RoleScope;
use Chill\MainBundle\Entity\PermissionsGroup;
use Chill\MainBundle\Form\PermissionsGroupType;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Chill\MainBundle\Entity\Scope;
/**
* PermissionsGroup controller.
*
*/
class PermissionsGroupController extends Controller
{
/**
* Lists all PermissionsGroup entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:PermissionsGroup')->findAll();
return $this->render('ChillMainBundle:PermissionsGroup:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new PermissionsGroup entity.
*
*/
public function createAction(Request $request)
{
$permissionsGroup = new PermissionsGroup();
$form = $this->createCreateForm($permissionsGroup);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($permissionsGroup);
$em->flush();
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit',
array('id' => $permissionsGroup->getId())));
}
return $this->render('ChillMainBundle:PermissionsGroup:new.html.twig', array(
'entity' => $permissionsGroup,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a PermissionsGroup entity.
*
* @param PermissionsGroup $permissionsGroup The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(PermissionsGroup $permissionsGroup)
{
$form = $this->createForm(new PermissionsGroupType(), $permissionsGroup, array(
'action' => $this->generateUrl('admin_permissionsgroup_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new PermissionsGroup entity.
*
*/
public function newAction()
{
$permissionsGroup = new PermissionsGroup();
$form = $this->createCreateForm($permissionsGroup);
return $this->render('ChillMainBundle:PermissionsGroup:new.html.twig', array(
'entity' => $permissionsGroup,
'form' => $form->createView(),
));
}
/**
* Finds and displays a PermissionsGroup entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
$translatableStringHelper = $this->get('chill.main.helper.translatable_string');
$roleScopes = $permissionsGroup->getRoleScopes()->toArray();
usort($roleScopes,
function(RoleScope $a, RoleScope $b) use ($translatableStringHelper) {
if ($a->getScope() === NULL) {
return 1;
}
if ($b->getScope() === NULL) {
return +1;
}
return strcmp(
$translatableStringHelper->localize($a->getScope()->getName()),
$translatableStringHelper->localize($b->getScope()->getName())
);
});
return $this->render('ChillMainBundle:PermissionsGroup:show.html.twig', array(
'entity' => $permissionsGroup,
'role_scopes' => $roleScopes,
'expanded_roles' => $this->getExpandedRoles($roleScopes)
));
}
/**
* expand roleScopes to be easily shown in template
*
* @param array $roleScopes
* @return array
*/
private function getExpandedRoles(array $roleScopes)
{
$expandedRoles = array();
foreach ($roleScopes as $roleScope) {
if (!array_key_exists($roleScope->getRole(), $expandedRoles)) {
$expandedRoles[$roleScope->getRole()] =
array_map(
function(RoleInterface $role) {
return $role->getRole();
},
$this->get('security.role_hierarchy')
->getReachableRoles(
array(new Role($roleScope->getRole()))
)
);
}
}
return $expandedRoles;
}
/**
* Displays a form to edit an existing PermissionsGroup entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
$editForm = $this->createEditForm($permissionsGroup);
$deleteRoleScopesForm = array();
foreach ($permissionsGroup->getRoleScopes() as $roleScope) {
$deleteRoleScopesForm[$roleScope->getId()] = $this->createDeleteRoleScopeForm(
$permissionsGroup, $roleScope);
}
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
return $this->render('ChillMainBundle:PermissionsGroup:edit.html.twig', array(
'entity' => $permissionsGroup,
'edit_form' => $editForm->createView(),
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map( function($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView()
));
}
/**
* Creates a form to edit a PermissionsGroup entity.
*
* @param PermissionsGroup $permissionsGroup The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(PermissionsGroup $permissionsGroup)
{
$form = $this->createForm(new PermissionsGroupType(), $permissionsGroup, array(
'action' => $this->generateUrl('admin_permissionsgroup_update', array('id' => $permissionsGroup->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing PermissionsGroup entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
$editForm = $this->createEditForm($permissionsGroup);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit', array('id' => $id)));
}
$deleteRoleScopesForm = array();
foreach ($permissionsGroup->getRoleScopes() as $roleScope) {
$deleteRoleScopesForm[$roleScope->getId()] = $this->createDeleteRoleScopeForm(
$permissionsGroup, $roleScope);
}
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
return $this->render('ChillMainBundle:PermissionsGroup:edit.html.twig', array(
'entity' => $permissionsGroup,
'edit_form' => $editForm->createView(),
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map( function($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView()
));
}
/**
* get a role scope by his parameters. The role scope is persisted if it
* doesn't exists in database.
*
* @param Scope $scope
* @param string $role
* @return RoleScope
*/
protected function getPersistentRoleScopeBy($role, Scope $scope = null)
{
$em = $this->getDoctrine()->getManager();
$roleScope = $em->getRepository('ChillMainBundle:RoleScope')
->findOneBy(array('role' => $role, 'scope' => $scope));
if ($roleScope === NULL) {
$roleScope = (new RoleScope())
->setRole($role)
->setScope($scope)
;
$em->persist($roleScope);
}
return $roleScope;
}
/**
* remove an association between permissionsGroup and roleScope
*
* @param int $pgid permissionsGroup id
* @param int $rsid roleScope id
* @return redirection to edit form
*/
public function deleteLinkRoleScopeAction($pgid, $rsid)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($pgid);
$roleScope = $em->getRepository('ChillMainBundle:RoleScope')->find($rsid);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
if (!$roleScope) {
throw $this->createNotFoundException('Unable to find RoleScope entity');
}
try {
$permissionsGroup->removeRoleScope($roleScope);
} catch (\RuntimeException $ex) {
$this->addFlash('notice',
$this->get('translator')->trans("The role '%role%' and circle "
. "'%scope%' is not associated with this permission group", array(
'%role%' => $this->get('translator')->trans($roleScope->getRole()),
'%scope%' => $this->get('chill.main.helper.translatable_string')
->localize($roleScope->getScope()->getName())
)));
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit',
array('id' => $pgid)));
}
$em->flush();
$this->addFlash('notice',
$this->get('translator')->trans("The role '%role%' on circle "
. "'%scope%' has been removed", array(
'%role%' => $this->get('translator')->trans($roleScope->getRole()),
'%scope%' => $this->get('chill.main.helper.translatable_string')
->localize($roleScope->getScope()->getName())
)));
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit',
array('id' => $pgid)));
}
/**
*
* @param Request $request
* @param int $id
* @return Respon
* @throws type
*/
public function addLinkRoleScopeAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$permissionsGroup = $em->getRepository('ChillMainBundle:PermissionsGroup')->find($id);
if (!$permissionsGroup) {
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
}
$form = $this->createAddRoleScopeForm($permissionsGroup);
$form->handleRequest($request);
if ($form->isValid()) {
$roleScope = $this->getPersistentRoleScopeBy(
$form['composed_role_scope']->getData()->getRole(),
$form['composed_role_scope']->getData()->getScope()
);
$permissionsGroup->addRoleScope($roleScope);
$violations = $this->get('validator')->validate($permissionsGroup);
if ($violations->count() === 0) {
$em->flush();
$this->addFlash('notice',
$this->get('translator')->trans("The permissions have been added"));
return $this->redirect($this->generateUrl('admin_permissionsgroup_edit',
array('id' => $id)));
} else {
foreach($violations as $error) {
$this->addFlash('error', $error->getMessage());
}
}
} else {
foreach ($form->getErrors() as $error) {
$this->addFlash('error', $error->getMessage());
}
}
$editForm = $this->createEditForm($permissionsGroup);
$deleteRoleScopesForm = array();
foreach ($permissionsGroup->getRoleScopes() as $roleScope) {
$deleteRoleScopesForm[$roleScope->getId()] = $this->createDeleteRoleScopeForm(
$permissionsGroup, $roleScope);
}
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
return $this->render('ChillMainBundle:PermissionsGroup:edit.html.twig', array(
'entity' => $permissionsGroup,
'edit_form' => $editForm->createView(),
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
'delete_role_scopes_form' => array_map( function($form) {
return $form->createView();
}, $deleteRoleScopesForm),
'add_role_scopes_form' => $addRoleScopesForm->createView()
));
}
/**
* Creates a form to delete a link to roleScope.
*
* @param mixed $permissionsGroup The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteRoleScopeForm(PermissionsGroup $permissionsGroup,
RoleScope $roleScope)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('admin_permissionsgroup_delete_role_scope',
array('pgid' => $permissionsGroup->getId(), 'rsid' => $roleScope->getId())))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Delete'))
->getForm()
;
}
/**
* creates a form to add a role scope to permissionsgroup
*
* @param PermissionsGroup $permissionsGroup
* @return \Symfony\Component\Form\Form The form
*/
private function createAddRoleScopeForm(PermissionsGroup $permissionsGroup)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('admin_permissionsgroup_add_role_scope',
array('id' => $permissionsGroup->getId())))
->setMethod('PUT')
->add('composed_role_scope', 'composed_role_scope')
->add('submit', 'submit', array('label' => 'Add permission'))
->getForm()
;
}
}

View File

@ -0,0 +1,177 @@
<?php
namespace Chill\MainBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Form\ScopeType;
/**
* Scope controller.
*
*/
class ScopeController extends Controller
{
/**
* Lists all Scope entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:Scope')->findAll();
return $this->render('ChillMainBundle:Scope:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new Scope entity.
*
*/
public function createAction(Request $request)
{
$scope = new Scope();
$form = $this->createCreateForm($scope);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($scope);
$em->flush();
return $this->redirect($this->generateUrl('admin_scope_show', array('id' => $scope->getId())));
}
return $this->render('ChillMainBundle:Scope:new.html.twig', array(
'entity' => $scope,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a Scope entity.
*
* @param Scope $scope The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Scope $scope)
{
$form = $this->createForm(new ScopeType(), $scope, array(
'action' => $this->generateUrl('admin_scope_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Scope entity.
*
*/
public function newAction()
{
$scope = new Scope();
$form = $this->createCreateForm($scope);
return $this->render('ChillMainBundle:Scope:new.html.twig', array(
'entity' => $scope,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Scope entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$scope = $em->getRepository('ChillMainBundle:Scope')->find($id);
if (!$scope) {
throw $this->createNotFoundException('Unable to find Scope entity.');
}
return $this->render('ChillMainBundle:Scope:show.html.twig', array(
'entity' => $scope
));
}
/**
* Displays a form to edit an existing Scope entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$scope = $em->getRepository('ChillMainBundle:Scope')->find($id);
if (!$scope) {
throw $this->createNotFoundException('Unable to find Scope entity.');
}
$editForm = $this->createEditForm($scope);
return $this->render('ChillMainBundle:Scope:edit.html.twig', array(
'entity' => $scope,
'edit_form' => $editForm->createView(),
));
}
/**
* Creates a form to edit a Scope entity.
*
* @param Scope $scope The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Scope $scope)
{
$form = $this->createForm(new ScopeType(), $scope, array(
'action' => $this->generateUrl('admin_scope_update', array('id' => $scope->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Scope entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$scope = $em->getRepository('ChillMainBundle:Scope')->find($id);
if (!$scope) {
throw $this->createNotFoundException('Unable to find Scope entity.');
}
$editForm = $this->createEditForm($scope);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('admin_scope_edit', array('id' => $id)));
}
return $this->render('ChillMainBundle:Scope:edit.html.twig', array(
'entity' => $scope,
'edit_form' => $editForm->createView()
));
}
}

View File

@ -0,0 +1,423 @@
<?php
namespace Chill\MainBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\UserType;
use Chill\MainBundle\Entity\GroupCenter;
use Chill\MainBundle\Form\Type\ComposedGroupCenterType;
use Chill\MainBundle\Form\UserPasswordType;
/**
* User controller.
*
*/
class UserController extends Controller
{
const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter';
/**
* Lists all User entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChillMainBundle:User')->findAll();
return $this->render('ChillMainBundle:User:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new User entity.
*
*/
public function createAction(Request $request)
{
$user = new User();
$form = $this->createCreateForm($user);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$user->setPassword($this->get('security.password_encoder')
->encodePassword($user, $form['plainPassword']['password']->getData()));
$em->persist($user);
$em->flush();
return $this->redirect($this->generateUrl('admin_user_show', array('id' => $user->getId())));
}
return $this->render('ChillMainBundle:User:new.html.twig', array(
'entity' => $user,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a User entity.
*
* @param User $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(User $entity)
{
$form = $this->createForm(new UserType(), $entity, array(
'action' => $this->generateUrl('admin_user_create'),
'method' => 'POST',
'is_creation' => true
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new User entity.
*
*/
public function newAction()
{
$user = new User();
$form = $this->createCreateForm($user);
return $this->render('ChillMainBundle:User:new.html.twig', array(
'entity' => $user,
'form' => $form->createView(),
));
}
/**
* Finds and displays a User entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($id);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
return $this->render('ChillMainBundle:User:show.html.twig', array(
'entity' => $user,
));
}
/**
* Displays a form to edit an existing User entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($id);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
$editForm = $this->createEditForm($user);
return $this->render('ChillMainBundle:User:edit.html.twig', array(
'entity' => $user,
'edit_form' => $editForm->createView(),
'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($user)->createView(),
'delete_groupcenter_form' => array_map(
function(\Symfony\Component\Form\Form $form) {
return $form->createView();
},
iterator_to_array($this->getDeleteLinkGroupCenterByUser($user), true))
));
}
/**
* Displays a form to edit the user password.
*
*/
public function editPasswordAction($id)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($id);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
$editForm = $this->createEditPasswordForm($user);
return $this->render('ChillMainBundle:User:edit_password.html.twig', array(
'entity' => $user,
'edit_form' => $editForm->createView()
));
}
/**
*
*
* @param User $user
* @return \Symfony\Component\Form\Form
*/
private function createEditPasswordForm(User $user)
{
return $this->createForm(new UserPasswordType(), $user, array(
'action' =>
$this->generateUrl('admin_user_update_password', array('id' => $user->getId())),
'method' => 'PUT'
))
->add('submit', 'submit', array('label' => 'Change password'))
;
}
public function deleteLinkGroupCenterAction($uid, $gcid)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($uid);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
$groupCenter = $em->getRepository('ChillMainBundle:GroupCenter')
->find($gcid);
if (!$groupCenter) {
throw $this->createNotFoundException('Unable to find groupCenter entity');
}
try {
$user->removeGroupCenter($groupCenter);
} catch (\RuntimeException $ex) {
$this->addFlash('error', $this->get('translator')->trans($ex-getMessage()));
return $this->redirect($this->generateUrl('admin_user_edit', array('id' => $uid)));
}
$em->flush();
$this->addFlash('success', $this->get('translator')
->trans('The permissions where removed.'));
return $this->redirect($this->generateUrl('admin_user_edit', array('id' => $uid)));
}
public function addLinkGroupCenterAction(Request $request, $uid)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($uid);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
$form = $this->createAddLinkGroupCenterForm($user);
$form->handleRequest($request);
if ($form->isValid()) {
$groupCenter = $this->getPersistedGroupCenter(
$form[self::FORM_GROUP_CENTER_COMPOSED]->getData());
$user->addGroupCenter($groupCenter);
if ($this->get('validator')->validate($user)->count() === 0) {
$em->flush();
$this->addFlash('success', $this->get('translator')->trans('The '
. 'permissions have been successfully added to the user'));
return $this->redirect($this->generateUrl('admin_user_edit',
array('id' => $uid)));
} else {
foreach($this->get('validator')->validate($user) as $error)
$this->addFlash('error', $error->getMessage());
}
}
return $this->render('ChillMainBundle:User:edit.html.twig', array(
'entity' => $user,
'edit_form' => $this->createEditForm($user)->createView(),
'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($user)->createView(),
'delete_groupcenter_form' => array_map(
function(\Symfony\Component\Form\Form $form) {
return $form->createView();
},
iterator_to_array($this->getDeleteLinkGroupCenterByUser($user), true))
));
}
private function getPersistedGroupCenter(GroupCenter $groupCenter)
{
$em = $this->getDoctrine()->getManager();
$groupCenterManaged = $em->getRepository('ChillMainBundle:GroupCenter')
->findOneBy(array(
'center' => $groupCenter->getCenter(),
'permissionsGroup' => $groupCenter->getPermissionsGroup()
));
if (!$groupCenterManaged) {
$em->persist($groupCenter);
return $groupCenter;
}
return $groupCenterManaged;
}
/**
* Creates a form to edit a User entity.
*
* @param User $user The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(User $user)
{
$form = $this->createForm(new UserType(), $user, array(
'action' => $this->generateUrl('admin_user_update', array('id' => $user->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing User entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($id);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
$editForm = $this->createEditForm($user);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('admin_user_edit', array('id' => $id)));
}
return $this->render('ChillMainBundle:User:edit.html.twig', array(
'entity' => $user,
'edit_form' => $editForm->createView(),
'add_groupcenter_form' => $this->createAddLinkGroupCenterForm($user)->createView(),
'delete_groupcenter_form' => array_map(
function(\Symfony\Component\Form\Form $form) {
return $form->createView();
},
iterator_to_array($this->getDeleteLinkGroupCenterByUser($user), true))
));
}
/**
* Edits the user password
*
*/
public function updatePasswordAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('ChillMainBundle:User')->find($id);
if (!$user) {
throw $this->createNotFoundException('Unable to find User entity.');
}
$editForm = $this->createEditPasswordForm($user);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$password = $editForm->getData();
$user->setPassword($this->get('security.password_encoder')
->encodePassword($user, $password));
$em->flush();
$this->addFlash('success', $this->get('translator')->trans('Password successfully updated!'));
return $this->redirect($this->generateUrl('admin_user_edit', array('id' => $id)));
}
return $this->render('ChillMainBundle:User:edit_password.html.twig', array(
'entity' => $user,
'edit_form' => $editForm->createView(),
));
}
/**
* Creates a form to delete a link to a GroupCenter
*
* @param mixed $permissionsGroup The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteLinkGroupCenterForm(User $user, GroupCenter $groupCenter)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('admin_user_delete_group_center',
array('uid' => $user->getId(), 'gcid' => $groupCenter->getId())))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Delete'))
->getForm()
;
}
/**
* create a form to add a link to a groupcenter
*
* @param User $user
* @return \Symfony\Component\Form\Form
*/
private function createAddLinkGroupCenterForm(User $user)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('admin_user_add_group_center',
array('uid' => $user->getId())))
->setMethod('POST')
->add(self::FORM_GROUP_CENTER_COMPOSED, new ComposedGroupCenterType())
->add('submit', 'submit', array('label' => 'Add a new groupCenter'))
->getForm()
;
}
/**
*
* @param User $user
*/
private function getDeleteLinkGroupCenterByUser(User $user)
{
foreach ($user->getGroupCenters() as $groupCenter) {
yield $groupCenter->getId() => $this
->createDeleteLinkGroupCenterForm($user, $groupCenter);
}
}
}

View File

@ -47,7 +47,7 @@ class LoadGroupCenters extends AbstractFixture implements OrderedFixtureInterfac
foreach (LoadPermissionsGroup::$refs as $permissionGroupRef) {
$GroupCenter = new GroupCenter();
$GroupCenter->setCenter($this->getReference($centerRef));
$GroupCenter->addPermissionGroup($this->getReference($permissionGroupRef));
$GroupCenter->setPermissionsGroup($this->getReference($permissionGroupRef));
$manager->persist($GroupCenter);

View File

@ -36,6 +36,7 @@ class Configuration implements ConfigurationInterface
->prototype('scalar')->end()
->end()
->end()
->end()
->end();
return $treeBuilder;

View 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\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class RoleProvidersCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('chill.main.role_provider')) {
throw new \LogicException('service chill.main.role_provider '
. 'is not defined. It is required by RoleProviderCompilerPass');
}
$definition = $container->getDefinition(
'chill.main.role_provider'
);
$taggedServices = $container->findTaggedServiceIds(
'chill.role'
);
foreach ($taggedServices as $id => $tagAttributes) {
$definition->addMethodCall(
'addProvider',
array(new Reference($id))
);
}
}
}

View File

@ -52,9 +52,9 @@ class GroupCenter
/**
*
* @var Collection
* @var PermissionsGroup
*/
private $permissionGroups;
private $permissionsGroup;
public function __construct()
{
@ -76,15 +76,6 @@ class GroupCenter
return $this->center;
}
/**
*
* @return PermissionGroup[]
*/
public function getPermissionGroups()
{
return $this->permissionGroups;
}
/**
*
* @param Center $center
@ -95,22 +86,32 @@ class GroupCenter
$this->center = $center;
return $this;
}
/**
*
* @param PermissionGroup $permission
* @return \Chill\MainBundle\Entity\GroupCenter
*/
public function addPermissionGroup(PermissionsGroup $permission)
{
$this->permissionGroups->add($permission);
return $this;
}
public function getUsers()
{
return $this->users;
}
/**
*
* @return PermissionGroup
*/
public function getPermissionsGroup()
{
return $this->permissionsGroup;
}
/**
*
* @param \Chill\MainBundle\Entity\PermissionsGroup $permissionGroup
* @return \Chill\MainBundle\Entity\GroupCenter
*/
public function setPermissionsGroup(PermissionsGroup $permissionsGroup)
{
$this->permissionsGroup = $permissionsGroup;
return $this;
}

View File

@ -21,7 +21,7 @@
namespace Chill\MainBundle\Entity;
use Chill\MainBundle\Entity\RoleScope;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
@ -79,10 +79,50 @@ class PermissionsGroup
return $this;
}
/**
*
* @param RoleScope $roleScope
*/
public function addRoleScope(RoleScope $roleScope)
{
$this->roleScopes->add($roleScope);
}
/**
*
* @param RoleScope $roleScope
* @throws \RuntimeException if the roleScope could not be removed.
*/
public function removeRoleScope(RoleScope $roleScope)
{
$result = $this->roleScopes->removeElement($roleScope);
if ($result === FALSE) {
throw new \RuntimeException(sprintf("The roleScope '%s' could not be removed, "
. "aborting.", spl_object_hash($roleScope)));
}
}
/**
* Test that a role scope is associated only once with the permission group
*
* @param ExecutionContextInterface $context
*/
public function isRoleScopePresentOnce(ExecutionContextInterface $context)
{
$roleScopesId = array_map(function(RoleScope $roleScope) {
return $roleScope->getId();
},
$this->getRoleScopes()->toArray());
$countedIds = array_count_values($roleScopesId);
foreach ($countedIds as $id => $nb) {
if ($nb > 1) {
$context->buildViolation("A permission is already present "
. "for the same role and scope")
->addViolation();
}
}
}
}

View File

@ -45,6 +45,10 @@ class RoleScope
*/
private $scope;
public function __construct() {
$this->new = true;
}
public function getId()
{
return $this->id;
@ -76,6 +80,7 @@ class RoleScope
public function setRole($role)
{
$this->role = $role;
return $this;
}
@ -84,11 +89,10 @@ class RoleScope
* @param \Chill\MainBundle\Entity\Scope $scope
* @return \Chill\MainBundle\Entity\RoleScope
*/
public function setScope(Scope $scope)
public function setScope(Scope $scope = null)
{
$this->scope = $scope;
return $this;
}
}

View File

@ -5,6 +5,7 @@ namespace Chill\MainBundle\Entity;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
/**
* User
@ -165,6 +166,15 @@ class User implements AdvancedUserInterface {
return $this->enabled;
}
/**
*
* @param bool $enabled
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
}
/**
*
* @return GroupCenter[]
@ -184,5 +194,37 @@ class User implements AdvancedUserInterface {
$this->groupCenters->add($groupCenter);
return $this;
}
/**
*
* @param \Chill\MainBundle\Entity\GroupCenter $groupCenter
* @throws \RuntimeException if the groupCenter is not in the collection
*/
public function removeGroupCenter(GroupCenter $groupCenter)
{
if ($this->groupCenters->removeElement($groupCenter) === FALSE) {
throw new \RuntimeException(sprintf("The groupCenter could not be removed, "
. "it seems not to be associated with the user. Aborting."));
}
}
/**
* This function check that groupCenter are present only once. The validator
* use this function to avoid a user to be associated to the same groupCenter
* more than once.
*/
public function isGroupCenterPresentOnce(ExecutionContextInterface $context)
{
$groupCentersIds = array();
foreach ($this->getGroupCenters() as $groupCenter) {
if (in_array($groupCenter->getId(), $groupCentersIds)) {
$context->buildViolation("The user has already those permissions")
->addViolation();
} else {
$groupCentersIds[] = $groupCenter->getId();
}
}
}
}

39
Form/CenterType.php Normal file
View File

@ -0,0 +1,39 @@
<?php
namespace Chill\MainBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CenterType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\MainBundle\Entity\Center'
));
}
/**
* @return string
*/
public function getName()
{
return 'chill_mainbundle_center';
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Chill\MainBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class PermissionsGroupType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\MainBundle\Entity\PermissionsGroup'
));
}
/**
* @return string
*/
public function getName()
{
return 'chill_mainbundle_permissionsgroup';
}
}

39
Form/ScopeType.php Normal file
View File

@ -0,0 +1,39 @@
<?php
namespace Chill\MainBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ScopeType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'translatable_string')
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\MainBundle\Entity\Scope'
));
}
/**
* @return string
*/
public function getName()
{
return 'chill_mainbundle_scope';
}
}

View File

@ -0,0 +1,62 @@
<?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\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\MainBundle\Entity\PermissionsGroup;
use Chill\MainBundle\Entity\Center;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ComposedGroupCenterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('permissionsgroup', 'entity', array(
'class' => 'Chill\MainBundle\Entity\PermissionsGroup',
'choice_label' => function(PermissionsGroup $group) {
return $group->getName();
}
))->add('center', 'entity', array(
'class' => 'Chill\MainBundle\Entity\Center',
'choice_label' => function(Center $center) {
return $center->getName();
}
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('data_class', 'Chill\MainBundle\Entity\GroupCenter');
}
public function getName()
{
return 'composed_groupcenter';
}
}

View File

@ -0,0 +1,112 @@
<?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\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Security\RoleProvider;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
/**
* Form to Edit/create a role scope. If the role scope does not
* exists in the database, he is generated.
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/
class ComposedRoleScopeType extends AbstractType
{
/**
*
* @var string[]
*/
private $roles = array();
/**
*
* @var string[]
*/
private $rolesWithoutScope = array();
/**
*
* @var TranslatableStringHelper
*/
private $translatableStringHelper;
public function __construct(TranslatableStringHelper $translatableStringHelper,
RoleProvider $roleProvider)
{
$this->roles = $roleProvider->getRoles();
$this->rolesWithoutScope = $roleProvider->getRolesWithoutScopes();
$this->translatableStringHelper = $translatableStringHelper;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
// store values used in internal function
$translatableStringHelper = $this->translatableStringHelper;
$rolesWithoutScopes = $this->rolesWithoutScope;
//build roles
$values = array();
foreach ($this->roles as $role) {
$values[$role] = $role;
}
$builder
->add('role', 'choice', array(
'choices' => $values,
'placeholder' => 'Choose amongst roles',
'choice_attr' => function($role) use ($rolesWithoutScopes) {
if (in_array($role, $rolesWithoutScopes)) {
return array('data-has-scope' => '0');
} else {
return array('data-has-scope' => '1');
}
}
))
->add('scope', 'entity', array(
'class' => 'ChillMainBundle:Scope',
'choice_label' => function(Scope $scope) use ($translatableStringHelper) {
return $translatableStringHelper->localize($scope->getName());
},
'required' => false,
'data' => null
));
}
public function getName()
{
return 'composed_role_scope';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('data_class', 'Chill\MainBundle\Entity\RoleScope');
}
}

66
Form/UserPasswordType.php Normal file
View File

@ -0,0 +1,66 @@
<?php
namespace Chill\MainBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Regex;
class UserPasswordType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('password', 'repeated', array(
'type' => 'password',
'required' => false,
'options' => array(),
'first_options' => array(
'label' => 'Password'
),
'second_options' => array(
'label' => 'Repeat the password'
),
'invalid_message' => "The password fields must match",
'constraints' => array(
new Length(array(
'min' => 9,
'minMessage' => 'The password must be greater than {{ limit }} characters'
)),
new NotBlank(),
new Regex(array(
'pattern' => "/((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%!,;:+\"'-\/{}~=µ\(\)£]).{6,})/",
'message' => "The password must contains one letter, one "
. "capitalized letter, one number and one special character "
. "as *[@#$%!,;:+\"'-/{}~=µ()£]). Other characters are allowed."
))
)
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_classds' => 'Chill\MainBundle\Entity\User'
));
}
/**
* @return string
*/
public function getName()
{
return 'chill_mainbundle_user_password';
}
}

62
Form/UserType.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace Chill\MainBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Chill\MainBundle\Form\UserPasswordType;
class UserType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
;
if ($options['is_creation']) {
$builder->add('plainPassword', new UserPasswordType(), array(
'mapped' => false
));
} else {
$builder->add($builder
->create('enabled', 'choice', array(
'choices' => array(
0 => 'Disabled, the user is not allowed to login',
1 => 'Enabled, the user is active'
),
'expanded' => false,
'multiple' => false
))
);
}
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chill\MainBundle\Entity\User'
));
$resolver
->setDefaults(array('is_creation' => false))
->addAllowedValues(array('is_creation' => array(true, false)))
;
}
/**
* @return string
*/
public function getName()
{
return 'chill_mainbundle_user';
}
}

View File

@ -11,6 +11,5 @@ Chill\MainBundle\Entity\GroupCenter:
center:
targetEntity: Chill\MainBundle\Entity\Center
inversedBy: groupCenters
manyToMany:
permissionGroups:
permissionsGroup:
targetEntity: Chill\MainBundle\Entity\PermissionsGroup

View File

@ -14,4 +14,5 @@ Chill\MainBundle\Entity\RoleScope:
manyToOne:
scope:
targetEntity: Chill\MainBundle\Entity\Scope
inversedBy: roleScopes
inversedBy: roleScopes
nullable: true

View File

@ -1,3 +1,19 @@
chill_main_admin_permissionsgroup:
resource: "@ChillMainBundle/Resources/config/routing/permissionsgroup.yml"
prefix: "{_locale}/admin/permissionsgroup"
chill_main_admin_user:
resource: "@ChillMainBundle/Resources/config/routing/user.yml"
prefix: "{_locale}/admin/user"
chill_main_admin_scope:
resource: "@ChillMainBundle/Resources/config/routing/scope.yml"
prefix: "{_locale}/admin/scope"
chill_main_admin:
resource: "@ChillMainBundle/Resources/config/routing/center.yml"
prefix: "{_locale}/admin/center"
root:
path: /
defaults:
@ -38,6 +54,18 @@ chill_main_admin_central:
order: 30
label: Admin Menu
icons: [gears]
admin_permissions:
order: 0
label: Main admin menu
chill_main_admin_permissions:
path: /{_locale}/admin/permissions
defaults: {_controller: ChillMainBundle:Admin:indexPermissions }
options:
menus:
admin:
order: 200
label: Permissions
chill_main_search:
path: /{_locale}/search

View File

@ -0,0 +1,35 @@
admin_center:
path: /
defaults: { _controller: "ChillMainBundle:Center:index" }
options:
menus:
admin_rpermissions:
order: 100
label: List centers
admin_center_show:
path: /{id}/show
defaults: { _controller: "ChillMainBundle:Center:show" }
admin_center_new:
path: /new
defaults: { _controller: "ChillMainBundle:Center:new" }
options:
menus:
admin_permissions:
order: 101
label: New center
admin_center_create:
path: /create
defaults: { _controller: "ChillMainBundle:Center:create" }
methods: POST
admin_center_edit:
path: /{id}/edit
defaults: { _controller: "ChillMainBundle:Center:edit" }
admin_center_update:
path: /{id}/update
defaults: { _controller: "ChillMainBundle:Center:update" }
methods: [POST, PUT]

View File

@ -0,0 +1,45 @@
admin_permissionsgroup:
path: /
defaults: { _controller: "ChillMainBundle:PermissionsGroup:index" }
options:
menus:
admin_permissions:
order: 300
label: Permissions group list
admin_permissionsgroup_show:
path: /{id}/show
defaults: { _controller: "ChillMainBundle:PermissionsGroup:show" }
admin_permissionsgroup_new:
path: /new
defaults: { _controller: "ChillMainBundle:PermissionsGroup:new" }
options:
menus:
admin_permissions:
order: 301
label: New permission group
admin_permissionsgroup_create:
path: /create
defaults: { _controller: "ChillMainBundle:PermissionsGroup:create" }
methods: POST
admin_permissionsgroup_edit:
path: /{id}/edit
defaults: { _controller: "ChillMainBundle:PermissionsGroup:edit" }
admin_permissionsgroup_update:
path: /{id}/update
defaults: { _controller: "ChillMainBundle:PermissionsGroup:update" }
methods: [POST, PUT]
admin_permissionsgroup_delete_role_scope:
path: /{pgid}/delete_link_role_scope/{rsid}
defaults: { _controller: "ChillMainBundle:PermissionsGroup:deleteLinkRoleScope" }
methods: [DELETE]
admin_permissionsgroup_add_role_scope:
path: /{id}/add_link_role_scope
defaults: { _controller: "ChillMainBundle:PermissionsGroup:addLinkRoleScope" }
methods: [PUT]

View File

@ -0,0 +1,35 @@
admin_scope:
path: /
defaults: { _controller: "ChillMainBundle:Scope:index" }
options:
menus:
admin_permissions:
order: 200
label: List circles
admin_scope_show:
path: /{id}/show
defaults: { _controller: "ChillMainBundle:Scope:show" }
admin_scope_new:
path: /new
defaults: { _controller: "ChillMainBundle:Scope:new" }
options:
menus:
admin_permissions:
order: 201
label: New circle
admin_scope_create:
path: /create
defaults: { _controller: "ChillMainBundle:Scope:create" }
methods: POST
admin_scope_edit:
path: /{id}/edit
defaults: { _controller: "ChillMainBundle:Scope:edit" }
admin_scope_update:
path: /{id}/update
defaults: { _controller: "ChillMainBundle:Scope:update" }
methods: [POST, PUT]

View File

@ -0,0 +1,54 @@
admin_user:
path: /
defaults: { _controller: "ChillMainBundle:User:index" }
options:
menus:
admin_permissions:
order: 400
label: List users
admin_user_show:
path: /{id}/show
defaults: { _controller: "ChillMainBundle:User:show" }
admin_user_new:
path: /new
defaults: { _controller: "ChillMainBundle:User:new" }
options:
menus:
admin_permissions:
order: 401
label: Add a new user
admin_user_create:
path: /create
defaults: { _controller: "ChillMainBundle:User:create" }
methods: POST
admin_user_edit:
path: /{id}/edit
defaults: { _controller: "ChillMainBundle:User:edit" }
admin_user_edit_password:
path: /{id}/edit_password
defaults: { _controller: "ChillMainBundle:User:editPassword" }
admin_user_update:
path: /{id}/update
defaults: { _controller: "ChillMainBundle:User:update" }
methods: [POST, PUT]
admin_user_update_password:
path: /{id}/update_password
defaults: { _controller: "ChillMainBundle:User:updatePassword" }
methods: [POST, PUT]
admin_user_delete_group_center:
path: /{uid}/delete_link_groupcenter/{gcid}
defaults: { _controller: "ChillMainBundle:User:deleteLinkGroupCenter" }
methods: [DELETE]
admin_user_add_group_center:
path: /{uid}/add_link_groupcenter
defaults: { _controller: "ChillMainBundle:User:addLinkGroupCenter" }
methods: [POST]

View File

@ -107,3 +107,23 @@ services:
class: Chill\MainBundle\Security\Authorization\AuthorizationHelper
arguments:
- "@security.role_hierarchy"
chill.main.role_provider:
class: Chill\MainBundle\Security\RoleProvider
chill.main.form.type.composed_role_scope:
class: Chill\MainBundle\Form\Type\ComposedRoleScopeType
arguments:
- "@chill.main.helper.translatable_string"
- "@chill.main.role_provider"
tags:
- { name: form.type, alias: composed_role_scope }
chill.main.validator.role_scope_scope_presence:
class: Chill\MainBundle\Validation\Validator\RoleScopeScopePresence
arguments:
- "@chill.main.role_provider"
- "@logger"
- "@translator"
tags:
- { name: validator.constraint_validator, alias: 'role_scope_scope_presence' }

View File

@ -0,0 +1,31 @@
Chill\MainBundle\Entity\PermissionsGroup:
properties:
name:
- NotBlank: ~
- Length:
max: 50
roleScopes:
- Valid: ~
constraints:
- Callback: [isRoleScopePresentOnce]
Chill\MainBundle\Entity\User:
properties:
username:
- Length:
max: 70
min: 3
constraints:
- Callback: [isGroupCenterPresentOnce]
Chill\MainBundle\Entity\RoleScope:
constraints:
- \Chill\MainBundle\Validation\Constraint\RoleScopeScopePresenceConstraint: ~
Chill\MainBundle\Entity\Center:
properties:
name:
- NotBlank: ~
- Length:
max: 50
min: 3

View File

@ -0,0 +1,133 @@
<?php
namespace Application\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
/**
* Migrate association from
* ManyToMany between PermissionGroup <-> GroupCenter
* to
* ManyToOne : a GroupCenter can have only one PermissionGroup
*
* @link https://redmine.champs-libres.coop/issues/578 The issue describing the move
*/
class Version20150821105642 extends AbstractMigration implements
\Symfony\Component\DependencyInjection\ContainerAwareInterface
{
/**
*
* @var ContainerInterface
*/
private $container;
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE group_centers ADD permissionsGroup_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE group_centers ADD CONSTRAINT FK_A14D8F3D447BBB3B FOREIGN KEY (permissionsGroup_id) REFERENCES permission_groups (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_A14D8F3D447BBB3B ON group_centers (permissionsGroup_id)');
}
public function postUp(Schema $schema)
{
//transform data from groupcenter_permissionsgroup table
$em = $this->container->get('doctrine.orm.entity_manager');
//get all existing associations
$rsm = new ResultSetMapping();
$rsm->addScalarResult('groupcenter_id', 'groupcenter_id');
$rsm->addScalarResult('permissionsgroup_id', 'permissionsgroup_id');
$groupPermissionsAssociations = $em->createNativeQuery(
"SELECT groupcenter_id, permissionsgroup_id "
. "FROM groupcenter_permissionsgroup",
$rsm
)
->getScalarResult();
//update
foreach ($groupPermissionsAssociations as $groupPermissionAssociation) {
//get the corresponding groupCenter
$rsmGroupCenter = new ResultSetMapping();
$rsmGroupCenter->addScalarResult('id', 'id');
$rsmGroupCenter->addScalarResult('permissionsGroup_id', 'permissionsGroup_id');
$rsmGroupCenter->addScalarResult('center_id', 'center_id');
$groupCenters = $em->createNativeQuery("SELECT id, permissionsGroup_id, center_id "
. "FROM group_centers "
. "WHERE id = :groupcenter_id AND permissionsGroup_id IS NULL",
$rsmGroupCenter)
->setParameter('groupcenter_id', $groupPermissionAssociation['groupcenter_id'])
->getResult();
if (count($groupCenters) === 1) {
// we have to update this group with the current association
$em->getConnection()->executeUpdate("UPDATE group_centers "
. "SET permissionsGroup_id = ? "
. "WHERE id = ?", array(
$groupPermissionAssociation['permissionsgroup_id'],
$groupPermissionAssociation['groupcenter_id'])
);
} elseif (count($groupCenters) === 0) {
// the association was multiple. We have to create a new group_center
$rsmNewId = new ResultSetMapping();
$rsmNewId->addScalarResult('new_id', 'new_id');
$newId = $em->createNativeQuery("select nextval('group_centers_id_seq') as new_id",
$rsmNewId)
->getSingleScalarResult();
$em->getConnection()->insert("group_centers", array(
'id' => $newId,
'center_id' => $group_center['center_id'],
'permissionsGroup_id' => $groupPermissionAssociation['permissionsgroup_id']
));
// we have to link existing users to new created groupcenter
$em->getConnection()->executeQuery('INSERT INTO user_groupcenter '
. '(user_id, groupcenter_id) SELECT user_id, '.$newId.' '
. 'FROM user_groupcenter WHERE groupcenter_id = '
.$groupPermissionAssociation['groupcenter_id']);
} else {
throw new \RuntimeException("Error in the data : we should not have two groupCenter "
. "with the same id !");
}
}
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE group_centers DROP CONSTRAINT FK_A14D8F3D447BBB3B');
$this->addSql('DROP INDEX IDX_A14D8F3D447BBB3B');
$this->addSql('ALTER TABLE group_centers DROP permissionGroup_id');
}
public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container = null)
{
if ($container === NULL) {
throw new \RuntimeException('Container is not provided. This migration '
. 'need container to set a default center');
}
$this->container = $container;
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Application\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* drop table groupcenter_permissionsgroup, not necessary after
* 20150821105642
*/
class Version20150821122935 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
$this->addSql('DROP TABLE groupcenter_permissionsgroup');
$this->addSql('ALTER TABLE group_centers ALTER permissionsGroup_id SET NOT NULL');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
$this->addSql('ALTER TABLE group_centers ALTER permissionsGroup_id SET DEFAULT NULL');
$this->addSql('CREATE TABLE groupcenter_permissionsgroup (groupcenter_id INT NOT NULL, permissionsgroup_id INT NOT NULL, PRIMARY KEY(groupcenter_id, permissionsgroup_id))');
$this->addSql('CREATE INDEX idx_55dfec607ec2fa68 ON groupcenter_permissionsgroup (groupcenter_id)');
$this->addSql('CREATE INDEX idx_55dfec606fa97d46 ON groupcenter_permissionsgroup (permissionsgroup_id)');
$this->addSql('ALTER TABLE groupcenter_permissionsgroup ADD CONSTRAINT fk_55dfec607ec2fa68 FOREIGN KEY (groupcenter_id) REFERENCES group_centers (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE groupcenter_permissionsgroup ADD CONSTRAINT fk_55dfec606fa97d46 FOREIGN KEY (permissionsgroup_id) REFERENCES permission_groups (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
}
}

View File

@ -6,9 +6,17 @@ Logout: Se déconnecter
Bad credentials: Le mot de passe et le nom d'utilisateur ne correspondent pas
Invalid CSRF token.: Votre session a expirée ou est devenue invalide.
Username: Nom d'utilisateur
username: nom d'utilisateur
Password: Mot de passe
Welcome to %installation_name%: Bienvenue à %installation_name%
Login to %installation_name%: Connexion à %installation_name%
Enabled: activé
Id: identifiant
Homepage: Accueil
Welcome: Bienvenue
Export Menu: Export
Admin Menu: Menu d'administration
Details: Détails
#serach
Your search is empty. Please provide search terms.: La recherche est vide. Merci de fournir des termes de recherche.
@ -16,4 +24,63 @@ The domain %domain% is unknow. Please check your search.: Le domaine de recherch
Invalid terms : Recherche invalide
You should not have more than one domain. : Vous ne devriez pas avoir plus d'un domaine de recherche.
#used for page title
Search %pattern%: Recherche de "%pattern%"
Search %pattern%: Recherche de "%pattern%"
#admin
Create: Créer
show: voir
edit: modifier
Main admin menu: Menu d'administration principal
Actions: Actions
#permissions
Permissions Menu: Gestion des droits
Permissions management of your chill installation: Gestion des permissions de votre instance
#admin section for center's administration
Create a new center: Créer un nouveau centre
Center list: Liste des centres
Center edit: Édition d'un centre
Center creation: Création d'un centre
New center: Nouveau centre
Center: Centre
#admin section for permissions group
Permissions group list: Liste des groupes de permissions
Create a new permissions group: Créer un nouveau groupe de permissions
Permission group "%name%": Groupe de permissions "%name%"
Grant those permissions: Attribue ces permissions
Which implies: Ce qui implique
Permission group: Groupe de permissions
Permissionsgroup: Group de permissions
New permission group: Nouveau groupe de permissions
PermissionsGroup "%name%" edit: Modification du groupe de permission '%name%'
Grant new permissions: Attribuer de nouvelles permissions
Role: Rôle
Choose amongst roles: Choisir parmi les rôles
Add permission: Ajouter les permissions
This group does not provide any permission: Ce groupe n'attribue aucune permission
#admin section for users
List users: Liste des utilisateurs
user list: liste des utilisateurs
User edit: Modification d'un utilisateur
User'status: Statut de l'utilisateur
Disabled, the user is not allowed to login: Désactivé, l'utilisateur n'est pas autorisé à se connecter
Enabled, the user is active: Actif, l'utilisateur peut se connecter
Edit password: Modifier le mot de passe
Permissions granted: Permissions accordées
Grant new permissions: Ajout de permissions
Add a new groupCenter: Ajout de permissions
Center & groups: Centre et groupes
User %username%: Utilisateur %username%
Add a new user: Ajouter un nouvel utilisateur
The permissions have been added: Les permissions ont été ajoutées
#admin section for circles (old: scopes)
List circles: Liste des cercles
New circle: Nouveau cercle
Circle: Cercle
Circle edit: Modification du cercle
Circle creation: Création d'un cercle
Create a new circle: Créer un nouveau cercle

View File

@ -0,0 +1,4 @@
# role_scope constraint
# scope presence
The role "%role%" require to be associated with a scope.: Le rôle "%role%" doit être associé à un cercle.
The role "%role%" should not be associated with a scope.: Le rôle "%role%" ne doit pas être associé à un cercle.

View File

@ -0,0 +1,31 @@
{#
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
<info@champs-libres.coop> / <http://www.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/>.
#}
{% extends "ChillMainBundle::layoutWithVerticalMenu.html.twig" %}
{% block vertical_menu_content %}
{{ chill_menu('admin_permissions', {
'layout': 'ChillMainBundle::Menu/admin_permissions.html.twig',
}) }}
{% endblock %}
{% block layout_wvm_content %}
{% block admin_content %}<!-- block personcontent empty -->
<h1>{{ 'Permissions management of your chill installation' |trans }}</h1>
{% endblock %}
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Center edit'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Center edit'|trans }}</h1>
{{ form_start(edit_form) }}
{{ form_row(edit_form.name) }}
{{ form_row(edit_form.submit, { 'attr' : { 'class' : 'sc-button green' } } ) }}
{{ form_end(edit_form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_center') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,41 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Center list'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Center list'|trans }}</h1>
<table class="records_list">
<thead>
<tr>
<th>{{ 'Name'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td><a href="{{ path('admin_center_show', { 'id': entity.id }) }}">{{ entity.name }}</a></td>
<td>
<ul>
<li>
<a href="{{ path('admin_center_show', { 'id': entity.id }) }}">{{ 'show'|trans }}</a>
</li>
<li>
<a href="{{ path('admin_center_edit', { 'id': entity.id }) }}">{{ 'edit'|trans }}</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a href="{{ path('admin_center_new') }}">
{{ 'Create a new center'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Center creation'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Center creation'|trans }}</h1>
{{ form_start(form) }}
{{ form_row(form.name) }}
{{ form_row(form.submit, { 'attr' : { 'class' : 'sc-button green' } } ) }}
{{ form_end(form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_center') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,29 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Centre %name%'|trans({ '%name%': entity.name }) }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Centre %name%'|trans({ '%name%': entity.name }) }}</h1>
<table class="record_properties">
<tbody>
<tr>
<th>{{ 'Name'|trans }}</th>
<td>{{ entity.name }}</td>
</tr>
</tbody>
</table>
<ul class="record_actions">
<li>
<a href="{{ path('admin_center') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
<li>
<a href="{{ path('admin_center_edit', { 'id': entity.id }) }}">
{{ 'Edit'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,20 @@
{#
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
<info@champs-libres.coop> / <http://www.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/>.
#}
{% extends "ChillMainBundle::Menu/verticalMenu.html.twig" %}
{% block v_menu_title %}{{ 'Permissions Menu'|trans }}{% endblock %}

View File

@ -0,0 +1,78 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'PermissionsGroup "%name%" edit'|trans( { '%name%': entity.name } ) }}</h1>
<h2>{{ 'Details'|trans }}</h2>
{{ form_start(edit_form) }}
{{ form_row(edit_form.name) }}
{{ form_row(edit_form.submit, { 'attr': { 'class': 'sc-button green' } } ) }}
{{ form_end(edit_form) }}
<h2>{{ 'Grant those permissions'|trans }} :</h2>
{%- if entity.getRoleScopes|length > 0 -%}
<table class="striped rounded">
<thead>
<tr>
<th>{{ 'Role'|trans }}</th>
<th>{{ 'Circle'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for role_scope in entity.getRoleScopes %}
<tr>
<td>
<span class="role_scope role">{{ role_scope.role|trans }}</span>
{% if expanded_roles[role_scope.role]|length > 1 %}
<br/>
<small>{{ 'Which implies'|trans }}&nbsp;: {% for role in expanded_roles[role_scope.role] %}{{ role }}{% if not loop.last %}, {% endif %}{% endfor %}</small>
{% endif %}
</td>
<td>
{%- if role_scope.scope is not null -%}
<span class="role_scope scope">
{{ role_scope.scope.name|localize_translatable_string }}
</span>
{%- else -%}
<em>N/A</em>
{%- endif -%}
</td>
<td>
{{ form_start(delete_role_scopes_form[role_scope.id]) }}
{{ form_widget(delete_role_scopes_form[role_scope.id].submit, { 'attr': { 'class': 'sc-button red' } } ) }}
{{ form_end(delete_role_scopes_form[role_scope.id]) }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{%- else -%}
<p>{{ 'This group does not provide any permission'|trans }}</p>
{%- endif -%}
<h2>{{ 'Grant new permissions'|trans }}</h2>
{{ form_start(add_role_scopes_form) }}
{{ form_errors(add_role_scopes_form) }}
{{ form_row(add_role_scopes_form.composed_role_scope.role) }}
{{ form_row(add_role_scopes_form.composed_role_scope.scope) }}
{{ form_row(add_role_scopes_form.submit, { 'attr' : { 'class': 'sc-button green' } } ) }}
{{ form_end(add_role_scopes_form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_permissionsgroup') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,41 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Permissions group list'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Permissions group list'|trans }}</h1>
<table class="records_list">
<thead>
<tr>
<th>{{ 'Name'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td><a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}">{{ entity.name }}</a></td>
<td>
<ul>
<li>
<a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}">{{ 'show'|trans }}</a>
</li>
<li>
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}">{{ 'edit'|trans }}</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a href="{{ path('admin_permissionsgroup_new') }}">
{{ 'Create a new permissions group'| trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'New permission group'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'New permission group'|trans }}</h1>
{{ form_start(form) }}
{{ form_row(form.name) }}
{{ form_row(form.submit, { 'attr': { 'class': 'sc-button green' } } ) }}
{{ form_end(form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_permissionsgroup') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,66 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Permission group "%name%"'|trans({ '%name%': entity.name }) }}</h1>
<table class="record_properties">
<tbody>
<tr>
<th>{{ 'Name'|trans }}</th>
<td>{{ entity.name }}</td>
</tr>
</tbody>
</table>
{% if role_scopes|length > 0 %}
<h2>{{ 'Grant those permissions'|trans }}&nbsp;:</h2>
<table class="striped rounded">
<thead>
<tr>
<th>{{ 'Role'|trans }}</th>
<th>{{ 'Circle'|trans }}</th>
</tr>
</thead>
<tbody>
{% for role_scope in role_scopes %}
<tr>
<td>
{{ role_scope.role|trans }}
{% if expanded_roles[role_scope.role]|length > 1 %}
<br/>
<small>{{ 'Which implies'|trans }}&nbsp;: {% for role in expanded_roles[role_scope.role] %}{{ role }}{% if not loop.last %}, {% endif %}{% endfor %}</small>
{% endif %}
</td>
<td>{%- if role_scope.scope is not null -%}
{{ role_scope.scope.name|localize_translatable_string }}
{%- else -%}
<em>N/A</em>
{%- endif -%}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>{{ 'This group does not provide any permission'|trans }}.
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}">
{{ 'add permissions'|trans|capitalize }}</a></p>
{% endif %}
<ul class="record_actions">
<li>
<a href="{{ path('admin_permissionsgroup') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
<li>
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}">
{{ 'Edit'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Circle edit'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Circle edit'|trans }}</h1>
{{ form_start(edit_form) }}
{{ form_row(edit_form.name) }}
{{ form_row(edit_form.submit, { 'attr' : { 'class' : 'sc-button green' } } ) }}
{{ form_end(edit_form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_scope') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,41 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'List circles'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'List circles'|trans }}</h1>
<table class="records_list">
<thead>
<tr>
<th>{{ 'Name'|trans }}</th>
<th>{{ 'Actions'|trans }}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td><a href="{{ path('admin_scope_show', { 'id': entity.id }) }}">{{ entity.name|localize_translatable_string }}</a></td>
<td>
<ul>
<li>
<a href="{{ path('admin_scope_show', { 'id': entity.id }) }}">{{ 'show'|trans }}</a>
</li>
<li>
<a href="{{ path('admin_scope_edit', { 'id': entity.id }) }}">{{ 'edit'|trans }}</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a href="{{ path('admin_scope_new') }}">
{{ 'Create a new circle'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,20 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Circle creation'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Circle creation'|trans }}</h1>
{{ form_start(form) }}
{{ form_row(form.name) }}
{{ form_row(form.submit, { 'attr' : { 'class' : 'sc-button green' } } ) }}
{{ form_end(form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_scope') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,29 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Circle'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Circle'|trans }}</h1>
<table class="record_properties">
<tbody>
<tr>
<th>{{ 'Name'|trans }}</th>
<td>{{ entity.name|localize_translatable_string }}</td>
</tr>
</tbody>
</table>
<ul class="record_actions">
<li>
<a href="{{ path('admin_scope') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
<li>
<a href="{{ path('admin_scope_edit', { 'id': entity.id }) }}">
{{ 'Edit'| trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,72 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'User edit'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'User edit'|trans }}</h1>
{{ form_start(edit_form) }}
{{ form_row(edit_form.username) }}
{{ form_row(edit_form.enabled, { 'label': "User'status"}) }}
{{ form_widget(edit_form.submit, { 'attr': { 'class' : 'sc-button green center' } } ) }}
<a href="{{ path('admin_user_edit_password', { 'id' : entity.id }) }}" class="sc-button orange">{{ 'Edit password'|trans }}</a>
{{ form_end(edit_form) }}
<h2>{{ 'Permissions granted'|trans }}</h2>
{% if entity.groupcenters|length > 0 %}
<table>
<thead>
<tr>
<th>{{ 'Permission group'|trans }}</th>
<th>{{ 'Center'|trans }}</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for groupcenter in entity.groupcenters %}
<tr>
<td>
<span class="user_group permissionsgroup">
{{ groupcenter.permissionsgroup.name }}
</span>
</td>
<td>
<span class="user_group center">
{{ groupcenter.center.name }}
</span>
</td>
<td>
{{ form_start(delete_groupcenter_form[groupcenter.id]) }}
{{ form_row(delete_groupcenter_form[groupcenter.id].submit, { 'attr': { 'class': 'sc-button red' } } ) }}
{{ form_rest(delete_groupcenter_form[groupcenter.id]) }}
{{ form_end(delete_groupcenter_form[groupcenter.id]) }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>{{ 'no permissions granted to this user'|trans }}</p>
{% endif %}
<h2>{{ 'Grant new permissions'|trans }}</h2>
{{ form_start(add_groupcenter_form) }}
{{ form_row(add_groupcenter_form.composed_groupcenter.center) }}
{{ form_row(add_groupcenter_form.composed_groupcenter.permissionsgroup) }}
{{ form_row(add_groupcenter_form.submit, { 'attr' : { 'class': 'sc-button green' } } ) }}
{{ form_end(add_groupcenter_form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_user') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,22 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'Edit password for %username%'|trans( { '%username%': entity.username } ) }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'Edit password for %username%'|trans( { '%username%': entity.username } ) }}</h1>
{{ form(edit_form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_user') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
<li>
<a href="{{ path('admin_user_edit', { 'id' : entity.id }) }}">
{{ 'Back to the user edition'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,41 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'user list'|trans|capitalize }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'user list'|trans|capitalize }}</h1>
<table class="records_list">
<thead>
<tr>
<th>{{ 'Username'|trans|capitalize }}</th>
<th>{{ 'Actions'|trans|capitalize }}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr class="{% if entity.isEnabled == false %}user-disabled{% else %}user-enabled{% endif %}" >
<td><a href="{{ path('admin_user_show', { 'id': entity.id }) }}">{{ entity.username }}</a></td>
<td>
<ul>
<li>
<a href="{{ path('admin_user_show', { 'id': entity.id }) }}">{{ 'show'|trans }}</a>
</li>
<li>
<a href="{{ path('admin_user_edit', { 'id': entity.id }) }}">{{ 'edit'|trans }}</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a href="{{ path('admin_user_new') }}">
{{ 'Add a new user'|trans|capitalize }}
</a>
</li>
</ul>
{% endblock admin_content %}

View File

@ -0,0 +1,17 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'User creation'|trans }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'User creation'|trans }}</h1>
{{ form(form) }}
<ul class="record_actions">
<li>
<a href="{{ path('admin_user') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,76 @@
{% extends 'ChillMainBundle::Admin/layout_permissions.html.twig' %}
{% block title %}{{ 'User %username%'|trans({ '%username%': entity.username }) }}{% endblock %}
{% block admin_content -%}
<h1>{{ 'User %username%'|trans({ '%username%': entity.username }) }}</h1>
<table class="record_properties">
<tbody>
<tr>
<th>{{ 'Username' }}</th>
<td>{{ entity.username }}</td>
</tr>
<tr>
<th>{{ "User'status"|trans }}</th>
<td>
{%- if entity.enabled -%}
{{ 'Enabled, the user is active'|trans }}
{%- else -%}
{{ 'Disabled, the user is not allowed to login'|trans }}
{%- endif -%}
</td>
</tr>
</tbody>
</table>
<h2>{{ 'Permissions granted'|trans }}</h2>
{% if entity.groupcenters|length > 0 %}
<table>
<thead>
<tr>
<th>{{ 'Permission group'|trans }}</th>
<th>{{ 'Center'|trans }}</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for groupcenter in entity.groupcenters %}
<tr>
<td>
<span class="user_group permissionsgroup">
{{ groupcenter.permissionsgroup.name }}
</span>
</td>
<td>
<span class="user_group center">
{{ groupcenter.center.name }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>{{ 'The user does not belong to any groupcenter'|trans }}.
<a href="{{ path('admin_user_edit', { 'id': entity.id }) }}">
{{ 'Add new group centers'|trans }}
</a>
</p>
{% endif %}
<ul class="record_actions">
<li>
<a href="{{ path('admin_user') }}">
{{ 'Back to the list'|trans }}
</a>
</li>
<li>
<a href="{{ path('admin_user_edit', { 'id': entity.id }) }}">
{{ 'Edit'|trans }}
</a>
</li>
</ul>
{% endblock admin_content %}

View File

@ -40,7 +40,7 @@
</div>
{% endfor %}
{% for flashMessage in app.session.flashbag.get('danger') %}
{% for flashMessage in app.session.flashbag.get('error') %}
<div class="grid-8 centered error">
<span>
{{ flashMessage|raw }}
@ -48,7 +48,7 @@
</div>
{% endfor %}
{% for flashMessage in app.session.flashbag.get('info') %}
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="grid-8 centered notice">
<span>
{{ flashMessage|raw }}

View File

@ -95,30 +95,29 @@ class AuthorizationHelper
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 === NULL) {
return true;
}
if ($scope->getId() === $roleScope
->getScope()->getId()) {
return true;
}
} else {
$permissionGroup = $groupCenter->getPermissionsGroup();
//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 === NULL) {
return true;
}
if ($scope->getId() === $roleScope
->getScope()->getId()) {
return true;
}
} else {
return true;
}
}
}
}
}
@ -139,25 +138,24 @@ class AuthorizationHelper
$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) {
$permissionGroup = $groupCenter->getPermissionsGroup();
//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 1;
} else {
if ($scope->getId() == $roleScope->getScope()->getId()){
$centers[] = $groupCenter->getCenter();
break 2;
} else {
if ($scope->getId() == $roleScope->getScope()->getId()){
$centers[] = $groupCenter->getCenter();
break 2;
}
}
break 1;
}
}
}
}
}
return $centers;
@ -178,15 +176,14 @@ class AuthorizationHelper
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()))) {
$permissionGroup = $groupCenter->getPermissionsGroup();
//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();
}
$scopes[] = $roleScope->getScope();
}
}
}

View 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\Security;
/**
* Declare role
*
* The role are added to the configuration at compile time.
*
* The implemented object must be declared as a service and tagged as
*
* <pre>
* my_role_declaration:
* # ...
* tags:
* - { name: chill.role }
* </pre>
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
interface ProvideRoleInterface
{
/**
* return an array of role provided by the object
*
* @return string[] array of roles (as string)
*/
public function getRoles();
/**
* return roles which doesn't need
*
* @return string[] array of roles without scopes
*/
public function getRolesWithoutScope();
}

78
Security/RoleProvider.php Normal file
View File

@ -0,0 +1,78 @@
<?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;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class RoleProvider
{
/**
*
* @var ProvideRoleInterface[]
*/
private $providers = array();
/**
* Add a role provider
*
* @internal This function is called by the dependency injector: it inject provider
* @param \Chill\MainBundle\Security\ProvideRoleInterface $provider
*/
public function addProvider(ProvideRoleInterface $provider)
{
$this->providers[] = $provider;
}
/**
*
* @return string[] the roles as string
*/
public function getRoles()
{
$roles = array();
foreach ($this->providers as $provider) {
if ($provider->getRoles() !== NULL) {
$roles = array_merge($roles, $provider->getRoles());
}
}
return $roles;
}
/**
*
* @return string[] the roles as string
*/
public function getRolesWithoutScopes()
{
$roles = array();
foreach ($this->providers as $provider) {
if ($provider->getRolesWithoutScope() !== NULL) {
$roles = array_merge($roles, $provider->getRolesWithoutScope());
}
}
return $roles;
}
}

View File

@ -68,6 +68,7 @@ trait PrepareUserTrait
$groupCenter = (new GroupCenter())
->setCenter($permission['center']);
$permissionGroup = new PermissionsGroup();
foreach ($permission['permissionsGroup'] as $pg) {
$roleScope = (new RoleScope())
@ -75,11 +76,14 @@ trait PrepareUserTrait
->setScope($pg['scope']);
;
$permissionGroup->addRoleScope($roleScope);
$groupCenter->addPermissionGroup($permissionGroup);
}
$groupCenter->setPermissionsGroup($permissionGroup);
$user->addGroupCenter($groupCenter);
}
}
return $user;
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class CenterControllerTest extends WebTestCase
{
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'admin',
'PHP_AUTH_PW' => 'password',
));
// Create a new entry in the database
$crawler = $client->request('GET', '/fr/admin/center/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(),
"Unexpected HTTP status code for GET /fr/admin/center/");
$crawler = $client->click($crawler->selectLink('Créer un nouveau centre')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Créer')->form(array(
'chill_mainbundle_center[name]' => 'Test center',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0,
$crawler->filter('td:contains("Test center")')->count(),
'Missing element td:contains("Test center")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
'chill_mainbundle_center[name]' => 'Foo',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(),
'Missing element [value="Foo"]');
$crawler = $client->request('GET', '/fr/admin/center/');
// Check the entity has been delete on the list
$this->assertRegExp('/Foo/', $client->getResponse()->getContent());
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PermissionsGroupControllerTest extends WebTestCase
{
public function testEmpty()
{
$this->markTestSkipped();
}
/*
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient();
// Create a new entry in the database
$crawler = $client->request('GET', '/admin/permissionsgroup/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /admin/permissionsgroup/");
$crawler = $client->click($crawler->selectLink('Create a new entry')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
'chill_mainbundle_permissionsgroup[field_name]' => 'Test',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(), 'Missing element td:contains("Test")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
'chill_mainbundle_permissionsgroup[field_name]' => 'Foo',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
// Delete the entity
$client->submit($crawler->selectButton('Delete')->form());
$crawler = $client->followRedirect();
// Check the entity has been delete on the list
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
}
*/
}

View File

@ -0,0 +1,59 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class ScopeControllerTest extends WebTestCase
{
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'admin',
'PHP_AUTH_PW' => 'password',
));
// Create a new entry in the database
$crawler = $client->request('GET', '/fr/admin/scope/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(),
"Unexpected HTTP status code for GET /fr/admin/scope/");
$crawler = $client->click($crawler->selectLink('Créer un nouveau cercle')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Créer')->form(array(
'chill_mainbundle_scope[name][fr]' => 'Test en fr',
'chill_mainbundle_scope[name][en]' => 'Test en en'
));
$client->submit($form/*, array(
'chill_mainbundle_scope' => array(
'name' => array(
'fr' => 'test en fr',
'en' => 'test in english',
'nl' => 'test in nl'
)
)
)*/);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test en fr")')->count(),
'Missing element td:contains("Test en fr")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
'chill_mainbundle_scope[name][fr]' => 'Foo',
'chill_mainbundle_scope[name][en]' => 'Foo en',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class UserControllerTest extends WebTestCase
{
public function testBlank()
{
$this->markTestSkipped();
}
/*
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient();
// Create a new entry in the database
$crawler = $client->request('GET', '/admin/user/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /admin/user/");
$crawler = $client->click($crawler->selectLink('Create a new entry')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
'chill_mainbundle_user[field_name]' => 'Test',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(), 'Missing element td:contains("Test")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
'chill_mainbundle_user[field_name]' => 'Foo',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
// Delete the entity
$client->submit($crawler->selectButton('Delete')->form());
$crawler = $client->followRedirect();
// Check the entity has been delete on the list
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
}
*/
}

View File

@ -15,7 +15,8 @@ class AppKernel extends Kernel
new \Symfony\Bundle\AsseticBundle\AsseticBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle()
new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
);
}

View File

@ -10,6 +10,13 @@ security:
role_hierarchy:
CHILL_MASTER_ROLE: [CHILL_INHERITED_ROLE_1]
providers:
chain_provider:
chain :
providers: [in_memory, users]
in_memory:
memory:
users:
admin: { password: "password", roles: 'ROLE_ADMIN' }
users:
entity:
class: Chill\MainBundle\Entity\User
@ -18,6 +25,8 @@ security:
encoders:
Chill\MainBundle\Entity\User:
algorithm: bcrypt
Symfony\Component\Security\Core\User\User:
algorithm: plaintext
firewalls:
dev:
@ -39,5 +48,5 @@ security:
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/[a-z]*/admin, roles: ROLE_ADMIN }
- { path: ^/, roles: ROLE_USER }

View File

@ -0,0 +1,46 @@
<?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\Validation\Constraint;
use Symfony\Component\Validator\Constraint;
/**
* Check that a role scope has a scope if required
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class RoleScopeScopePresenceConstraint extends Constraint
{
public $messagePresenceRequired = "The role \"%role%\" require to be associated with "
. "a scope.";
public $messageNullRequired = "The role \"%role%\" should not be associated with a scope.";
public function validatedBy()
{
return 'role_scope_scope_presence';
}
public function getTargets()
{
return self::CLASS_CONSTRAINT;
}
}

View File

@ -0,0 +1,102 @@
<?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\Validation\Validator;
use Chill\MainBundle\Security\RoleProvider;
use Chill\MainBundle\Entity\RoleScope;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Chill\MainBundle\Validation\Constraint\RoleScopeScopePresenceConstraint;
use Psr\Log\LoggerInterface;
use Symfony\Component\Translation\TranslatorInterface;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class RoleScopeScopePresence extends ConstraintValidator
{
/**
*
* @var RoleProvider
*/
private $roleProvider;
/**
*
* @var LoggerInterface
*/
private $logger;
/**
*
* @var TranslatorInterface
*/
private $translator;
public function __construct(RoleProvider $roleProvider, LoggerInterface $logger,
TranslatorInterface $translator)
{
$this->roleProvider = $roleProvider;
$this->logger = $logger;
$this->translator = $translator;
}
public function validate($value, Constraint $constraint)
{
if (! $value instanceof RoleScope) {
throw new \RuntimeException('The validated object is not an instance of roleScope');
}
if (! $constraint instanceof RoleScopeScopePresenceConstraint) {
throw new \RuntimeException('This validator should be used with RoleScopScopePresenceConstraint');
}
$this->logger->debug('begin validation of a role scope instance');
//if the role scope should have a scope
if (
!in_array($value->getRole(), $this->roleProvider->getRolesWithoutScopes())
&&
$value->getScope() === NULL
) {
$this->context->buildViolation($constraint->messagePresenceRequired)
->setParameter('%role%', $this->translator->trans($value->getRole()))
->addViolation();
$this->logger->debug('the role scope should have a scope, but scope is null. Violation build.');
} elseif // if the scope should be null
(
in_array($value->getRole(), $this->roleProvider->getRolesWithoutScopes())
&&
! is_null($value->getScope())
)
{
$this->context->buildViolation($constraint->messageNullRequired)
->setParameter('%role%', $this->translator->trans($value->getRole()))
->addViolation();
$this->logger->debug('the role scole should not have a scope, but scope is not null. Violation build.');
} // everything is fine !
else {
$this->logger->debug('role scope is valid. Validation finished.');
}
}
}