Commit a2e99e87 authored by Patrick Barroca's avatar Patrick Barroca 🐧

Merge branch 'dev#106075_explo_france_connect_avec_identifiant_gpsea' into 'master'

Dev#106075 explo france connect avec identifiant gpsea

See merge request !3432
parents d4f91f5b 8fbf9e0a
Pipeline #9676 passed with stage
in 46 minutes and 57 seconds
......@@ -16,6 +16,9 @@
[submodule "library/matomo-php-tracker"]
path = library/matomo-php-tracker
url = https://git.afi-sa.net/afi/matomo-php-tracker.git
[submodule "library/php-jwt"]
path = library/php-jwt
url = https://git.afi-sa.net/afi/php-jwt.git
[submodule "library/phpseclib"]
path = library/phpseclib
url = https://git.afi-sa.net/afi/phpseclib.git
......
'106075' =>
['Label' => $this->_('Serveurs d\'identité tiers'),
'Desc' => $this->_('Bokeh permet aux abonnés d\'associer leurs comptes FranceConnect, Google et plus généralement OpenId à leur compte Bokeh.'),
'Image' => '',
'Video' => 'https://youtu.be/sRC3dO70ezI',
'Category' => $this->_('Compte lecteur'),
'Right' => function($feature_description, $user) {return true;},
'Wiki' => 'http://wiki.bokeh-library-portal.org/index.php?title=FranceConnect_OpenId',
'Test' => '',
'Date' => '2020-02-27'],
\ No newline at end of file
- ticket #106075 : Compte lecteur : Ajout de la prise en charge de serveurs d'identité tiers France Connect, Google et plus généralement OpenId
\ No newline at end of file
<?php
/**
* Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH 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.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Admin_IdentityProvidersController extends ZendAfi_Controller_Action {
public function getPlugins() {
return ['ZendAfi_Controller_Plugin_ResourceDefinition_IdentityProvider',
'ZendAfi_Controller_Plugin_Manager_IdentityProvider'];
}
public function indexAction() {
parent::indexAction();
$this->view->titre = $this->_('Fournisseurs d\'identité');
}
}
?>
\ No newline at end of file
<?php
echo $this
->tag('div',
$this->tag('dl',
$this->tag('dt', $this->_('Url de retour :'))
. $this->tag('dd', $this->provider->getCallBackUrl())),
['class' => 'content_edit_head']);
echo $this->renderForm($this->form);
<?php
echo $this->Button_New((new Class_Entity())
->setText($this->_('Ajouter un fournisseur d\'identité')));
echo $this
->renderTable((new Class_TableDescription('providers'))
->addColumn($this->_('Libellé'), ['attribute' => 'label'])
->addColumn($this->_('Url de retour'), ['attribute' => 'callback_url'])
->addColumn($this->_('Actif ?'),
function($model)
{
return $model->getActive()
? $this->_('Oui')
: $this->_('Non');
})
->addRowAction(function($model) { return $this->renderPluginsActions($model); }),
$this->providers);
......@@ -1225,6 +1225,26 @@ class AbonneController extends ZendAfi_Controller_Action {
}
public function associatedProvidersAction() {
$this->view->titre = $this->_('Mes comptes associés');
$this->view->identities = Class_User_Identity::findIdentitiesForActiveProviders($this->_user);
}
public function dissociateProviderAction() {
if ((!$identity = Class_User_Identity::find((int)$this->_getParam('id')))
|| $this->_user->getId() != $identity->getUserId()) {
$this->_helper->notify($this->_('Impossible de dissocier une identité inconnue'));
return $this->_redirectToUrlOrReferer('/');
}
$identity->dissociate();
$this->_helper->notify($this->_('Votre compte a été dissocié de %s',
$identity->getProviderLabel()));
$this->_redirectToUrlOrReferer('/');
}
public function unlinkCardAction() {
return $this->_unlinkCard(['parent_id' => $this->_user->getId(),
'child_id' => (int)$this->_getParam('id')],
......
<?php
/**
* Copyright (c) 2012, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH 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.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class IdentityProvidersController extends ZendAfi_Controller_Action {
public function authenticateAction() {
if (!Class_AdminVar::isIdentityProvidersEnabled())
throw new Zend_Controller_Action_Exception($this->_('Désolé, cette page n\'existe pas'), 404);
if (!$provider = Class_IdentityProvider::find((int)$this->_getParam('id'))) {
$this->_helper->notify($this->_('Impossible de s\'identifier à un service inconnu'));
return $this->_redirectToReferer();
}
if (!$url = $provider->loginUrl($this->_getParam('redirect', ''))) {
$this->_helper->notify($this->_('Impossible de déterminer l\'url de login pour %s',
$provider->getLabel()));
return $this->_redirectToReferer();
}
$provider->setLoginSuccessRedirectUrl($this->_getReferer());
$this->_redirect($url);
}
public function logoutAction() {
if (!$provider = Class_IdentityProvider::find((int)$this->_getParam('id')))
return $this->_redirectToReferer();
$this->_redirect($provider->logoutUrl());
}
}
<?php
$this->openBoite($this->titre);
echo $this->abonne_AssociatedProvidersBoard($this->identities);
$this->closeBoite();
echo $this->abonne_RetourFiche();
......@@ -2,6 +2,7 @@
$action = ['controller' => 'auth',
'action' => 'ajax-login'];
if ($this->isPopup())
$action['render'] = 'popup';
......@@ -12,3 +13,6 @@ echo $this->Widget_Login(new Class_Entity(array_merge(['Preferences' => $this->
'action' => $this->url($action, null, true)
. ($this->location ? '?location=' . $this->location : '')]])));
echo $this->identityProviders();
<?php
$url_action = $this->form_action ?
$this->form_action : $this->url(['controller' => 'auth',
'action' => ('boite-login'),
'id_module' => $this->id_module]);
echo $this->Widget_Login(
new Class_Entity(array_merge(['Preferences' => $this->preferences],
['FormOptions' => ['data' => array_merge($this->preferences,
......@@ -6,8 +10,4 @@ echo $this->Widget_Login(
'service' => $this->service,
'id_notice' => $this->id_notice]),
'action' => $this->url(['controller' => 'auth',
'action' => ($this->form_action
? $this->form_action
: 'boite-login'),
'id_module' => $this->id_module])]])));
'action' => $url_action]])));
<?php
$this->openBoite($this->title);
if ($this->message)
echo $this->tag('p', $this->message);
include('boite-login.phtml');
$this->closeBoite();
?>
......@@ -42,7 +42,7 @@ class Telephone_AuthController extends AuthController {
$this->view->service = $service;
$this->view->titre = $this->view->_('Connexion');
$strategy = Auth_Strategy_Abstract::strategyForController($this);
$strategy = Class_Auth_Strategy::newFor($this);
$strategy->setDefaultUrl($redirect);
$strategy->processLogin();
$this->_loginCommon();
......@@ -72,7 +72,6 @@ class Telephone_AuthController extends AuthController {
}
protected function _loginCommon() {
$form = $this->_getFormLogin()->setAction($this->view->url());
if ($this->_request->isPost()) {
......@@ -114,4 +113,3 @@ class Telephone_AuthController extends AuthController {
return $form;
}
}
?>
\ No newline at end of file
<?php
(new Class_Migration_BirthdateFormatChanges())->run();
\ No newline at end of file
(new Class_Migration_BirthdateFormatChanges())->run();
<?php
Zend_Registry::get('sql')->query('CREATE TABLE if not exists `identity_provider` ( '
. 'id int(11) unsigned not null auto_increment,'
. 'type varchar(255),'
. 'protocol varchar(255),'
. 'active boolean default true,'
. 'label varchar(255) not null,'
. 'config text,'
. 'primary key (id)'
. ') engine=MyISAM default charset=utf8');
Zend_Registry::get('sql')->query('CREATE TABLE if not exists `user_identities` ( '
. 'id int(11) unsigned not null auto_increment,'
. 'provider_id int(11) unsigned not null,'
. 'user_id int(11) not null,'
. 'identifier varchar(255) not null,'
. 'primary key (id),'
. 'key provider_id (provider_id),'
. 'key user_id (user_id)'
. ') engine=MyISAM default charset=utf8');
......@@ -135,7 +135,8 @@ class Class_AdminVarLoader extends Storm_Model_Loader {
'file-manager' => $this->_getFileManagerVars(),
'federation-reviews' => $this->_getFederationVars(),
'usergroup-agenda' => $this->_getRendezVousVars(),
'templating' => $this->_getTemplatingVars()
'templating' => $this->_getTemplatingVars(),
'identity-providers' => $this->_getIdentityProvidersVars(),
];
}
......@@ -534,6 +535,13 @@ class Class_AdminVarLoader extends Storm_Model_Loader {
}
protected function _getIdentityProvidersVars() {
return
['ENABLE_IDENTITY_PROVIDERS' => Class_AdminVar_Meta::newOnOff($this->_('Activer la gestion des fournisseurs d\'identité')),
];
}
public function allVarsValues() {
if (null !== static::$_all_vars_values)
return static::$_all_vars_values;
......@@ -1110,6 +1118,11 @@ class Class_AdminVarLoader extends Storm_Model_Loader {
public function isRendezVousEnabled() {
return Class_AdminVar::isModuleEnabled('ENABLE_RENDEZ_VOUS');
}
public function isIdentityProvidersEnabled() {
return Class_AdminVar::isModuleEnabled('ENABLE_IDENTITY_PROVIDERS');
}
}
......
<?php
/**
* Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH 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.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Auth_Cas {
public static function newFor($controller) {
$request = $controller->getRequest();
if (0 == strlen($request->getParam('service')))
return;
return Class_Users::hasIdentity()
? new Class_Auth_CasLogged($controller)
: new Class_Auth_CasNotLogged($controller);
}
}
trait Trait_Auth_CasAware {
protected $_server_url;
protected function _getServerUrl() {
return $this->_server_url
? $this->_server_url
: $this->_server_url = $this->_getParam('service');
}
protected function _urlServiceCas() {
if ($url_musicme = $this->_redirectMusicme())
return $url_musicme;
$ticket = (new Class_CasTicket())->getTicketForCurrentUser();
$queries = [];
$url_cas = array_merge(['query'=> '', 'path' => ''],
parse_url($this->_getServerUrl()));
parse_str($url_cas['query'], $queries);
$queries['ticket'] = $ticket;
$path = $url_cas['path'] ? $url_cas['path'] : '';
$scheme = $url_cas['scheme'] ? $url_cas['scheme'] : 'http';
return $scheme . '://' . $url_cas['host'] . $path . '?' . http_build_query($queries);
}
protected function _redirectMusicme() {
return (strpos($this->_getServerUrl(), 'musicme') !== false)
? Musicme_Config::getInstance()->getSsoUrl(Class_Users::getIdentity())
: null;
}
}
class Class_Auth_CasLogged extends Class_Auth_Logged {
use Trait_Auth_CasAware;
public function prepareLogin() {
$this->redirect_url = stristr($this->_getServerUrl(), 'deconnexion=ok')
? '/opac'
: $this->_urlServiceCas();
}
}
class Class_Auth_CasNotLogged extends Class_Auth_NotLogged {
use Trait_Auth_CasAware;
protected function _doOnLoginSuccess() {
$this->redirect_url = $this->_urlServiceCas();
}
}
<?php
/**
* Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH 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.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Auth_IdentityProvider {
public static function newFor($controller) {
$request = $controller->getRequest();
if (!$request->getParam('provider'))
return;
return Class_Users::hasIdentity()
? new Class_Auth_IdentityProviderLogged($controller)
: new Class_Auth_IdentityProviderNotLogged($controller);
}
}
class Class_Auth_IdentityProviderLogged extends Class_Auth_Logged {
use Trait_IdentityProviderAware;
public function logout() {
if (!$provider = $this->_getProvider())
return parent::logout();
$redirect_url = $provider->logoutUrl($this->_getProfilRedirectUrl());
$provider->clearRemoteLogin();
ZendAfi_Auth::getInstance()->clearIdentity();
$this->controller->redirect($redirect_url);
}
protected function _handleRedirect() {
if ((!$provider = $this->_getProvider())
|| !$provider->associate(Class_Users::getIdentity()))
return parent::_handleRedirect();
$this->setRedirectUrl(($url = $provider->loginSuccessRedirectUrl())
? $url
: $this->default_url);
return parent::_handleRedirect();
}
}
class Class_Auth_IdentityProviderNotLogged extends Class_Auth_NotLogged {
use Trait_IdentityProviderAware;
public function getPageTitle($view) {
return $this->_('Associer votre compte');
}
public function getMessage($view) {
if (!$provider = $this->_getProvider())
return parent::getMessage($view);
$message = ($name = $provider->getRemoteName())
? $this->_('Vous êtes connecté à %s en tant que %s.', $provider->getLabel(), $name)
: $this->_('Vous êtes connecté à %s.', $provider->getLabel());
if (!Class_Users::getIdentity())
$message .= ' ' . $this->_('Pour votre première connexion, veuillez saisir les identifiants de votre abonnement.');
return $message;
}
protected function _doOnLoginSuccess() {
if (!$provider = $this->_getProvider()) {
$this->controller->notify($this->_('Impossible d\'associer votre compte à un fournisseur inconnu'));
return parent::_doOnLoginSuccess();
}
if (!$provider->associate(Class_Users::getIdentity())) {
$this->controller->notify($this->_('L\'association de votre compte à %s a échoué',
$provider->getLabel()));
return parent::_doOnLoginSuccess();
}
$this->controller->notify($this->_('L\'association de votre compte à %s a réussi',
$provider->getLabel()));
if ($url = $provider->loginSuccessRedirectUrl())
$this->setRedirectUrl($url);
return parent::_doOnLoginSuccess();
}
protected function _clearRemoteLogins() {
// do not clear as we are meant to keep remote login
}
protected function _doOnLoginFail() {
$this->redirect_url = '';
}
public function getFormAction($id_module) {
return ($provider = $this->_getProvider())
? $provider->loginFormAction(parent::getFormAction($id_module))
: parent::getFormAction($id_module);
}
protected function _handleRedirect() {
if ((!$provider = $this->_getProvider()))
return parent::_handleRedirect();
if ($user = $provider->getRemotelyLoggedUser()) {
ZendAfi_Auth::getInstance()->logUser($user);
$this->redirect_url = ($url = $provider->loginSuccessRedirectUrl())
? $url
: $this->default_url;
}
return parent::_handleRedirect();
}
}
<?php
/**
* Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH 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.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Auth_Lectura extends Class_Auth_Strategy {
public static function newFor($controller) {
$request = $controller->getRequest();
return $request->getParam('lectura', false)
? new static($controller)
: null;
}
protected function _handlePost() {
$this->controller->getHelper('ViewRenderer')->setNoRender();
$response = $this->controller->getResponse();
$view = $this->controller->view;
$request = $this->controller->getRequest();
$response->setHeader('Content-Type', 'application/xml;charset=utf-8');
$login = $request->getPost('CAB');
$password = $request->getPost('PWD');
$response->setBody($this->getXmlResponse($view,
ZendAfi_Auth::getInstance()->authenticateLoginPassword($login, $password)));
return function() {};
}
protected function getXmlResponse($view, $is_success=true) {
return '<?xml version="1.0" encoding="UTF-8"?>'."\n".
$view->tag('libraryuserauth',
$view->tag('returncode', $is_success ? 'success':'error'),
['timestamp' => date('Ymd-his')]);
}
}
<?php
/**
* Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH 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.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Auth_Logged extends Class_Auth_Strategy {
public function getPageTitle($view) {
return isset($view->preferences['titre_connecte'])
? $view->preferences['titre_connecte']
: '';
}
}
<?php
/**
* Copyright (c) 2012-2019, Agence Française Informatique (AFI). All rights reserved.
*
* BOKEH 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.
*
* There are special exceptions to the terms and conditions of the AGPL as it
* is applied to this software (see README file).
*
* BOKEH 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 BOKEH; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
class Class_Auth_NotLogged extends Class_Auth_Strategy {
protected function _handlePost() {
$this->redirect_url = $this->default_url;
if (!$error = $this->controller->_authenticate())
return function() {
// login without associating remote identity should clear to prevent messing with remote ids afterwards
$this->_clearRemoteLogins();
return $this->_doOnLoginSuccess();
};
return function() use($error) {
$this->controller->notify($error);
return $this->_doOnLoginFail();
};
}
protected function _clearRemoteLogins() {
(new Class_IdentityProvider_Types)->clearRemoteLogin();