Commit 40e2f9a5 authored by Laurent Lécluse's avatar Laurent Lécluse
Browse files

Possibilité de bloquer l'usage de certains rôles si l'on se trouve hors du...

Possibilité de bloquer l'usage de certains rôles si l'on se trouve hors du réseau de l'établissement

#25913
parent 52d2971d
# OSE 12 alpha
## Nouveautés
* Possibilité de bloquer l'usage de certains rôles si l'on se trouve hors du réseau de l'établissement
# OSE 11.2
## Correction de bug
......
......@@ -15,6 +15,40 @@ return [
/* Langue utilisée (la liste des langues est disponible dans le répertoire /language de l'application) */
'locale' => 'fr_FR',
/* Fonction qui détermine si le client est situé dans le réseau de l'établissement ou non *
* Si la fonction retourne true, alors on n'est topujours considéré comme connecté depuis le réseau de l'établissement
*/
'inEtablissement' => function () {
/* Exemple de test :
$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
$forwarded = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
$ipInterne = '10.'; // les IP doivent débuter par 10.* pour être considérés comme de l'établissement
$proxies = [
// Liste des adresses IP de vos proxies
];
$reverseProxies = [
// Liste des adresses IP des reverse-proxies
];
// Si on est en direct et en interne sans passer par le proxy (pas de redirection)
if (0 === strpos($ip,$ipInterne) && $forwarded === '') return true;
// Si on est en interne, que l'on sort puis on re-rentre en passant par le reverse proxy
if (in_array($ip,$reverseProxies) && 0 === strpos($forwarded,$ipInterne)) return true;
// Si on est en interne, que l'on passe par le proxy en interne
if (in_array($ip,$proxies) && 0 === strpos($forwarded,$ipInterne)) return true;
// Sinon, on vient de l'extérieur
return false;
*/
return true;
},
],
......
......@@ -157,16 +157,20 @@ $config = [
ORM\Event\Listeners\HistoriqueListener::class => ORM\Event\Listeners\HistoriqueListener::class,
],
'factories' => [
\Zend\Navigation\Navigation::class => Navigation\NavigationFactory::class,
Provider\Role\RoleProvider::class => Provider\Role\RoleProviderFactory::class,
Provider\Identity\IdentityProvider::class => Provider\Identity\IdentityProviderFactory::class,
Service\ContextService::class => Service\Factory\ContextServiceFactory::class,
'MouchardCompleterContext' => MouchardCompleterContextFactory::class,
'UnicaenAuth\Service\Privilege' => Service\Factory\PrivilegeServiceFactory::class,
Connecteur\LdapConnecteur::class => Connecteur\Factory\LdapConnecteurFactory::class,
Cache\CacheService::class => Cache\Factory\CacheServiceFactory::class,
Service\UtilisateurService::class => Service\Factory\UtilisateurServiceFactory::class,
Assertion\InformationAssertion::class => \UnicaenAuth\Assertion\AssertionFactory::class,
\Zend\Navigation\Navigation::class => Navigation\NavigationFactory::class,
Provider\Role\RoleProvider::class => Provider\Role\RoleProviderFactory::class,
Provider\Identity\IdentityProvider::class => Provider\Identity\IdentityProviderFactory::class,
Service\ContextService::class => Service\Factory\ContextServiceFactory::class,
'MouchardCompleterContext' => MouchardCompleterContextFactory::class,
'UnicaenAuth\Service\Privilege' => Service\Factory\PrivilegeServiceFactory::class,
Connecteur\LdapConnecteur::class => Connecteur\Factory\LdapConnecteurFactory::class,
Cache\CacheService::class => Cache\Factory\CacheServiceFactory::class,
Service\UtilisateurService::class => Service\Factory\UtilisateurServiceFactory::class,
Assertion\InformationAssertion::class => \UnicaenAuth\Assertion\AssertionFactory::class,
HostLocalization\HostLocalizationOse::class => HostLocalization\HostLocalizationOseFactory::class,
],
'aliases' => [
'HostLocalization' => HostLocalization\HostLocalizationOse::class,
],
],
'view_helpers' => [
......
......@@ -20,6 +20,7 @@
<field name="histoModification" type="datetime" column="HISTO_MODIFICATION" nullable="false"/>
<field name="libelle" type="string" column="LIBELLE" length="50" nullable="false"/>
<field name="peutChangerStructure" type="boolean" column="PEUT_CHANGER_STRUCTURE" nullable="false" />
<field name="accessibleExterieur" type="boolean" column="ACCESSIBLE_EXTERIEUR" nullable="false" />
<many-to-one field="perimetre" target-entity="Application\Entity\Db\Perimetre">
<join-columns>
<join-column name="PERIMETRE_ID" referenced-column-name="ID"/>
......
......@@ -43,6 +43,11 @@ class Role implements HistoriqueAwareInterface, RoleInterface
*/
protected $peutChangerStructure;
/**
* @var bool
*/
private $accessibleExterieur = true;
/**
* @var \Doctrine\Common\Collections\Collection
*/
......@@ -198,6 +203,30 @@ class Role implements HistoriqueAwareInterface, RoleInterface
/**
* @return bool
*/
public function getAccessibleExterieur(): bool
{
return $this->accessibleExterieur;
}
/**
* @param bool $accessibleExterieur
*
* @return Role
*/
public function setAccessibleExterieur(bool $accessibleExterieur): Role
{
$this->accessibleExterieur = $accessibleExterieur;
return $this;
}
/**
* Get id
*
......
......@@ -23,7 +23,7 @@ class RoleForm extends AbstractForm
$hydrator = new RoleFormHydrator;
$hydrator->setServicePerimetre($this->getServicePerimetre());
$this->setHydrator($hydrator);
$this->setAttribute('action',$this->getCurrentUrl());
$this->setAttribute('action', $this->getCurrentUrl());
$this->add([
'type' => 'Text',
'name' => 'code',
......@@ -61,6 +61,14 @@ class RoleForm extends AbstractForm
'type' => 'Checkbox',
]);
$this->add([
'name' => 'accessible-exterieur',
'options' => [
'label' => 'Utilisable hors du réseau informatique de l\'établissement',
],
'type' => 'Checkbox',
]);
$this->add([
'name' => 'id',
'type' => 'Hidden',
......@@ -99,6 +107,9 @@ class RoleForm extends AbstractForm
'peut-changer-structure' => [
'required' => true,
],
'accessible-exterieur' => [
'required' => true,
],
];
}
}
......@@ -114,8 +125,8 @@ class RoleFormHydrator implements HydratorInterface
/**
* @param array $data
* @param \Application\Entity\Db\Role $object
* @param array $data
* @param \Application\Entity\Db\Role $object
*
* @return object
*/
......@@ -125,6 +136,7 @@ class RoleFormHydrator implements HydratorInterface
$object->setLibelle($data['libelle']);
$object->setPerimetre($this->getServicePerimetre()->get($data['perimetre']));
$object->setPeutChangerStructure($data['peut-changer-structure']);
$object->setAccessibleExterieur($data['accessible-exterieur']);
return $object;
}
......@@ -132,7 +144,7 @@ class RoleFormHydrator implements HydratorInterface
/**
* @param \Application\Entity\Db\Role $object
* @param \Application\Entity\Db\Role $object
*
* @return array
*/
......@@ -144,6 +156,7 @@ class RoleFormHydrator implements HydratorInterface
'libelle' => $object->getLibelle(),
'perimetre' => $object->getPerimetre() ? $object->getPerimetre()->getId() : null,
'peut-changer-structure' => $object->getPeutChangerStructure(),
'accessible-exterieur' => $object->getAccessibleExterieur(),
];
return $data;
......
<?php
namespace Application\HostLocalization;
use UnicaenApp\HostLocalization\HostLocalizationInterface;
class HostLocalizationOse implements HostLocalizationInterface
{
public function inEtablissement(): bool
{
$inEtablissement = \AppConfig::get('global', 'inEtablissement', true);
if ($inEtablissement instanceof HostLocalizationInterface) {
$inEtablissement = $inEtablissement->inEtablissement();
}
if (is_callable($inEtablissement)) {
$inEtablissement = $inEtablissement();
}
return (bool)$inEtablissement;
}
}
\ No newline at end of file
<?php
namespace Application\HostLocalization;
use Psr\Container\ContainerInterface;
class HostLocalizationOseFactory
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$hl = new HostLocalizationOse();
return $hl;
}
}
\ No newline at end of file
......@@ -6,6 +6,7 @@ use Application\Entity\Db\Affectation;
use Application\Entity\Db\Role;
use Application\Service\Traits\ContextServiceAwareTrait;
use Application\Service\Traits\IntervenantServiceAwareTrait;
use UnicaenApp\HostLocalization\HostLocalizationAwareTrait;
use UnicaenApp\Service\EntityManagerAwareTrait;
use UnicaenAuth\Provider\Identity\ChainableProvider;
use UnicaenAuth\Provider\Identity\ChainEvent;
......@@ -22,6 +23,7 @@ class IdentityProvider implements ChainableProvider, IdentityProviderInterface
use SessionContainerTrait;
use IntervenantServiceAwareTrait;
use ContextServiceAwareTrait;
use HostLocalizationAwareTrait;
/**
* @var array
......@@ -45,7 +47,7 @@ class IdentityProvider implements ChainableProvider, IdentityProviderInterface
*/
public function getIdentityRoles()
{
if (!$this->identityRoles){
if (!$this->identityRoles) {
$filter = $this->getEntityManager()->getFilters()->enable('historique');
$filter->init([
Role::class,
......@@ -54,6 +56,8 @@ class IdentityProvider implements ChainableProvider, IdentityProviderInterface
$this->identityRoles = ['guest' => 'guest'];
$inEtablissement = $this->getHostLocalization()->inEtablissement();
/**
* Rôles que possède l'utilisateur dans la base de données.
*/
......@@ -63,14 +67,14 @@ class IdentityProvider implements ChainableProvider, IdentityProviderInterface
/* @var $affectation Affectation */
$role = $affectation->getRole();
try {
if ($role->estNonHistorise()) {
if ($role->estNonHistorise() && ($inEtablissement || $role->getAccessibleExterieur())) {
$roleId = $role->getCode();
if ($structure = $affectation->getStructure()) {
$roleId .= '-' . $structure->getSourceCode();
}
$this->identityRoles[] = $roleId;
}
}catch(\Exception $e){
} catch (\Exception $e) {
// on ignore les affectations dont les rôles ont été supprimés
}
}
......@@ -82,7 +86,6 @@ class IdentityProvider implements ChainableProvider, IdentityProviderInterface
if ($intervenant = $this->getServiceContext()->getIntervenant()) {
$this->identityRoles[$intervenant->getStatut()->getRoleId()] = $intervenant->getStatut()->getRoleId();
}
}
return $this->identityRoles;
......
......@@ -26,6 +26,7 @@ class IdentityProviderFactory
$identityProvider->setEntityManager($container->get(\Application\Constants::BDD));
$identityProvider->setServiceContext($container->get(ContextService::class));
$identityProvider->setHostLocalization($container->get('HostLocalization'));
return $identityProvider;
}
......
......@@ -14,6 +14,7 @@ echo $this->formControlGroup($form->get('code'));
echo $this->formControlGroup($form->get('libelle'));
echo $this->formControlGroup($form->get('perimetre'));
echo $this->formControlGroup($form->get('peut-changer-structure'));
echo $this->formControlGroup($form->get('accessible-exterieur'));
echo $this->formRow($form->get('submit'));
echo $this->formHidden($form->get('id'));
......
......@@ -5,8 +5,8 @@ use Application\Provider\Privilege\Privileges;
/* @var $roles Application\Entity\Db\Role[] */
$canEdit = $this->isAllowed(Privileges::getResourceId(Privileges::DROIT_ROLE_EDITION));
$ajoutUrl = $this->url( 'droits/roles/edition' );
$canEdit = $this->isAllowed(Privileges::getResourceId(Privileges::DROIT_ROLE_EDITION));
$ajoutUrl = $this->url('droits/roles/edition');
?>
<table class="table table-condensed table-bordered">
......@@ -15,37 +15,42 @@ $ajoutUrl = $this->url( 'droits/roles/edition' );
<th>Libellé</th>
<th>Périmètre</th>
<th>Struct. modifiable</th>
<?php if ($canEdit): ?><th>Action</th><?php endif; ?>
</tr>
<?php foreach( $roles as $role ):
$editionUrl = $this->url( 'droits/roles/edition', ['role' => $role->getId()] );
$suppressionUrl = $this->url( 'droits/roles/suppression', ['role' => $role->getId()] );
?>
<tr>
<td><?= $role->getCode(); ?></td>
<td><?= $role->getLibelle(); ?></td>
<td><?= $role->getPerimetre(); ?></td>
<td style="text-align: center;"><?= $role->getPeutChangerStructure() ? '<span class="glyphicon glyphicon-ok text-success"></span>' : '<span class="glyphicon glyphicon-remove text-danger refuse"></span>'; ?></td>
<th>Accessible hors établissement</th>
<?php if ($canEdit): ?>
<td style="width:1%;white-space: nowrap;text-align: center">
<a href="<?= $editionUrl; ?>" class="ajax-modal" data-event="role-edition"><span class="glyphicon glyphicon-edit"></span></a>
<a href="<?= $suppressionUrl; ?>" class="ajax-modal" data-event="role-suppression"><span class="glyphicon glyphicon-remove"></span></a>
</td>
<?php endif; ?>
<th>Action</th><?php endif; ?>
</tr>
<?php endforeach; ?>
<?php foreach ($roles as $role):
$editionUrl = $this->url('droits/roles/edition', ['role' => $role->getId()]);
$suppressionUrl = $this->url('droits/roles/suppression', ['role' => $role->getId()]);
?>
<tr>
<td><?= $role->getCode(); ?></td>
<td><?= $role->getLibelle(); ?></td>
<td><?= $role->getPerimetre(); ?></td>
<td style="text-align: center;"><?= $role->getPeutChangerStructure() ? '<span class="glyphicon glyphicon-ok text-success"></span>' : '<span class="glyphicon glyphicon-remove text-danger refuse"></span>'; ?></td>
<td style="text-align: center;"><?= $role->getAccessibleExterieur() ? '<span class="glyphicon glyphicon-ok text-success"></span>' : '<span class="glyphicon glyphicon-remove text-danger refuse"></span>'; ?></td>
<?php if ($canEdit): ?>
<td style="width:1%;white-space: nowrap;text-align: center">
<a href="<?= $editionUrl; ?>" class="ajax-modal" data-event="role-edition"><span
class="glyphicon glyphicon-edit"></span></a>
<a href="<?= $suppressionUrl; ?>" class="ajax-modal" data-event="role-suppression"><span
class="glyphicon glyphicon-remove"></span></a>
</td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
</table>
<?php if ($canEdit): // droits ?>
<a href="<?= $ajoutUrl ?>" class="btn btn-primary ajax-modal" data-event="role-edition">Création d'un nouveau rôle</a>
<a href="<?= $ajoutUrl ?>" class="btn btn-primary ajax-modal" data-event="role-edition">Création d'un nouveau rôle</a>
<?php endif; ?>
<?= $this->modalAjaxDialog('roles-edition-suppression'); ?>
<script type="text/javascript">
$(function() {
$("body").on("role-edition", function(event, data) {
$(function () {
$("body").on("role-edition", function (event, data) {
window.location.reload();
});
$("body").on("role-suppression", function(event, data) {
$("body").on("role-suppression", function (event, data) {
window.location.reload();
});
});
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment