An error occurred while loading the file. Please try again.
-
Laurent authored8cbd2596
AuthController.php 26.29 KiB
<?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 AuthController extends ZendAfi_Controller_Action {
public function init() {
$this->view->locale = Zend_Registry::get('locale');
}
public function onPasswordNotSecure($message, $pattern) {
$this->_setParam('password_hint', $message)
->_setParam('pattern', $pattern)
->_forward('secure-password');
}
public function indexAction() {
$this->_redirect('/opac');
}
public function isLectura() {
return $this->_getParam('lectura', false);
}
public function isCasRequest() {
return strlen($this->getCasServerUrl())>0;
}
public function getCasServerUrl() {
return $this->_request->getParam('service');
}
public function getErrorMessages($error_code) {
$messages= [1 => $this->_('Veuillez saisir votre identifiant.'),
2 => $this->_('Identifiant inconnu.'),
4 => $this->_("Votre mail n'est pas renseigné dans votre compte lecteur. Merci de vous adresser à la bibliothèque pour récupérer votre mot de passe ou bien le remplacer par un nouveau.")];
if (isset($messages[$error_code]))
return $messages[$error_code];
return '';
}
public function notify($message) {
$this->_helper->notify($message);
}
public function getRedirectDefaultUrl() {
return $this->_request->getParam('redirect','/opac');
}
public function redirect($redirect_url) {
$this->_redirect($redirect_url);
}
public function _authenticate() {
$f = new Zend_Filter_StripTags();
$username = $f->filter($this->_request->getPost('username'));
$password = $f->filter($this->_request->getPost('password'));
if (empty($username))
return $this->view->_('Entrez votre identifiant S.V.P.');
if (empty($password))
return $this->view->_('Entrez votre mot de passe S.V.P.');
if (!ZendAfi_Auth::getInstance()->authenticateLoginPassword($username, $password))
return $this->view->_('Identifiant ou mot de passe incorrect.');
$user = Class_Users::getIdentity();
$this->_helper->trackEvent('authentification', 'connexion', 'utilisateur', $user->getId());
}
public function securePasswordAction() {
$this->_setupSecurePasswordForm();
}
protected function _setupSecurePasswordForm() {
$form = new ZendAfi_Form_SecurePassword();
$form->current_password->setValue($this->_request->getPost('password'));
$form->password_hint->setValue($this->_getParam('password_hint'));
$form->pattern->setValue($this->_getParam('pattern'));
$form
->secure_password
->addValidator(
(new Zend_Validate_Regex($this->_getParam('pattern')))
->setMessage($this->_getParam('password_hint'), Zend_Validate_Regex::NOT_MATCH));
$this->view->title = $this->_('Sécurisation du compte');
$this->view->message = $this->_('Vous vous connectez pour la première fois avec votre courriel. Vous devez modifier votre mot de passe pour sécuriser l\'accès par courriel.');
$this->view->password_hint = $this->_getParam('password_hint');
$this->view->form = $form;
return $form->setAction($this->view->url(['action' => 'do-secure-password']));
}
public function doSecurePasswordAction() {
$card = $this->_request->getPost('card');
$current_password = $this->_request->getPost('current_password');
$form = $this->_setupSecurePasswordForm();
if (!$form->isValid($this->_request->getPost()))
return $this->renderScript('auth/secure-password.phtml');
if (!ZendAfi_Auth::getInstance()->authenticateLoginPassword($card, $current_password)) {
$form->card->addError($this->_('Numéro de carte incorrect'));
return $this->renderScript('auth/secure-password.phtml');
}
$user = Class_Users::getIdentity();
$user->getFicheSIGB(); // init sigb infos
$user
->setPassword($this->_request->getPost('secure_password'))
->save();
$this->getHelper('notify')->bePopup();
$this->_helper->notify($this->_('Votre compte est sécurisé. Vous pouvez maintenant vous connecter avec votre courriel et votre nouveau mot de passe.'));
$this->_redirect('/');
}
//see http://www.jasig.org/cas/protocol#cas-uris
public function validateAction() {
$this->_forward('validate', 'cas-server');
}
public function loginAction() {
$this->view->preferences = $this->_loginPrefFromWidgetOrModule();
$redirect = $this->_getParam('redirect', '/opac');
$this->view->redirect = $redirect;
$service = $this->_getParam('service','');
$this->view->service = $service;
$this->view->titreAdd($this->view->_('Connexion'));
$this->view->title = Class_Users::getIdentity()
? $this->view->preferences['titre_connecte']
: $this->view->preferences['titre'];
$strategy = Auth_Strategy_Abstract::strategyForController($this);
$strategy->setDefaultUrl($redirect);
$strategy
->onLoginSuccess(function($user)
{
$user->registerNotificationsOn($this->getHelper('notify')->bePopup());
});
$strategy->processLogin();
$this->view->form_action = 'login';
}
public function ajaxLoginAction(){
$redirect = urldecode($this->_getParam('redirect'));
$location = urldecode($this->_getParam('location'));
$this->view->preferences = $this->_loginPrefFromWidgetOrModule();
Auth_Strategy_Abstract::strategyForController($this)
->disableRedirect()
->onLoginSuccess(function($user) use ($redirect, $location)
{
$user->registerNotificationsOn($this->getHelper('notify'));
$this->renderPopup($redirect, $location);
})
->onLoginFail(function() use ($redirect, $location)
{
$this->renderPopup($this->view->url(['action' => 'popup-login'])
. '?redirect=' . urlencode($redirect)
. ($location ? '&location=' . urlencode($location) : ''));
})
->processLogin();
}
public function oauthAction() {
$validator = new ZendAfi_Validate_Url();
if (('code' !== $this->_getParam('response_type'))
|| !$this->_getParam('client_id')
|| !$this->_getParam('redirect_uri')) {
throw new Zend_Controller_Action_Exception($this->view->_('Désolé, requête incomplète'), 400);
}
$this->view->titre = $this->_('Authentifiez-vous pour autoriser "%s" à accéder à votre compte',
$this->_getParam('client_id'));
$preferences = Class_Profil::getCurrentProfil()->getCfgModulesPreferences('auth', 'login');
$options = ['data' => array_merge(
$preferences,
['redirect_url' => $this->_getParam('redirect_uri'),
'id_notice' => 0])];
$this->view->form = ZendAfi_Form_Login::newWithOptions($options);
$this->getHelper('ViewRenderer')->setLayoutScript('subModal.phtml');
$redirect_uri = $this->_getParam('redirect_uri');
$strategy = new Auth_Strategy_OAuth($this);
$strategy->processLogin();
}
public function popupLoginAction() {
$this->view->preferences = $this->_loginPrefFromWidgetOrModule();
$this->view->redirect = $this->_getParam('redirect');
$this->view->location = $this->_getParam('location');
$this->renderPopupResult($this->view->_('Authentification'),
$this->view->render('auth/ajax-login.phtml'));
}
protected function _loginPrefFromWidgetOrModule() {
$module = Class_Profil::getCurrentProfil()
->getCfgModulesPreferences('auth','login');
$widget = Class_Profil::getCurrentProfil()
->getModuleAccueilPreferencesByType('LOGIN');
return $widget ? $widget : $module;
}
public function boiteLoginAction() {
$this->view->preferences = Class_Profil::getCurrentProfil()
->getModuleAccueilPreferencesByType('LOGIN');
$profil_redirect = isset($this->view->preferences['profil_redirect'])
? (int)$this->view->preferences['profil_redirect']
: 0;
$url = ($target = Class_Profil::find($profil_redirect))
? $target->getUrl()
: $this->_request->getServer('HTTP_REFERER');
$strategy = Auth_Strategy_Abstract::strategyForController($this);
$strategy->setDefaultUrl($url);
$strategy->onLoginSuccess(function($user) {
$user->registerNotificationsOn($this->getHelper('notify')->bePopup());
});
$strategy->processLogin();
}
public function ajaxlostpassAction() {
if ($this->_request->isPost()) {
$user = ZendAfi_Filters_Post::filterStatic($this->_request->getPost('username'));
$classe_user = new Class_Users();
$ret = $classe_user->lostpass($user);
$this->view->message = $this->getErrorMessages($ret["error"]);
$this->view->message_mail = $ret["message_mail"];
}
$this->view->username=$user;
$viewRenderer = $this->getHelper('ViewRenderer');
$viewRenderer->setLayoutScript('subModal.phtml');
}
public function logoutAction() {
ZendAfi_Auth::getInstance()->clearIdentity();
$profil = Class_Profil::getCurrentProfil();
$this->_redirectToLogoutProfil($profil->getModuleAccueilPreferencesByType('LOGIN'));
}
public function lostpassAction() {
$preferences = $this->_loginPrefFromWidgetOrModule();
$this->view->form = ZendAfi_Form_LostPassword::newWithOptions(['username_label' => $preferences["identifiant"],
'username_placeholder' => $preferences["identifiant_exemple"]])
->setAction($this->view->url(['module' => 'opac',
'controller' => 'auth',
'action' => 'lostpass'], null , true));
if(!$this->_request->isPost())
return;
$user = ZendAfi_Filters_Post::filterStatic($this->_request->getPost('lost_username'));
$classe_user = new Class_Users();
$ret = $classe_user->lostpass($user);
$this->view->message = $this->getErrorMessages($ret["error"]);
$this->view->message_mail = isset($ret["message_mail"])
? $ret["message_mail"]
: '';
$this->view->username=$user;
}
public function registerAction() {
if (Class_AdminVar::get('INTERDIRE_ENREG_UTIL')) {
$this->_redirect('/');
return;
}
$this->view->preferences = Class_Profil::getCurrentProfil()->getCfgModulesPreferences('auth', 'register');
$this->view->form = new ZendAfi_Form_Register();
$this->_postAndSave();
// Opération terminée
if($this->view->message_mail) {
$this->view->titre = $this->view->_("Votre demande d'inscription");
$viewRenderer = $this->getHelper('ViewRenderer');
$viewRenderer->renderScript('auth/message.phtml');
}
}
protected function _postAndSave() {
if(!$this->_request->isPost() || !$this->view->form->isValid($this->_request->getPost()))
return;
$data = ZendAfi_Filters_Post::filterStatic($this->_request->getPost());
$class_user = new Class_Users();
$data['cle'] = md5($data['mail']);
$ret = $class_user->registerUser($data);
// Affichage des erreurs
if(isset($ret["error"])) {
$this->view->login = $data["login"];
$this->view->email = $data["mail"];
$this->view->email2 = $data["mail2"];
$this->view->error = $ret["error"];
}
$this->view->message_mail = isset($ret["message_confirm"])
? $ret["message_confirm"]
: '';
}
public function newsletterRegisterAction() {
if('' != $this->_request->getParam('emailCheck'))
return $this->_redirect('/');
if(!($id_newsletter = $this->_request->getParam('id')))
return $this->_redirect('/');
if(!($newsletter = Class_Newsletter::find($id_newsletter)))
return $this->_redirect('/');
$this->view->newsletter = $newsletter;
if(null != Class_Users::getIdentity()) {
$_SERVER['HTTP_REFERER'] = '/';
return $this->_forward('subscribe-newsletter', 'abonne', 'opac', ['id' => $id_newsletter]);
}
$this->view->titre = $this->view->_('Inscription à la lettre d\'information: ') . $newsletter->getTitre();
$this->view->error = '';
$this->view->form = new ZendAfi_Form_NewsletterRegister();
if (!$this->_request->isPost()
|| !$this->view->form->isValid($this->_request->getPost()))
return;
$email = $this->view->form->getValue('email');
if (!Class_Users::isEmailUnique($email)) {
$this->view->error = $this->view->_('Un utilisateur a déjà renseigné cet email. Merci de vous identifier avec le compte qui utilise cet email.');
return;
}
$this->view->user = Class_UsersNonValid::newWithMail($email);
$this->newsletterRegisterSendMail($newsletter, $email);
$this->view->titre = $this->view->_('Demande d\'inscription à la lettre d\'information: ') . $newsletter->getTitre();
$this->getHelper('ViewRenderer')->renderScript('auth/newsletter-message.phtml');
}
protected function newsletterRegisterSendMail($newsletter, $email) {
$mail_body = $this->view->render('auth/newsletter-register-mail.phtml');
$mail_admin = Class_Profil::getCurrentProfil()->getMailSiteOrPortail();
try {
(new ZendAfi_Mail('utf8'))
->setSubject($newsletter->getTitre())
->setBodyText($mail_body)
->setFrom($mail_admin)
->addTo($email)
->addBcc($mail_admin)
->send();
} catch (Exception $e) {
$this->view->error = $this->view->_('Une erreur est survenue à l\'envoi du mail de confirmation. Veuillez réessayer. Si le problème persiste, veuillez contacter votre médiathèque.');
return;
}
$this->view->message = $this->view->_("Une demande de confirmation d'inscription vous a été envoyée à l'adresse mail renseignée.");
}
public function newsletterUnsubscribeAction() {
if(!($id_newsletter = $this->_request->getParam('id')))
return $this->_redirect('/');
if(!($newsletter = Class_Newsletter::find($id_newsletter))) {
$this->notify('Vous n\'êtes plus inscrit à la lettre d\'information, celle-ci n\'existe plus.');
return $this->_redirect('/');
}
if(null != Class_Users::getIdentity()) {
$_SERVER['HTTP_REFERER'] = '/';
return $this->_forward('unsubscribe-newsletter','abonne', 'opac', ['id' => $id_newsletter]);
}
$this->view->titre = $this->view->_('Désinscription de la lettre d\'information: ').$newsletter->getTitre();
$this->view->newsletter = Class_Newsletter::find($this->_getParam('id'));
}
public function activeuserAction() {
if (!$cle = $this->_request->getParam('c'))
$this->_redirect('/');
$info = (Class_UsersNonValid::activateBy($cle)) ?
getVar('USER_VALIDATED') :
getVar('USER_NON_VALIDATED');
$this->view->info = urldecode(str_replace('%0D%0A',"<br />", $info));
}
public function newsletterActiveUserAction() {
if(!($key = $this->_request->getParam('c')) || !($id_newsletter = $this->_request->getParam('id')))
return $this->_redirect('/');
if(!$newsletter = Class_Newsletter::find($id_newsletter))
return $this->_redirect('/');
$this->view->titre = $this->view->_("Confirmation d'inscription à la newsletter: ").$newsletter->getTitre();
($user = Class_UsersNonValid::activateForNewsletterBy($key))
? $this->newsletterRegisterUser($newsletter, $user)
: $this->view->message = $this->view->_("Inscription à la newsletter invalide.");
}
protected function newsletterRegisterUser($newsletter, $user) {
$user->addNewsletter($newsletter)
? $this->view->message = $this->view->_('Vous avez bien été abonné à la newsletter: ').$newsletter->getTitre().$this->view->_(' avec l\'adresse suivante: ').$user->getMail()
: $this->view->message = $this->view->_('Erreur lors de l\inscription à la newsletter.');
}
public function generatecaptchaAction() {
$md5_hash = md5(rand(0,999));
$security_code = substr($md5_hash, 15, 5);
$_SESSION['captcha_code'] = $security_code;
$image = ImageCreate(100, 20); // largeur, hauteur
$fond = ImageColorAllocate($image, 0, 0, 0);
$white = ImageColorAllocate($image, 255, 255, 255); // bg image
ImageString($image, 3, 30, 3, $security_code, $white);
header('Content-Type: image/jpeg');
ImageJpeg($image);
$viewRenderer = $this->getHelper('ViewRenderer');
$viewRenderer->setNoRender();
}
public function preRegistrationAction() {
$this->view->titre = $this->_('Demande de préinscription');
$pre_registration = new Class_WebService_SIGB_PreRegistration();
if (!$form = $pre_registration->getForm()) {
$this->_helper->notify($this->_('Cette fonctionnalité n\'est pas activée.'));
return $this->_redirect('opac/index');
}
$form = $pre_registration
->getForm()
->populate(ZendAfi_Filters_Post::filterStatic($this->_request->getParams()));
$this->view->form = $form;
$data = ZendAfi_Filters_Post::filterStatic($this->_request->getPost());
if ($this->_request->isPost() && $form->isValid($data)) {
$pre_registration->send($data);
$pre_registration->getErrors()->isEmpty()
? $this->_preRegistrationSuccess()
: $this->_preRegistrationFailed(implode(BR, $pre_registration->getErrors()->getArrayCopy()));
}
}
protected function _preRegistrationFailed($message) {
$this->_helper->notify($message);
$this->_preRegistrationRedirect('pre-registration');
}
protected function _preRegistrationSuccess() {
$this->_preRegistrationSuccessFull();
$this->view->library = $this->view->annexe->getBib();
$email = $this->_getParam('email', $this->_getParam('mail', ''));
$mail_admin = Class_Profil::getCurrentProfil()->getMailSiteOrPortail();
try {
(new ZendAfi_Mail('utf8'))
->setSubject($this->_('Préinscription à %s', $this->view->library_label))
->setBodyHTML($this->view->tagPreRegistration($this->view->library,
$this->view->form))
->setBodyText($this->view->tagPreRegistration($this->view->library,
$this->view->form,
false))
->setFrom($mail_admin)
->addTo($email)
->addBcc($mail_admin)
->send();
} catch (Exception $e) {}
$this->_helper->notify($this->_('Un email de confirmation de préinscription vous a été envoyé à l\'adresse %s .', $this->view->tag('b', $email)));
return $this->_preRegistrationRedirect('pre-registration-success');
}
protected function _preRegistrationRedirect($action) {
$this->_redirect($this->view->absoluteUrl(array_merge(['action' => $action],
$this->_request->getPost())));
}
public function preRegistrationSuccessAction() {
$this->view->titre = $this->_('Préinscription');
$this->_preRegistrationSuccessFull();
}
protected function _preRegistrationSuccessFull() {
$pre_registration = new Class_WebService_SIGB_PreRegistration();
$this->view->branchcode = $pre_registration->getBranchCode($this->_request->getParams());
$this->view->annexe = Class_CodifAnnexe::findFirstBy(['code' => $this->view->branchcode]);
$this->view->library = $this->view->annexe->getBib();
$this->view->library_label = $this->view->library->getLibelle();
$this->view->form = $pre_registration->getForm()
->populate($this->_request->getParams());
}
}
abstract class Auth_Strategy_Abstract {
protected
$redirect_url = '',
$disable_redirect = false,
$on_login_success_callback,
$on_login_fail_callback;
static public function strategyForController($controller) {
if ($controller->isCasRequest() && static::isLogged())
return new Auth_Strategy_Cas_Logged($controller);
if ($controller->isCasRequest() && !static::isLogged())
return new Auth_Strategy_Cas_NotLogged($controller);
if ($controller->isLectura())
return new Auth_Strategy_Lectura($controller);
if (static::isLogged())
return new Auth_Strategy_Logged($controller);
return new Auth_Strategy_NotLogged($controller);
}
static protected function isLogged() {
return Class_Users::getIdentity();
}
public function disableRedirect() {
$this->disable_redirect = true;
return $this;
}
public function __construct($controller) {
$this->controller = $controller;
$this->default_url = $this->controller->getRedirectDefaultUrl();
}
public function getRequest(){
return $this->controller->getRequest();
}
public function processLogin() {
$this->prepareLogin();
if ($this->getRequest()->isPost()) {
try {
$this->handlePost();
} catch (Class_WebService_SIGB_Nanook_PatronPasswordNotSecureException $e) {
return $this->controller->onPasswordNotSecure($e->getMessage(),
$e->getPattern());
}
}
if ($this->shouldRedirect())
$this->controller->redirect($this->redirect_url);
}
public function setDefaultUrl($url) {
$this->default_url=$url;
}
public function prepareLogin() {
}
/** @codeCoverageIgnore */
public function handlePost() {
}
public function shouldRedirect() {
return ($this->getRedirectUrl()!='');
}
public function getRedirectUrl() {
if ($this->disable_redirect)
return '';
return $this->redirect_url;
}
public function onLoginSuccess($do) {
$this->on_login_success_callback = $do;
return $this;
}
public function onLoginFail($do) {
$this->on_login_fail_callback = $do;
return $this;
}
protected function _doOnLoginFail() {
if (isset($this->on_login_fail_callback))
call_user_func($this->on_login_fail_callback);
return $this;
}
protected function _doOnLoginSuccess() {
if (($user = Class_Users::getIdentity()) && isset($this->on_login_success_callback))
call_user_func($this->on_login_success_callback, $user);
return $this;
}
}
class Auth_Strategy_NotLogged extends Auth_Strategy_Abstract{
public function handlePost() {
$this->redirect_url=$this->default_url;
if ($error = $this->controller->_authenticate()) {
$this->controller->notify($error);
return $this->_doOnLoginFail();
}
$this->_doOnLoginSuccess();
}
}
class Auth_Strategy_Logged extends Auth_Strategy_Abstract{
}
class Auth_Strategy_Cas_Abstract extends Auth_Strategy_Abstract{
public 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->controller->getCasServerUrl()));
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);
}
public function redirectMusicMe() {
if (strpos($this->controller->getCasServerUrl(),'musicme') !== false) {
$musicme = new Class_Systeme_ModulesMenu_MusicMe();
return $musicme->getDynamiqueUrl();
}
return false;
}
}
class Auth_Strategy_Cas_Logged extends Auth_Strategy_Cas_Abstract{
public function prepareLogin() {
if ($this->isCasDeconnected())
return $this->redirect_url='/opac';
$this->redirect_url=$this->urlServiceCas();
}
protected function isCasDeconnected() {
return stristr($this->controller->getCasServerUrl(),'deconnexion=ok') != FALSE;
}
}
class Auth_Strategy_Cas_NotLogged extends Auth_Strategy_Cas_Abstract{
public function handlePost() {
if ($error=$this->controller->_authenticate())
return $this->controller->notify($error);
$this->redirect_url=$this->urlServiceCas();
}
}
class Auth_Strategy_Lectura extends Auth_Strategy_Abstract {
public 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)));
}
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')]);
}
}
class Auth_Strategy_OAuth extends Auth_Strategy_NotLogged {
public function handlePost() {
parent::handlePost();
if (!$user = Class_Users::getIdentity())
return $this;
$request = $this->controller->getRequest();
$token = Class_User_ApiToken::findOrCreateForUserAndApplication($user,
$request->getParam('client_id'));
$this->redirect_url = sprintf('%s#token=%s',
$request->getParam('redirect_uri'),
$token->getToken());
}
}