Commit 59f490ef authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Intégration des modifications issues de la branche dev-ldap_extract_params...

Intégration des modifications issues de la branche dev-ldap_extract_params pour pouvoir configurer les filtres d'accès au LDAP
parent 6089b063
Loading
Loading
Loading
Loading
+32 −1
Changes for config/module.config.php: 32 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -3,6 +3,37 @@
namespace UnicaenApp;

return [
    /**
     * Paramètres de fonctionnement LDAP.
     */
    'ldap' => [
        'dn' => [
            'UTILISATEURS_BASE_DN'                  => 'ou=people,dc=unicaen,dc=fr',
            'UTILISATEURS_DESACTIVES_BASE_DN'       => 'ou=deactivated,dc=unicaen,dc=fr',
            'GROUPS_BASE_DN'                        => 'ou=groups,dc=unicaen,dc=fr',
            'STRUCTURES_BASE_DN'                    => 'ou=structures,dc=unicaen,dc=fr',
        ],
        'filters' => [
            'LOGIN_FILTER'                          => '(supannAliasLogin=%s)',
            'UTILISATEUR_STD_FILTER'                => '(|(uid=p*)(&(uid=e*)(eduPersonAffiliation=student)))',
            'CN_FILTER'                             => '(cn=%s)',
            'NAME_FILTER'                           => '(cn=%s*)',
            'UID_FILTER'                            => '(uid=%s)',
            'NO_INDIVIDU_FILTER'                    => '(supannEmpId=%08s)',
            'AFFECTATION_FILTER'                    => '(&(uid=*)(eduPersonOrgUnitDN=%s))',
            'AFFECTATION_CSTRUCT_FILTER'            => '(&(uid=*)(|(ucbnSousStructure=%s;*)(supannAffectation=%s;*)))',
            'LOGIN_OR_NAME_FILTER'                  => '(|(supannAliasLogin=%s)(cn=%s*))',
            'MEMBERSHIP_FILTER'                     => '(memberOf=%s)',
            'AFFECTATION_ORG_UNIT_FILTER'           => '(eduPersonOrgUnitDN=%s)',
            'AFFECTATION_ORG_UNIT_PRIMARY_FILTER'   => '(eduPersonPrimaryOrgUnitDN=%s)',
            'ROLE_FILTER'                           => '(supannRoleEntite=[role={SUPANN}%s][type={SUPANN}%s][code=%s]*)',
            'PROF_STRUCTURE'                        => '(&(eduPersonAffiliation=teacher)(eduPersonOrgUnitDN=%s))',
            'FILTER_STRUCTURE_DN'		            => '(%s)',
            'FILTER_STRUCTURE_CODE_ENTITE'	        => '(supannCodeEntite=%s)',
            'FILTER_STRUCTURE_CODE_ENTITE_PARENT'   => '(supannCodeEntiteParent=%s)',
        ],
    ],

    'asset_manager'   => [
        'resolver_configs' => [
            'paths' => [
@@ -408,7 +439,7 @@ return [
        'strategies'               => [
            'ViewJsonStrategy', // register JSON renderer strategy
            'ViewCsvStrategy', // register CSV renderer strategy
            'ViewXmlStrategy', // register XML renderer strategy
//            'ViewXmlStrategy', // register XML renderer strategy
            //            'ViewFeedStrategy', // register Feed renderer strategy
        ],
    ],
+40 −12
Changes for config/unicaen-app.global.php.dist: 40 added lines, 12 removed lines.
Original line number Diff line number Diff line
@@ -2,31 +2,59 @@
/**
 * Configuration globale du module UnicaenApp.
 *
 * If you have a ./config/autoload/ directory set up for your project,
 * drop this config file in it and change the values as you wish.
 * Copiez ce fichier dans le répertoire "config/autoload" de l'application,
 * enlevez l'extension ".dist" et adaptez son contenu à vos besoins.
 */
$settings = array(
return [
    'unicaen-app' => [

        /**
         * Informations concernant cette application
         */
    'app_infos' => array(
        'app_infos' => [
            'nom'     => "NomDeVotreApplication",
            'desc'    => "Description succincte de votre application",
            'version' => "0.0.1",
        'date'    => "19/04/2013",
        'contact' => array('mail' => "dsi.applications@unicaen.fr", /*'tel' => "01 02 03 04 05"*/),
            'date'    => "07/11/2017",
            'contact' => ['mail' => "dsi.applications@unicaen.fr", /*'tel' => "01 02 03 04 05"*/],
            'mentionsLegales'        => "http://www.unicaen.fr/acces-direct/mentions-legales/",
            'informatiqueEtLibertes' => "http://www.unicaen.fr/acces-direct/informatique-et-libertes/",
    ),
        ],

        /**
         * Période d'exécution de la requête de rafraîchissement de la session utilisateur, en millisecondes.
         */
        'session_refresh_period' => 0, // 0 <=> aucune requête exécutée
);

        /**
 * You do not need to edit below this line
         * Paramètres de fonctionnement LDAP.
         */
return array(
    'unicaen-app' => $settings,
);
 No newline at end of file
//        'ldap' => [
//            'dn' => [
//                'UTILISATEURS_BASE_DN'                  => 'ou=people,dc=unicaen,dc=fr',
//                'UTILISATEURS_DESACTIVES_BASE_DN'       => 'ou=deactivated,dc=unicaen,dc=fr',
//                'GROUPS_BASE_DN'                        => 'ou=groups,dc=unicaen,dc=fr',
//                'STRUCTURES_BASE_DN'                    => 'ou=structures,dc=unicaen,dc=fr',
//            ],
//            'filters' => [
//                'LOGIN_FILTER'                          => '(supannAliasLogin=%s)',
//                'UTILISATEUR_STD_FILTER'                => '(|(uid=p*)(&(uid=e*)(eduPersonAffiliation=student)))',
//                'CN_FILTER'                             => '(cn=%s)',
//                'NAME_FILTER'                           => '(cn=%s*)',
//                'UID_FILTER'                            => '(uid=%s)',
//                'NO_INDIVIDU_FILTER'                    => '(supannEmpId=%08s)',
//                'AFFECTATION_FILTER'                    => '(&(uid=*)(eduPersonOrgUnitDN=%s))',
//                'AFFECTATION_CSTRUCT_FILTER'            => '(&(uid=*)(|(ucbnSousStructure=%s;*)(supannAffectation=%s;*)))',
//                'LOGIN_OR_NAME_FILTER'                  => '(|(supannAliasLogin=%s)(cn=%s*))',
//                'MEMBERSHIP_FILTER'                     => '(memberOf=%s)',
//                'AFFECTATION_ORG_UNIT_FILTER'           => '(eduPersonOrgUnitDN=%s)',
//                'AFFECTATION_ORG_UNIT_PRIMARY_FILTER'   => '(eduPersonPrimaryOrgUnitDN=%s)',
//                'ROLE_FILTER'                           => '(supannRoleEntite=[role={SUPANN}%s][type={SUPANN}%s][code=%s]*)',
//                'PROF_STRUCTURE'                        => '(&(eduPersonAffiliation=teacher)(eduPersonOrgUnitDN=%s))',
//                'FILTER_STRUCTURE_DN'		            => '(%s)',
//                'FILTER_STRUCTURE_CODE_ENTITE'	        => '(supannCodeEntite=%s)',
//                'FILTER_STRUCTURE_CODE_ENTITE_PARENT'   => '(supannCodeEntiteParent=%s)',
//            ],
//        ],
    ],
];
+63 −17
Changes for src/UnicaenApp/Mapper/Ldap/AbstractMapper.php: 63 added lines, 17 removed lines.
Original line number Diff line number Diff line
<?php

namespace UnicaenApp\Mapper\Ldap;

use Zend\Ldap\Dn;
use Zend\Ldap\Filter\AbstractFilter;
use Zend\Ldap\Ldap;
use UnicaenApp\Exception\RuntimeException;

@@ -16,14 +19,21 @@ abstract class AbstractMapper
     */
    protected $ldap;

    /**
     * @var array
     */
    protected $config;

    /**
     * Constructeur.
     *
     * @param Ldap  $ldap Objet d'accès à l'annuaire LDAP
     * @param array $config
     */
    public function __construct(Ldap $ldap = null)
    public function __construct(Ldap $ldap = null, array $config = [])
    {
        $this->setLdap($ldap);
        $this->setConfig($config);
    }

    /**
@@ -53,24 +63,58 @@ abstract class AbstractMapper
    public function setLdap(Ldap $ldap = null)
    {
        $this->ldap = $ldap;

        return $this;
    }

    /**
     * @return array
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * @param array $config
     * @return AbstractMapper
     */
    public function setConfig($config)
    {
        $this->config = $config;

        return $this;
    }

    /**
     * @param string $name
     * @param string $category
     * @return string
     */
    public function configParam($category, $name)
    {
        if (empty($this->config[$category][$name])) {
            throw new RuntimeException("Le tableau de config doit fournir une valeur valide pour le paramètre ['$category']['$name']");
        }

        return $this->config[$category][$name];
    }

    /**
     * Cherche une entrée dans l'annuaire LDAP selon un filtre puis parcourt récursivement le résultat trouvé
     * pour remplacer tout array qui ne contient qu'une seule valeur par cette valeur.
     *
     * @param  string|Zend_Ldap_Filter_Abstract|array $filter
     * @param  string|Zend_Ldap_Dn|null               $basedn
     * @param string|AbstractFilter|array $filter
     * @param string                      $baseDn
     * @param array                       $attributes
     * @param string|null                 $sort
     * @param  integer                                $scope
     * @param int                         $scope
     * @return array
     */
    public function searchSimplifiedEntry($filter, $baseDn = null, array $attributes = array(), $sort = null, $scope = Ldap::SEARCH_SCOPE_SUB)
    public function searchSimplifiedEntry($filter, $baseDn = null, array $attributes = [], $sort = null, $scope = Ldap::SEARCH_SCOPE_SUB)
    {
        if (!$attributes) {
            $attributes = $this->getAttributes() ?: array('*');
            $attributes = $this->getAttributes() ?: ['*'];
        }
        $entries = $this->getLdap()->searchEntries($filter, $baseDn, $scope, $attributes, $sort);
        if (count($entries) > 1) {
@@ -80,6 +124,7 @@ abstract class AbstractMapper
            return null;
        }
        $entry = $entries[0];

        return self::simplifiedEntry($entry);
    }

@@ -87,22 +132,23 @@ abstract class AbstractMapper
     * Cherche des entrées dans l'annuaire LDAP selon un filtre puis parcourt récursivement les entrées trouvées
     * pour remplacer tout array qui ne contient qu'une seule valeur par cette valeur.
     *
     * @param  string|Zend_Ldap_Filter_Abstract|array $filter
     * @param  string|Zend_Ldap_Dn|null               $basedn
     * @param  string|AbstractFilter|array $filter
     * @param  string|Dn|null              $basedn
     * @param  array                       $attributes
     * @param  string|null                 $sort
     * @param  integer                     $scope
     * @return array
     */
    public function searchSimplifiedEntries($filter, $basedn = null, array $attributes = array(), $sort = null, $scope = Ldap::SEARCH_SCOPE_SUB)
    public function searchSimplifiedEntries($filter, $basedn = null, array $attributes = [], $sort = null, $scope = Ldap::SEARCH_SCOPE_SUB)
    {
        if (!$attributes) {
            $attributes = $this->getAttributes() ?: array('*');
            $attributes = $this->getAttributes() ?: ['*'];
        }
        $entries = $this->getLdap()->searchEntries($filter, $basedn, $scope, $attributes, $sort);
        foreach ($entries as $i => $entry) {
            $entries[$i] = self::simplifiedEntry($entry);
        }

        return $entries;
    }

@@ -111,11 +157,13 @@ abstract class AbstractMapper
     * qu'une seule valeur par cette valeur.
     *
     * @param array $entry
     * @param array $returnAttribs
     * @param array $omitAttribs
     * @return array Le tableau "simplifié"
     */
    static public function simplifiedEntry(array $entry, array $returnAttribs = array(), array $omitAttribs = array())
    static public function simplifiedEntry(array $entry, array $returnAttribs = [], array $omitAttribs = [])
    {
        $return = array();
        $return = [];

        foreach ($entry as $attr => $value) {
            if (($returnAttribs && !in_array($attr, $returnAttribs)) || ($omitAttribs && in_array($attr, $omitAttribs))) {
@@ -124,12 +172,10 @@ abstract class AbstractMapper
            if (is_array($value)) {
                if (count($value) > 1) {
                    $return[$attr] = self::simplifiedEntry($value);
                } else {
                    $return[$attr] = count($value) === 1 ? $value[0] : [];
                }
                else {
                    $return[$attr] = count($value) === 1 ? $value[0] : array();
                }
            }
            else {
            } else {
                $return[$attr] = $value;
            }
        }
+51 −0
Changes for src/UnicaenApp/Mapper/Ldap/AbstractMapperFactory.php: 51 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

namespace UnicaenApp\Mapper\Ldap;

use UnicaenApp\Options\ModuleOptions;
use Zend\Ldap\Ldap;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

/**
 * Classe abstraite des constructeurs de mapper.
 *
 * @author Unicaen
 */
abstract class AbstractMapperFactory implements FactoryInterface
{
    /**
     * @var string Classe du mapper à instancier.
     */
    protected $mapperClass;

    /**
     * Create service
     *
     * @param ServiceLocatorInterface $serviceLocator
     * @return static
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        /** @var ModuleOptions $ldapParams */
        $ldapParams = $serviceLocator->get('unicaen-app_module_options');
        $ldapConfig = $ldapParams->getLdap();

        $className = $this->mapperClass;

        return new $className($this->createLdap($ldapConfig), $ldapConfig);
    }

    /**
     * @param array $ldapConfig
     * @return Ldap
     */
    protected function createLdap(array $ldapConfig)
    {
        $ldapConnectionParams = isset($ldapConfig['connection']['default']['params']) ?
            $ldapConfig['connection']['default']['params'] :
            [];

        return new Ldap($ldapConnectionParams);
    }
}
+27 −20
Changes for src/UnicaenApp/Mapper/Ldap/Group.php: 27 added lines, 20 removed lines.
Original line number Diff line number Diff line
<?php

namespace UnicaenApp\Mapper\Ldap;

use DateTime;
use UnicaenApp\Exception\LogicException;
use UnicaenApp\Exception\RuntimeException;
use UnicaenApp\Entity\Ldap\Group as LdapGroupModel;
use UnicaenApp\Mapper\Ldap\Group as GroupMapper;
use Zend\Ldap\Exception\LdapException;

/**
 * Classe regroupant les opérations de recherche de groupes dans l'annuaire LDAP.
 *
 * @author Bertrand GAUTHIER <bertrand.gauthier@unicaen.fr>
 * @author Unicaen
 */
class Group extends AbstractMapper
{
    const GROUPS_BASE_DN = 'ou=groups,dc=unicaen,dc=fr';
    const CN_FILTER      = '(cn=%s)';
    
    /**
     * Retourne la liste des attributs LDAP remontés dans les résultats de recherches.
     * NB: l'attribut 'dn' est forcément inclus.
@@ -23,7 +24,7 @@ class Group extends AbstractMapper
     */
    public function getAttributes()
    {
        return array('*');
        return ['*'];
    }

    /**
@@ -37,14 +38,14 @@ class Group extends AbstractMapper
        $filter = '(objectClass=*)';
        try {
            $entry = $this->searchSimplifiedEntry($filter, $dn);//, array(), null, \Zend\Ldap\Ldap::SEARCH_SCOPE_BASE);
        }
        catch (\Zend\Ldap\Exception\LdapException $le) {
        } catch (LdapException $le) {
            // entrée introuvable
            $entry = null;
        }
        if ($entry) {
            $entry = new LdapGroupModel($entry);
        }

        return $entry;
    }

@@ -56,12 +57,13 @@ class Group extends AbstractMapper
     */
    public function findAllByDn($dn)
    {
        $entries = array();
        $entries = [];
        foreach ($dns = (array)$dn as $dn) {
            if (($entry = $this->findOneByDn($dn))) {
                $entries[$entry->getDn()] = $entry;
            }
        }

        return $entries;
    }

@@ -73,11 +75,12 @@ class Group extends AbstractMapper
     */
    public function findOneByCn($cn)
    {
        $filter = sprintf(self::CN_FILTER, $cn);
        $entry = $this->searchSimplifiedEntry($filter, self::GROUPS_BASE_DN);
        $filter = sprintf($this->configParam('filters', 'CN_FILTER'), $cn);
        $entry = $this->searchSimplifiedEntry($filter, $this->configParam('dn', 'GROUPS_BASE_DN'));
        if ($entry) {
            $entry = new LdapGroupModel($entry);
        }

        return $entry;
    }

@@ -90,12 +93,13 @@ class Group extends AbstractMapper
    public function findAllByCn($cn)
    {
        $cn = (array)$cn;
        $filter = '(|' . implode('', array_fill(0, count($cn), self::CN_FILTER)) . ')';
        $filter = '(|' . implode('', array_fill(0, count($cn), $this->configParam('filters', 'CN_FILTER'))) . ')';
        $filter = vsprintf($filter, $cn);
        $entries = $this->searchSimplifiedEntries($filter, self::GROUPS_BASE_DN);
        $entries = $this->searchSimplifiedEntries($filter, $this->configParam('dn', 'GROUPS_BASE_DN'));
        if ($entries) {
            $entries = LdapGroupModel::getInstances($entries);
        }

        return $entries;
    }

@@ -107,10 +111,11 @@ class Group extends AbstractMapper
    public function findAll()
    {
        $filter = '(objectClass=*)';
        $entries = $this->searchSimplifiedEntries($filter, self::GROUPS_BASE_DN);
        $entries = $this->searchSimplifiedEntries($filter, $this->configParam('dn', 'GROUPS_BASE_DN'));
        if ($entries) {
            $entries = LdapGroupModel::getInstances($entries);
        }

        return $entries;
    }

@@ -118,21 +123,22 @@ class Group extends AbstractMapper
     * Filtre des groupes pour ne retenir que ceux dont la date de fin est postérieure à une date d'observation.
     *
     * @param             array            (Group)|Group $groups Groupes à filtrer
     * @param \DateTime $dateObservation Date d'observation (date du jour si absente),
     * si la date de fin du groupe est antérieure à la date d'observation, le groupe n'est pas retenu
     * @param \UnicaenApp\Mapper\Ldap\Group $mapper Mapper de recherche des groupes dans l'annnuaire LDAP, requis si
     * @param DateTime    $dateObservation Date d'observation (date du jour si absente),
     *                                     si la date de fin du groupe est antérieure à la date d'observation, le
     *                                     groupe n'est pas retenu
     * @param GroupMapper $mapper          Mapper de recherche des groupes dans l'annnuaire LDAP, requis si
     *                                     les groupes sont spécifiés par leur CN
     * @return array(dn=>Group) Groupes retenus
     */
    public static function filterGroupsByDateFin($groups, \DateTime $dateObservation = null, \UnicaenApp\Mapper\Ldap\Group $mapper = null)
    public static function filterGroupsByDateFin($groups, DateTime $dateObservation = null, GroupMapper $mapper = null)
    {
        if (!is_array($groups)) {
            $groups = array($groups);
            $groups = [$groups];
        }
        if (null === $dateObservation) {
            $dateObservation = new \DateTime();
            $dateObservation = new DateTime();
        }
        $filteredGroups = array();
        $filteredGroups = [];
        foreach ($groups as $group) {
            if (!is_object($group)) {
                if (!$mapper) {
@@ -149,6 +155,7 @@ class Group extends AbstractMapper
            }
            $filteredGroups[$group->getDn()] = $group;
        }

        return $filteredGroups;
    }
}
Loading