Commit f8173ce6 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Ajout du nécessaire pour permettre à l'utilisateur changer de profil courant :

- nouveau contrôleur Utilisateur pour recevoir la requête de sélection du rôle pr l'utilisateur.
- ajout du nécessaire au service AuthUserContext pour mémoriser la sélection en session.
- aide de vue UserProfileSelect permettant de sélectioner un rôle parmi ceux de l'utilisateur (liste déroulante ou boutons radios) avec lancement requête AJAX vers le contrôleur Utilisateur.
- intégration de l'aide de vue dans l'aide de vue UserProfile.
- ajout attribut "selectable" qur la classe NamedRole car on ne veut pas que le rôle "Authentifié(e)" soit sélectionable.
- refactorisation aide de vue UserProfile pour utiliser le service AuthUserContext.
parent 91ad04be
......@@ -122,11 +122,12 @@ class Module implements ConfigProviderInterface, ViewHelperProviderInterface, Se
{
return array(
'factories' => array(
'userConnection' => 'UnicaenAuth\View\Helper\UserConnectionFactory',
'userCurrent' => 'UnicaenAuth\View\Helper\UserCurrentFactory',
'userStatus' => 'UnicaenAuth\View\Helper\UserStatusFactory',
'userProfile' => 'UnicaenAuth\View\Helper\UserProfileFactory',
'userInfo' => 'UnicaenAuth\View\Helper\UserInfoFactory',
'userConnection' => 'UnicaenAuth\View\Helper\UserConnectionFactory',
'userCurrent' => 'UnicaenAuth\View\Helper\UserCurrentFactory',
'userStatus' => 'UnicaenAuth\View\Helper\UserStatusFactory',
'userProfile' => 'UnicaenAuth\View\Helper\UserProfileFactory',
'userInfo' => 'UnicaenAuth\View\Helper\UserInfoFactory',
'userProfileSelect' => 'UnicaenAuth\View\Helper\UserProfileSelectFactory',
),
'invokables' => array(
'appConnection' => 'UnicaenAuth\View\Helper\AppConnection',
......
......@@ -91,8 +91,8 @@ $bjyauthorize = array(
* - le rôle 'user', c'est le rôle de tout utilisateur authentifié.
*/
'UnicaenAuth\Provider\Role\Config' => array(
'guest' => array('name' => "Non authentifié(e)", 'children' => array(
'user' => array('name' => "Authentifié(e)")
'guest' => array('name' => "Non authentifié(e)", 'selectable' => false, 'children' => array(
'user' => array('name' => "Authentifié(e)", 'selectable' => false)
)),
),
/**
......@@ -128,12 +128,13 @@ $bjyauthorize = array(
array('controller' => 'zfcuser', 'roles' => array()),
array('controller' => 'Application\Controller\Index', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'etab', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'apropos', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'contact', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'plan', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'mentions-legales', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'informatique-et-libertes', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'etab', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'apropos', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'contact', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'plan', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'mentions-legales', 'roles' => array()),
array('controller' => 'UnicaenApp\Controller\Application', 'action' => 'informatique-et-libertes', 'roles' => array()),
array('controller' => 'UnicaenAuth\Controller\Utilisateur', 'action' => 'selectionner-profil', 'roles' => array('user')),
),
),
);
......@@ -197,7 +198,7 @@ return array(
),
'controllers' => array(
'invokables' => array(
'UnicaenAuth\Controller\Utilisateur' => 'UnicaenAuth\Controller\UtilisateurController',
),
),
'view_manager' => array(
......@@ -263,6 +264,33 @@ return array(
),
),
),
'utilisateur' => array(
'type' => 'Literal',
'options' => array(
'route' => '/utilisateur',
'defaults' => array(
'__NAMESPACE__' => 'UnicaenAuth\Controller',
'controller' => 'Utilisateur',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:action[/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]*',
),
'defaults' => array(
'action' => 'index',
),
),
),
),
),
),
),
// All navigation-related configuration is collected in the 'navigation' key
......
<?php
namespace UnicaenAuth\Controller;
use Zend\Mvc\Controller\AbstractActionController;
/**
* Description of UtilisateurController
*
* @author Bertrand GAUTHIER <bertrand.gauthier at unicaen.fr>
*/
class UtilisateurController extends AbstractActionController
{
/**
* Traite les requêtes AJAX POST de sélection d'un profil utilisateur.
* La sélection est mémorisé en session par le service AuthUserContext.
*/
public function selectionnerProfilAction()
{
if (!$this->getRequest()->isXmlHttpRequest()) {
return $this->url()->fromRoute('home');
}
if (($role = $this->getRequest()->getPost('role'))) {
$this->getAuthUserContextService()->setSelectedIdentityRole($role);
}
exit;
}
/**
* @return \UnicaenAuth\Service\UserContext
*/
protected function getAuthUserContextService()
{
return $this->getServiceLocator()->get('AuthUserContext');
}
}
\ No newline at end of file
......@@ -64,8 +64,22 @@ class Config extends \BjyAuthorize\Provider\Role\Config
$children = array();
}
if (isset($options['description'])) {
$description = (bool) $options['description'];
}
else {
$description = false;
}
if (isset($options['selectable'])) {
$selectable = (bool) $options['selectable'];
}
else {
$selectable = true;
}
$roles = array();
$role = new NamedRole($name, $parent, $roleName);
$role = new NamedRole($name, $parent, $roleName, $description, $selectable);
$roles[] = $role;
foreach ($children as $key => $value) {
......
......@@ -3,47 +3,34 @@
namespace UnicaenAuth\Service;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Session\Container as SessionContainer;
use ZfcUser\Entity\UserInterface;
use UnicaenAuth\Entity\Ldap\People;
/**
*
* Service centralisant des méthodes utiles concernant l'utilisateur authentifié.
*
* @author Laurent LÉCLUSE <laurent.lecluse at unicaen.fr>
*/
class UserContext implements ServiceLocatorAwareInterface
{
/**
* @var ServiceLocatorInterface
*/
protected $sl;
use ServiceLocatorAwareTrait;
/**
* @var mixed
*/
protected $identity;
/**
*
* @return mixed
* @var array
*/
protected function getIdentity()
{
if (null === $this->identity) {
$authenticationService = $this->sl->get('Zend\Authentication\AuthenticationService');
if ($authenticationService->hasIdentity()) {
$this->identity = $authenticationService->getIdentity();
}
}
return $this->identity;
}
protected $identityRoles;
/**
* @var SessionContainer
*/
protected $sessionContainer;
/**
* Retourne l'utilisateur BDD courant
......@@ -76,25 +63,112 @@ class UserContext implements ServiceLocatorAwareInterface
}
/**
* Set service locator
* Retourne l'identité correspondant à l'utilisateur courant.
*
* @param ServiceLocatorInterface $serviceLocator
* @return self
* @return mixed
*/
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
protected function getIdentity()
{
$this->sl = $serviceLocator;
if (null === $this->identity) {
$authenticationService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');
if ($authenticationService->hasIdentity()) {
$this->identity = $authenticationService->getIdentity();
}
}
return $this->identity;
}
/**
* Retourne les rôles de l'utilisateur courant.
*
* @return array
*/
public function getIdentityRoles()
{
if (null === $this->identityRoles) {
$authorize = $this->getServiceLocator()->get('BjyAuthorize\Service\Authorize');
$identityProvider = $authorize->getIdentityProvider();
$this->identityRoles = $identityProvider->getIdentityRoles();
}
return $this->identityRoles;
}
/**
* Retourne les rôles de l'utilisateur courant qui peuvent être sélectionnés.
*
* @return array
*/
public function getSelectableIdentityRoles()
{
return array_filter(
$this->getIdentityRoles(),
function($r) { return !($r instanceof \UnicaenAuth\Acl\NamedRole && !$r->getSelectable()); });
}
/**
* Retourne le rôle utilisateur sélectionné, ou le premier sélectionnable si aucun n'a été sléectionné.
*
* @return mixed
*/
public function getSelectedIdentityRole()
{
if (null === $this->getSessionContainer()->selectedIdentityRole) {
$roles = $this->getSelectableIdentityRoles();
$this->getSessionContainer()->selectedIdentityRole = reset($roles) ?: null;
}
return $this->getSessionContainer()->selectedIdentityRole;
}
/**
* Mémorise le rôle courant de l'utilisateur.
*
* @param mixed $role
* @return \UnicaenAuth\Service\UserContext
*/
public function setSelectedIdentityRole($role)
{
if ($role) {
if (!$this->isRoleValid($role)) {
throw new \Common\Exception\RuntimeException("Rôle spécifié invalide.");
}
$this->getSessionContainer()->selectedIdentityRole = $role;
}
else {
unset($this->getSessionContainer()->selectedIdentityRole);
}
return $this;
}
/**
* Get service locator
*
* @return ServiceLocatorInterface
* Teste si le rôle spécifié fait partie des rôles disponibles.
*
* @param mixed $role
* @return boolean
*/
public function getServiceLocator()
protected function isRoleValid($role)
{
return $this->sl;
foreach ($this->getIdentityRoles() as $r) {
if ($r instanceof \Zend\Permissions\Acl\Role\RoleInterface) {
$r = $r->getRoleId();
}
if ($role === $r) {
return true;
}
}
return false;
}
/**
* Retourne le stockage en session utilisé pour mémoriser le profil
* sélectionné par l'utilsateur.
*
* @return SessionContainer
*/
protected function getSessionContainer()
{
if (null === $this->sessionContainer) {
$this->sessionContainer = new SessionContainer(get_class());
}
return $this->sessionContainer;
}
}
\ No newline at end of file
......@@ -43,7 +43,10 @@ class UserCurrent extends UserAbstract
if ($this->getIdentity()) {
$userProfileHelper = $this->getView()->plugin('userProfile'); /* @var $userProfileHelper \UnicaenAuth\View\Helper\UserProfile */
$userInfoHelper = $this->getView()->plugin('userInfo'); /* @var $userInfoHelper \UnicaenAuth\View\Helper\UserInfo */
$userProfileHelper->setUserProfileSelectable();
$userInfoHelper = $this->getView()->plugin('userInfo'); /* @var $userInfoHelper \UnicaenAuth\View\Helper\UserInfo */
$content = $userProfileHelper . $userInfoHelper($this->getAffectationFineSiDispo());
}
else {
......@@ -53,7 +56,7 @@ class UserCurrent extends UserAbstract
}
}
$content = preg_replace('/\r\n|\n|\r/', '', $content);
$content = htmlspecialchars(preg_replace('/\r\n|\n|\r/', '', $content));
$title = _("Utilisateur connecté à l'application");
if ($this->getTranslator()) {
......
<?php
namespace UnicaenAuth\View\Helper;
use BjyAuthorize\Provider\Identity\ProviderInterface;
use UnicaenAuth\Acl\NamedRole;
use Zend\Permissions\Acl\Role\RoleInterface;
......@@ -13,17 +12,32 @@ use Zend\Permissions\Acl\Role\RoleInterface;
class UserProfile extends UserAbstract
{
/**
* @var ProviderInterface
* @var \UnicaenAuth\Service\UserContext
*/
protected $identityProvider;
protected $userContextService;
/**
* @var bool
*/
protected $userProfileSelectable = false;
/**
* @var array
*/
protected $identityRoles;
/**
* Point d'entrée.
*
* @param bool $userProfileSelectable Spécifie s'il faut afficher les profils
* de l'utilisateur sous forme d'une liste déroulante ou de boutons radios, permettant
* ainsi à l'utilisateur de changer de profil courant.
* @return self
*/
public function __invoke()
public function __invoke($userProfileSelectable = false)
{
$this->userProfileSelectable = $userProfileSelectable;
return $this;
}
......@@ -32,7 +46,7 @@ class UserProfile extends UserAbstract
*
* @return string
*/
public function __toString()
public function render()
{
$title = _("Profil utilisateur");
$unknown = _("Inconnu");
......@@ -44,9 +58,58 @@ class UserProfile extends UserAbstract
$none = $this->getTranslator()->translate($none, $this->getTranslatorTextDomain());
}
$roles = array();
$identityRoles = $this->getIdentityProvider() ? $this->getIdentityProvider()->getIdentityRoles() : array();
foreach ($identityRoles as $role) {
$roles = $this->getIdentityRolesAsOptions();
if (!$roles) {
$roles[] = $none;
}
$html = "<strong>$title :</strong>" . PHP_EOL;
if ($this->userProfileSelectable) {
$html .= $this->getView()->userProfileSelect(false);
}
else {
$html .= $this->getView()->htmlList($roles);
}
return $html;
}
/**
* Retourne le code HTML généré par cette aide de vue.
*
* @return string
*/
public function __toString()
{
return $this->render();
}
/**
* Retourne les rôles de l'utilisateur courant.
*
* @return array
*/
protected function getIdentityRoles()
{
if (null === $this->identityRoles) {
$this->identityRoles = $this->getUserContextService()->getIdentityRoles();
}
return $this->identityRoles;
}
/**
* Retourne les rôles de l'utilisateur courant.
*
* @return array
*/
protected function getIdentityRolesAsOptions()
{
$identityRoles = $this->getIdentityRoles();
$roles = array();
foreach ($identityRoles as $id => $role) {
$lib = '';
if ($role instanceof NamedRole) {
$lib = $role->getRoleName();
......@@ -65,36 +128,46 @@ class UserProfile extends UserAbstract
if ($this->getTranslator()) {
$lib = $this->getTranslator()->translate($lib, $this->getTranslatorTextDomain());
}
$roles[] = $lib;
$roles[$id] = $lib;
}
}
if (!$roles) {
$roles[] = $none;
}
$html = "<strong>$title :</strong>" . PHP_EOL;
$html .= $this->getView()->htmlList($roles);
return $html;
return $roles;
}
/**
*
* @return ProviderInterface
* @return \UnicaenAuth\Service\UserContext
*/
public function getIdentityProvider()
public function getUserContextService()
{
return $this->identityProvider;
return $this->userContextService;
}
/**
*
* @param ProviderInterface $identityProvider
* @param \UnicaenAuth\Service\UserContext $userContextService
* @return self
*/
public function setIdentityProvider(ProviderInterface $identityProvider = null)
public function setUserContextService(\UnicaenAuth\Service\UserContext $userContextService = null)
{
$this->identityProvider = $identityProvider;
$this->userContextService = $userContextService;
return $this;
}
/**
* Spécifie s'il faut afficher les profils
* de l'utilisateur sous forme d'une liste déroulante ou de boutons radios, permettant
* ainsi à l'utilisateur de changer de profil courant.
*
* @param bool $userProfileSelectable
* @return \UnicaenAuth\View\Helper\UserProfile
*/
public function setUserProfileSelectable($userProfileSelectable = true)
{
$this->userProfileSelectable = $userProfileSelectable;
return $this;
}
}
\ No newline at end of file
......@@ -20,13 +20,12 @@ class UserProfileFactory implements FactoryInterface
*/
public function createService(ServiceLocatorInterface $helperPluginManager)
{
$serviceLocator = $helperPluginManager->getServiceLocator();
$authService = $serviceLocator->get('zfcuser_auth_service');
$authorize = $serviceLocator->get('BjyAuthorize\Service\Authorize');
$identityProvider = $authorize->getIdentityProvider();
$serviceLocator = $helperPluginManager->getServiceLocator();
$authService = $serviceLocator->get('zfcuser_auth_service');
$userContextService = $serviceLocator->get('AuthUserContext');
$helper = new UserProfile($authService);
$helper->setIdentityProvider($identityProvider);
$helper->setUserContextService($userContextService);
return $helper;
}
......
<?php
namespace UnicaenAuth\View\Helper;
use BjyAuthorize\Provider\Identity\ProviderInterface;
use UnicaenAuth\Acl\NamedRole;
use Zend\Permissions\Acl\Role\RoleInterface;
/**
* Aide de vue permettant à l'utilisateur de sélectionner son profil courant parmi
* les différents profils qu'il possède.
*
* Si l'utilisateur possède moins de 2 rôles, rien ne s'affiche.
*
* @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr>
*/
class UserProfileSelect extends UserProfile
{
/**
* @var string
*/
protected $formClass;
/**
* @var bool
*/
protected $asSelect = false;
/**
* Retourne le code HTML généré par cette aide de vue.
*
* @return string
*/
public function render()
{
$roles = $this->getIdentityRolesAsOptions();
if (!$roles) {
return '';
}
$formClass = 'user-profile-select-form';
$inputClass = 'user-profile-select-input';
$form = new \Zend\Form\Form();
$form->setAttribute('class', "$formClass " . $this->formClass);
$html = $this->getView()->form()->openTag($form);
// rendu sous forme d'un select
if ($this->asSelect) {
$select = new \Zend\Form\Element\Select('role');
$select
->setValueOptions($roles)
->setAttributes(array(
'class' => $inputClass,