Rajout SAML

Possibilité de s'authentifier à l'admin ou aux pages via une connexion
SSO à l'aide de SimpleSAMLPHP.
This commit is contained in:
Jérôme LAFFORGUE 2017-04-20 13:29:34 +02:00
parent 724133f6ae
commit bf87ac9438
8 changed files with 176 additions and 14 deletions

View file

@ -61,3 +61,6 @@ if (is_file(CONF_FILENAME)) {
require_once __DIR__ . '/i18n.php';
// Smarty
require_once __DIR__ . '/smarty.php';
// SAML
require_once __DIR__ . '/saml.php';

116
app/inc/saml.php Normal file
View file

@ -0,0 +1,116 @@
<?php
/**
* Fichier de configuration pour l'authentification de Framadate avec SimpleSAMLPHP
* Il est indispensable d'avoir configuré un Service Provider au préalable
*
*/
/**
* Chemin de la libraire PHPSimpleSAML
*/
const SAML_PATH = '/home/framadate/www/simplesamlphp/lib/_autoload.php';
/**
* Active la connexion SSO
*/
const SAML_SSO_ACTIVE = true;
/**
* Prérempli les coordonées (nom / email) dans le formulaire de création d'un sondage
*/
const AUTO_COMPLETE_USER = true;
/**
* Lise des pages que l'on veut sécuriser
*/
$hashPagesToSecure = array(
'front' => array(
'create_poll' => true, // Front - Création d'un sondage
'find_polls' => true, // Front - Ou sont mes sondages
'studs' => false, // Front - Réponse à un sondage
'adminstuds' => true, // Front - Edition d'un sondage
'exportcsv' => false, // Front - export CSV d'un sondage
),
'admin' => array(
'admin/index' => true, // Administration - Accueil
'admin/polls' => true, // Administration - Sondages
'admin/purge' => true, // Administration - Purge
'admin/logs' => true, // Administration - Historique
'admin/migration' => true, // Administration - Migration
'admin/check' => true, // Administration - Vérifications de l'installation
)
);
/**
* Champs de l'AD à mapper avec SAML
*/
$hashConfigFieldsMapping = array(
'name' => 'cn', // Nom complet
'email' => 'mail' // Adresse mail
);
/**
* Attributs de l'AD qui sont authorisés à se connecter aux différentes parties de Framadate
*/
$hashGroupAuthorized = array(
'front' => array(
'resMemberOf' => 'Framadate', // Valeurs à remplacer
),
'admin' => array(
'resMemberOf' => 'FramadateAdmin' // Valeurs à remplacer
)
);
if(SAML_SSO_ACTIVE == true){
if(!file_exists(SAML_PATH)){
die('Impossible de charger la librairie SimplePHPSAML');
}
require_once(SAML_PATH);
//On parcourt les pages des sections (front / back)
foreach($hashPagesToSecure as $strSection => $hashPages){
// On vérifie si la page courante doit-être sécurisée
foreach($hashPages as $strPageName => $boolSecure){
// SI page courante doit-être sécurisé on vérifie l'accès
if(strpos($_SERVER['SCRIPT_FILENAME'], $strPageName) !== false && $boolSecure == true){
$objAuthSaml = new SimpleSAML_Auth_Simple('framadate-sp');
$objAuthSaml->requireAuth();
$hashAuthAttributes = $objAuthSaml->getAttributes();
// On récupère le nom et l'email de l'utilisateur
$strUserName = array_shift($hashAuthAttributes[$hashConfigFieldsMapping['name']]);
$strUserEmail = array_shift($hashAuthAttributes[$hashConfigFieldsMapping['email']]);
// On assigne à Smarty l'URL de déconnexion + l'adresse email pour retrouver les sondages
$strHttpPrepfix = (substr($_SERVER['SCRIPT_URI'], 0, 5) == 'https')? 'https' : 'http';
$smarty->assign('saml_logout', $objAuthSaml->getLogoutURL($strHttpPrepfix.'://'.$_SERVER['HTTP_HOST']));
$smarty->assign('email', $strUserEmail);
// Si on est dans la section (front / back), on regarde si l'utilisateur est bien autorisé
if(isset($hashGroupAuthorized[$strSection])) {
foreach ($hashGroupAuthorized[$strSection] as $strAttribute => $strValue) {
if (!in_array(trim($strValue), $hashAuthAttributes[$strAttribute])) {
header('Location:'.$strHttpPrepfix.'://'.$_SERVER['HTTP_HOST'].'/forbidden.php');
break;
}
}
}
// Si il s'agit d'un nouveau sondage on affecte les infos du user en session
if(strpos($_SERVER['SCRIPT_FILENAME'], 'create_poll') !== FALSE && AUTO_COMPLETE_USER == true){
if(isset($_SESSION['form']) && empty($_SESSION['form']->id)){
$_SESSION['form']->admin_name = $strUserName;
$_SESSION['form']->admin_mail = $strUserEmail;
}
}
break;
}
}
}
}

30
forbidden.php Normal file
View file

@ -0,0 +1,30 @@
<?php
/**
* This software is governed by the CeCILL-B license. If a copy of this license
* is not distributed with this file, you can obtain one at
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
*
* Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
* Authors of Framadate/OpenSondage: Framasoft (https://github.com/framasoft)
*
* =============================
*
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
* ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
* http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
*
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
*/
use Framadate\Utils;
include_once __DIR__ . '/app/inc/init.php';
if (!is_file(CONF_FILENAME)) {
header(('Location: ' . Utils::get_server_name() . 'admin/check.php'));
exit;
}
$smarty->display('forbidden.tpl');

View file

@ -38,7 +38,8 @@
"Search": "Search",
"Creation date:": "Creation date:",
"Caption": "Caption",
"ASTERISK": "*"
"ASTERISK": "*",
"Disconnect" : "Disconnect"
},
"Date": {
"dd/mm/yyyy": "yyyy-mm-dd",
@ -323,8 +324,7 @@
"Purged:": "Purged:",
"Confirm removal of the poll": "Confirm removal of the poll ",
"polls in the database at this time": "polls in the database at this time",
"Purge the polls": "Purge the polls",
"Installation": "Installation"
"Purge the polls": "Purge the polls"
},
"FindPolls": {
"Send me my polls": "Send me my polls",
@ -334,6 +334,7 @@
"Have a good day!": "Have a good day!",
"PS: this email has been sent because you or someone else asked to get back the polls created with your email address.": "PS: this email has been sent because you or someone else asked to get back the polls created with your email address.",
"If you weren't the source of this action and if you think this is an abuse of the service, please notify the administrator on %s.": "If you weren't the source of this action and if you think this is an abuse of the service, please notify the administrator on %s."
},
"Mail": {
"Poll's participation: %s": "Poll participation: %s",
@ -406,10 +407,6 @@
"Poll id already used": "Identifier is already used",
"You can't select more than %d dates": "You can't select more than %d dates",
"Can't create the config.php file in '%s'.": "Can't create the config.php file in '%s'.",
"Failed to delete all comments": "Failed to delete all comments",
"Failed to delete all votes": "Failed to delete all votes",
"Failed to delete the comment": "Failed to delete the comment",
"Failed to delete the poll": "Failed to delete the poll",
"Can't create an empty column.": "Can't create an empty column."
},
"Check": {
@ -418,7 +415,6 @@
"PHP version %s is enough (needed at least PHP %s).": "PHP version %s is enough (needed at least PHP %s).",
"You need to enable the PHP Intl extension.": "You need to enable the PHP Intl extension.",
"PHP Intl extension is enabled.": "PHP Intl extension is enabled.",
"The template compile directory (%s) doesn't exist in \"%s\". Retry the installation process.": "The template compile directory (%s) doesn't exist in \"%s\". Retry the installation process.",
"The template compile directory (%s) is not writable.": "The template compile directory (%s) is not writable.",
"The template compile directory (%s) is writable.": "The template compile directory (%s) is writable.",
"The config file directory (%s) is not writable and the config file (%s) dos not exists.": "The config file directory (%s) is not writable and the config file (%s) dos not exists.",

View file

@ -38,7 +38,8 @@
"Search": "Chercher",
"Creation date:": "Date de création :",
"Caption": "Légende",
"ASTERISK": "*"
"ASTERISK": "*",
"Disconnect": "Déconnexion"
},
"Date": {
"dd/mm/yyyy": "jj/mm/aaaa",
@ -323,8 +324,7 @@
"Purged:": "Purgés :",
"Confirm removal of the poll": "Confirmer la suppression du sondage",
"polls in the database at this time": "sondages dans la base actuellement",
"Purge the polls": "Purger les sondages",
"Installation": "Installation"
"Purge the polls": "Purger les sondages"
},
"FindPolls": {
"Send me my polls": "Envoyer mes sondages",
@ -418,7 +418,6 @@
"PHP version %s is enough (needed at least PHP %s).": "Version de PHP %s suffisante (nécessite au moins PHP %s).",
"You need to enable the PHP Intl extension.": "Vous devez activer l'extension PHP Intl.",
"PHP Intl extension is enabled.": "L'extension PHP Intl est activée.",
"The template compile directory (%s) doesn't exist in \"%s\". Retry the installation process.": "Le dossier de compilation des templates (%s) n'existe pas dans \"%s\". Essayez de relancer l'installation.",
"The template compile directory (%s) is not writable.": "Le dossier de compilation des templates (%s) n'est pas accessible en écriture.",
"The template compile directory (%s) is writable.": "Le dossier de compilation des templates (%s) est accessible en écriture.",
"The config file directory (%s) is not writable and the config file (%s) dos not exists.": "Le dossier du fichier de configuration (%s) n'est pas accessible en écriture et le fichier de configuration (%s) n'existe pas.",

View file

@ -10,7 +10,7 @@
<div class="form-group">
<div class="input-group">
<label for="mail" class="input-group-addon">{__('Generic', 'Your email address')}</label>
<input type="email" class="form-control" id="mail" name="mail" autofocus>
<input type="email" class="form-control" id="mail" name="mail" value="{$email}" autofocus>
</div>
</div>
</div>

12
tpl/forbidden.tpl Normal file
View file

@ -0,0 +1,12 @@
{extends file='page.tpl'}
{block name=main}
<div class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Problème d'accès :</span>
C'est embarassant... Il semblerait pour que vous n'ayez pas le droit d'accéder à cette partie... Pour plus d'informations, veuillez contacter votre administrateur.
</div>
<a href="/"><span class="glyphicon glyphicon-arrow-left aria-hidden="true"></span> Retour à l'accueil</a>
{/block}

View file

@ -20,6 +20,12 @@
</a>
</h1>
{if !empty($title)}<h2 class="lead col-xs-12"><i>{$title|html}</i></h2>{/if}
{if $saml_logout}
<a href="{$saml_logout}" class="pull-right" style="margin-top: -60px;"><span class="glyphicon glyphicon-log-out"></span> {__('Generic', 'Disconnect')}</a>
{/if}
<div class="trait col-xs-12" role="presentation"></div>
</header>
<main role="main">
<main role="main">