LSsession : start LSerror before starting LStemplate
[ldapsaisie.git] / public_html / includes / class / class.LSsession.php
1 <?php
2 /*******************************************************************************
3  * Copyright (C) 2007 Easter-eggs
4  * http://ldapsaisie.labs.libre-entreprise.org
5  *
6  * Author: See AUTHORS file in top-level directory.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version 2
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 ******************************************************************************/
22
23 /** 
24  * Gestion des sessions
25  *
26  * Cette classe gère les sessions d'utilisateurs.
27  *
28  * @author Benjamin Renard <brenard@easter-eggs.com>
29  */
30 class LSsession {
31
32   // La configuration du serveur Ldap utilisé
33   public static $ldapServer = NULL;
34   
35   // L'id du serveur Ldap utilisé
36   private static $ldapServerId = NULL;
37   
38   // Le topDn courant
39   private static $topDn = NULL;
40   
41   // Le DN de l'utilisateur connecté
42   private static $dn = NULL;
43   
44   // Le RDN de l'utilisateur connecté (son identifiant)
45   private static $rdn = NULL;
46   
47   // Les LSprofiles de l'utilisateur
48   private static $LSprofiles = array();
49   
50   // Les droits d'accès de l'utilisateur
51   private static $LSaccess = array();
52   
53   // Les fichiers temporaires
54   private static $tmp_file = array();
55   
56   // Langue et encodage actuel
57   private static $lang = NULL;
58   private static $encoding = NULL;
59   
60   /*
61    * Constante de classe non stockée en session
62    */
63   // Le template à afficher
64   private static $template = NULL;
65   
66   // Les subDn des serveurs Ldap
67   private static $_subDnLdapServer = array();
68   
69   // Affichage Ajax
70   private static $ajaxDisplay = false;
71
72   // Les fichiers JS à charger dans la page
73   private static $JSscripts = array();
74   
75   // Les paramètres JS à communiquer dans la page
76   private static $_JSconfigParams = array();
77   
78   // Les fichiers CSS à charger dans la page
79   private static $CssFiles = array();
80
81   // L'objet de l'utilisateur connecté
82   private static $LSuserObject = NULL;
83   
84   // The LSauht object of the session
85   private static $LSauthObject = false;
86
87  /**
88   * Include un fichier PHP
89   *
90   * @author Benjamin Renard <brenard@easter-eggs.com>
91   *
92   * @retval true si tout c'est bien passé, false sinon
93   */
94   public static function includeFile($file) {
95     if (file_exists(LS_LOCAL_DIR.'/'.$file)) {
96       $file=LS_LOCAL_DIR.'/'.$file;
97     }
98     elseif (!file_exists($file)) {
99       return;
100     }
101     if (defined('LSdebug') && constant('LSdebug')) {
102       return include_once($file);
103     }
104     else {
105       return @include_once($file);
106     }
107     return;
108   }
109
110  /**
111   * Lancement de LSconfig
112   *
113   * @author Benjamin Renard <brenard@easter-eggs.com>
114   *
115   * @retval true si tout c'est bien passé, false sinon
116   */
117   private static function startLSconfig() {
118     if (self :: loadLSclass('LSconfig')) {
119       if (LSconfig :: start()) {
120         return true;
121       }
122     }
123     die("ERROR : Can't load configuration files.");
124     return;
125   }
126
127  /**
128   * Lancement et initialisation de Smarty
129   *
130   * @author Benjamin Renard <brenard@easter-eggs.com>
131   *
132   * @retval true si tout c'est bien passé, false sinon
133   */  
134   private static function startLStemplate() {
135     if ( self :: loadLSclass('LStemplate') ) {
136       self :: addJSconfigParam('LS_IMAGES_DIR',LS_IMAGES_DIR);
137       return LStemplate :: start(
138         array(
139           'smarty_path'  => LSconfig :: get('Smarty'),
140           'template_dir' => LS_TEMPLATES_DIR,
141           'compile_dir'  => LS_TMP_DIR,
142           'debug'        => LSdebug,
143           'debug_smarty' => (isset($_REQUEST['LStemplate_debug'])),
144         )
145       );
146     }
147     return False;
148   }
149   
150  /**
151   * Retourne le topDn de la session
152   *
153   * @author Benjamin Renard <brenard@easter-eggs.com>
154   *
155   * @retval string le topDn de la session
156   */
157   public static function getTopDn() {
158     if (!is_null(self :: $topDn)) {
159       return self :: $topDn;
160     }
161     else {
162       return self :: getRootDn();
163     }
164   }
165   
166  /**
167   * Retourne le rootDn de la session
168   *
169   * @author Benjamin Renard <brenard@easter-eggs.com>
170   *
171   * @retval string le rootDn de la session
172   */
173   public static function getRootDn() {
174     return self :: $ldapServer['ldap_config']['basedn'];
175   }
176
177  /**
178   * Initialisation de la gestion des erreurs
179   *
180   * Création de l'objet LSerror
181   *
182   * @author Benjamin Renard <brenard@easter-eggs.com
183   *
184   * @retval boolean true si l'initialisation a réussi, false sinon.
185   */
186   private static function startLSerror() {
187     if(!self :: loadLSclass('LSerror')) {
188       return;
189     }
190     self :: defineLSerrors();
191     return true;
192   }
193
194  /**
195   * Chargement d'une classe d'LdapSaisie
196   *
197   * @param[in] $class Nom de la classe Ã  charger (Exemple : LSpeople)
198   * @param[in] $type (Optionnel) Type de classe Ã  charger (Exemple : LSobjects)
199   *
200   * @author Benjamin Renard <brenard@easter-eggs.com
201   * 
202   * @retval boolean true si le chargement a réussi, false sinon.
203   */
204   public static function loadLSclass($class,$type='') {
205     if (class_exists($class))
206       return true;
207     if($type!='')
208       $type=$type.'.';
209     return self :: includeFile(LS_CLASS_DIR .'class.'.$type.$class.'.php');
210   }
211
212  /**
213   * Chargement d'un object LdapSaisie
214   *
215   * @param[in] $object Nom de l'objet Ã  charger
216   *
217   * @retval boolean true si le chargement a réussi, false sinon.
218   */
219   public static function loadLSobject($object) {
220     if(class_exists($object)) {
221       return true;
222     }
223     $error = 0;
224     self :: loadLSclass('LSldapObject');
225     if (!self :: loadLSclass($object,'LSobjects')) {
226       $error = 1;
227     }
228     if (!self :: includeFile( LS_OBJECTS_DIR . 'config.LSobjects.'.$object.'.php' )) {
229       $error = 1;
230     }
231     else {
232       if (!LSconfig :: set("LSobjects.$object",$GLOBALS['LSobjects'][$object])) {
233         $error = 1;
234       }
235       else if (isset($GLOBALS['LSobjects'][$object]['LSaddons'])){
236         if (is_array($GLOBALS['LSobjects'][$object]['LSaddons'])) {
237           foreach ($GLOBALS['LSobjects'][$object]['LSaddons'] as $addon) {
238             if (!self :: loadLSaddon($addon)) {
239               $error = 1;
240             }
241           }
242         }
243         else {
244           if (!self :: loadLSaddon($GLOBALS['LSobjects'][$object]['LSaddons'])) {
245             $error = 1;
246           }
247         } 
248       }
249     }
250     if ($error) {
251       LSerror :: addErrorCode('LSsession_04',$object);
252       return;
253     }
254     return true;
255   }
256
257  /**
258   * Chargement d'un addons d'LdapSaisie
259   *
260   * @param[in] $addon Nom de l'addon Ã  charger (Exemple : samba)
261   *
262   * @author Benjamin Renard <brenard@easter-eggs.com
263   * 
264   * @retval boolean true si le chargement a réussi, false sinon.
265   */
266   public static function loadLSaddon($addon) {
267     if(self :: includeFile(LS_ADDONS_DIR .'LSaddons.'.$addon.'.php')) {
268       self :: includeFile(LS_CONF_DIR."LSaddons/config.LSaddons.".$addon.".php");
269       if (!call_user_func('LSaddon_'. $addon .'_support')) {
270         LSerror :: addErrorCode('LSsession_02',$addon);
271         return;
272       }
273       return true;
274     }
275     return;
276   }
277
278  /**
279   * Chargement d'une classe d'authentification d'LdapSaisie
280   *
281   * @author Benjamin Renard <brenard@easter-eggs.com
282   * 
283   * @retval boolean true si le chargement a reussi, false sinon.
284   */
285   public static function loadLSauth() {
286     if (self :: loadLSclass('LSauth')) {
287       return true;
288     }
289     else {
290       LSerror :: addErrorCode('LSsession_05','LSauth');
291     }
292     return;
293   }
294
295  /**
296   * Chargement des addons LdapSaisie
297   *
298   * Chargement des LSaddons contenue dans la variable
299   * $GLOBALS['LSaddons']['loads']
300   *
301   * @retval boolean true si le chargement a réussi, false sinon.
302   */
303   public static function loadLSaddons() {
304     $conf=LSconfig :: get('LSaddons.loads');
305     if(!is_array($conf)) {
306       LSerror :: addErrorCode('LSsession_01',"LSaddons['loads']");
307       return;
308     }
309
310     foreach ($conf as $addon) {
311       self :: loadLSaddon($addon);
312     }
313     return true;
314   }
315
316  /**
317   * Défini la locale
318   * 
319   * @retval void
320   */
321   public static function setLocale() {
322     if (isset($_REQUEST['lang'])) {
323       $lang = $_REQUEST['lang'];
324     }
325     elseif (isset($_SESSION['LSlang'])) {
326       $lang = $_SESSION['LSlang'];
327     }
328     elseif (isset(self :: $ldapServer['lang'])) {
329       $lang = self :: $ldapServer['lang'];
330     }
331     else {
332       $lang = LSconfig :: get('lang');
333     }
334     
335     if (isset($_REQUEST['encoding'])) {
336       $encoding = $_REQUEST['encoding'];
337     }
338     elseif (isset($_SESSION['LSencoding'])) {
339       $encoding = $_SESSION['LSencoding'];
340     }
341     elseif (isset(self :: $ldapServer['encoding'])) {
342       $encoding = self :: $ldapServer['encoding'];
343     }
344     else {
345       $encoding = LSconfig :: get('encoding');
346     }
347     
348     $_SESSION['LSlang']=$lang;
349     self :: $lang=$lang;
350     $_SESSION['LSencoding']=$encoding;
351     self :: $encoding=$encoding;
352     
353
354     if (self :: localeExist($lang,$encoding)) {
355       if ($encoding) {
356         $lang.='.'.$encoding;
357       }
358       setlocale(LC_ALL, $lang);
359       bindtextdomain(LS_TEXT_DOMAIN, LS_I18N_DIR);
360       textdomain(LS_TEXT_DOMAIN);
361       
362       self :: includeFile(LS_I18N_DIR.'/'.$lang.'/lang.php');
363
364       foreach (listFiles(LS_LOCAL_DIR.'/'.LS_I18N_DIR.'/'.$lang,'/^lang.+\.php$/') as $file) {
365         include(LS_LOCAL_DIR.'/'.LS_I18N_DIR."/$lang/$file");
366       }
367     }
368     else {
369       if ($encoding && $lang) {
370         $lang.='.'.$encoding;
371       }
372       LSdebug('La locale "'.$lang.'" n\'existe pas, utilisation de la locale par défaut.');
373     }
374   }
375   
376  /**
377   * Retourne la liste des langues disponibles
378   * 
379   * @retval array Tableau/Liste des langues disponibles
380   **/ 
381   public static function getLangList() {
382     $list=array('en_US');
383     if (self :: $encoding) {
384       $regex = '^([a-zA-Z_]*)\.'.self :: $encoding.'$';
385     }
386     else {
387       $regex = '^([a-zA-Z_]*)$';
388     }
389     if ($handle = opendir(LS_I18N_DIR)) {
390       while (false !== ($file = readdir($handle))) {
391         if(is_dir(LS_I18N_DIR.'/'.$file)) {
392           if (ereg($regex,$file,$regs)) {
393             if (!in_array($regs[1],$list)) {
394               $list[]=$regs[1];
395             }
396           }
397         }
398       }
399     }
400     return $list;
401   }
402
403  /**
404   * Retourne la langue courante de la session
405   * 
406   * @param[in] boolean Si true, le code langue retourné sera court
407   * 
408   * @retval string La langue de la session
409   **/
410   public static function getLang($short=false) {
411     if ($short) {
412       return strtolower(self :: $lang[0].self :: $lang[1]);
413     }
414     return self :: $lang;
415   }
416   
417  /**
418   * Vérifie si une locale est disponible
419   * 
420   * @param[in] $lang string La langue (Ex : fr_FR)
421   * @param[in] $encoding string L'encodage de caractère (Ex : UTF8)
422   * 
423   * @retval boolean True si la locale est disponible, False sinon
424   **/
425   public static function localeExist($lang,$encoding) {
426     if ( !$lang && !$encoding ) {
427       return;
428     }
429     $locale=$lang.(($encoding)?'.'.$encoding:'');
430     if ($locale=='en_US.UTF8') {
431       return true;
432     }
433     return (is_dir(LS_I18N_DIR.'/'.$locale));
434   }
435
436  /**
437   * Initialisation LdapSaisie
438   *
439   * @retval boolean True si l'initialisation à réussi, false sinon.
440   */
441   public static function initialize() {
442     if (!self :: startLSconfig()) {
443       return;
444     }
445     
446     self :: startLSerror();
447     self :: startLStemplate();
448     
449     session_start();
450     
451     self :: setLocale();
452     
453     self :: loadLSaddons();
454     self :: loadLSauth();
455     return true;
456   }
457
458  /**
459   * Initialisation de la session LdapSaisie
460   *
461   * Initialisation d'une LSsession :
462   * - Authentification et activation du mécanisme de session de LdapSaisie
463   * - ou Chargement des paramètres de la session Ã  partir de la variable 
464   *   $_SESSION['LSsession'].
465   * - ou Destruction de la session en cas de $_GET['LSsession_logout'].
466   *
467   * @retval boolean True si l'initialisation Ã  réussi (utilisateur authentifié), false sinon.
468   */
469   public static function startLSsession() {
470     if (!self :: initialize()) {
471       return;
472     }
473     
474     if(isset($_SESSION['LSsession']['dn']) && !isset($_GET['LSsession_recoverPassword'])) {
475       LSdebug('LSsession : Session existente'); 
476       // --------------------- Session existante --------------------- //
477       self :: $topDn        = $_SESSION['LSsession']['topDn'];
478       self :: $dn           = $_SESSION['LSsession']['dn'];
479       self :: $rdn          = $_SESSION['LSsession']['rdn'];
480       self :: $ldapServerId = $_SESSION['LSsession']['ldapServerId'];
481       self :: $tmp_file     = $_SESSION['LSsession']['tmp_file'];
482       
483       if ( self :: cacheLSprofiles() && !isset($_REQUEST['LSsession_refresh']) ) {
484         self :: setLdapServer(self :: $ldapServerId);
485         if (!LSauth :: start()) {
486           LSdebug("LSsession : can't start LSauth -> stop");
487           return;
488         }
489         self :: $LSprofiles   = $_SESSION['LSsession']['LSprofiles'];
490         self :: $LSaccess   = $_SESSION['LSsession']['LSaccess'];
491         if (!self :: LSldapConnect())
492           return;
493       }
494       else {
495         self :: setLdapServer(self :: $ldapServerId);
496         if (!LSauth :: start()) {
497           LSdebug("LSsession : can't start LSauth -> stop");
498           return;
499         }
500         if (!self :: LSldapConnect())
501           return;
502         self :: loadLSprofiles();
503       }
504       
505       if ( self :: cacheSudDn() && (!isset($_REQUEST['LSsession_refresh'])) ) {
506         self :: $_subDnLdapServer = ((isset($_SESSION['LSsession_subDnLdapServer']))?$_SESSION['LSsession_subDnLdapServer']:NULL);
507       }
508       
509       if (!self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
510         return;
511       }
512       
513       if (isset($_GET['LSsession_logout'])) {
514         LSauth :: logout();
515         session_destroy();
516         
517         if (is_array($_SESSION['LSsession']['tmp_file'])) {
518           self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
519         }
520         self :: deleteTmpFile();
521         unset($_SESSION['LSsession']);
522         
523         self :: redirect('index.php');
524         return;
525       }
526       
527       if ( !self :: cacheLSprofiles() || isset($_REQUEST['LSsession_refresh']) ) {
528         self :: loadLSaccess();
529       }
530       
531       LStemplate :: assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
532       
533       if (isset ($_POST['LSsession_topDn']) && $_POST['LSsession_topDn']) {
534         if (self :: validSubDnLdapServer($_POST['LSsession_topDn'])) {
535           self :: $topDn = $_POST['LSsession_topDn'];
536           $_SESSION['LSsession']['topDn'] = $_POST['LSsession_topDn'];
537         } // end if
538       } // end if
539       
540       return true;
541       
542     }
543     else {
544       // --------------------- Session inexistante --------------------- //
545       if (isset($_GET['LSsession_recoverPassword'])) {
546         session_destroy();
547       }
548       // Session inexistante
549       if (isset($_POST['LSsession_ldapserver'])) {
550         self :: setLdapServer($_POST['LSsession_ldapserver']);
551       }
552       else {
553         self :: setLdapServer(0);
554       }
555       
556       // Connexion au serveur LDAP
557       if (self :: LSldapConnect()) {
558
559         // topDn
560         if (isset($_POST['LSsession_topDn']) && $_POST['LSsession_topDn'] != '' ){
561           self :: $topDn = $_POST['LSsession_topDn'];
562         }
563         else {
564           self :: $topDn = self :: $ldapServer['ldap_config']['basedn'];
565         }
566         $_SESSION['LSsession_topDn']=self :: $topDn;
567        
568         if (!LSauth :: start()) {
569           LSdebug("LSsession : can't start LSauth -> stop");
570           return;
571         }
572         
573         if (isset($_GET['LSsession_recoverPassword'])) {
574           $recoveryPasswordInfos = self :: recoverPasswd(
575                                       $_REQUEST['LSsession_user'],
576                                       $_GET['recoveryHash']
577                                    );
578         }
579         else {
580           $LSuserObject = LSauth :: forceAuthentication();
581           if ($LSuserObject) {
582             // Authentication successful
583             self :: $LSuserObject = $LSuserObject;
584             self :: $dn = $LSuserObject->getValue('dn');
585             self :: $rdn = $LSuserObject->getValue('rdn');
586             self :: loadLSprofiles();
587             self :: loadLSaccess();
588             LStemplate :: assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
589             $_SESSION['LSsession']=self :: getContextInfos();
590             return true;
591           }
592         }
593       }
594       else {
595         LSerror :: addErrorCode('LSsession_09');
596       }
597       
598       if (self :: $ldapServerId) {
599         LStemplate :: assign('ldapServerId',self :: $ldapServerId);
600       }
601       LStemplate :: assign('topDn',self :: $topDn);
602       if (isset($_GET['LSsession_recoverPassword'])) {
603         self :: displayRecoverPasswordForm($recoveryPasswordInfos);
604       }
605       elseif(LSauth :: displayLoginForm()) {
606         self :: displayLoginForm();
607       }
608       else {
609         self :: setTemplate('blank.tpl');
610         LSerror :: addErrorCode('LSsession_10');
611       }
612       return;
613     }
614   }
615   
616   /**
617    * Do recover password
618    * 
619    * @param[in] $username string The submited username
620    * @param[in] $recoveryHash string The submited recoveryHash
621    * 
622    * @retval array The recoveryPassword infos for template
623    **/
624   private static function recoverPasswd($username,$recoveryHash) {
625     $recoveryPasswordInfos=array();
626     if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) {
627       $authobject = new self :: $ldapServer['authObjectType']();
628       if (!empty($recoveryHash)) {
629         $filter=Net_LDAP2_Filter::create(
630           self :: $ldapServer['recoverPassword']['recoveryHashAttr'],
631           'equals',
632           $recoveryHash
633         );
634         $result = $authobject -> listObjects($filter,self :: $topDn);
635       }
636       elseif (!empty($username)) {
637         $result = $authobject -> searchObject(
638                     $username,
639                     self :: $topDn,
640                     self :: $ldapServer['authObjectFilter']
641                   );
642       }
643       else {
644         return $recoveryPasswordInfos;
645       }
646       
647       $nbresult=count($result);
648       
649       if ($nbresult==0) {
650         LSdebug('hash/username incorrect');
651         LSerror :: addErrorCode('LSsession_06');  
652       }
653       elseif ($nbresult>1) {
654         LSerror :: addErrorCode('LSsession_07');
655       }
656       else {
657         $rdn = $result[0] -> getValue('rdn');
658         $username = $rdn[0];
659         LSdebug('Recover : Id trouvé : '.$username);
660         if (self :: $ldapServer['recoverPassword']) {
661           if (self :: loadLSaddon('mail')) {
662             LSdebug('Récupération active');
663             $user=$result[0];
664             $emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
665             $emailAddress = $emailAddress[0];
666             
667             if (checkEmail($emailAddress)) {
668               LSdebug('Email : '.$emailAddress);
669               self :: $dn = $user -> getDn();
670               
671               // 1ère étape : envoie du recoveryHash
672               if (empty($recoveryHash)) {
673                 $hash=self :: recoverPasswdFirstStep($user);
674                 if ($hash) {
675                   if (self :: recoverPasswdSendMail($emailAddress,1,$hash)) {
676                     // Mail a bien été envoyé
677                     $recoveryPasswordInfos['recoveryHashMail']=$emailAddress;
678                   }
679                 }
680               }
681               // 2nd étape : génération du mot de passe + envoie par mail
682               else {
683                 $pwd=self :: recoverPasswdSecondStep($user);
684                 if ($pwd) {
685                   if (self :: recoverPasswdSendMail($emailAddress,2,$pwd)){
686                     // Mail a bien été envoyé
687                     $recoveryPasswordInfos['newPasswordMail']=$emailAddress;
688                   }
689                 }
690               }
691             }
692             else {
693               LSerror :: addErrorCode('LSsession_19');
694             }
695           }
696         }
697         else {
698           LSerror :: addErrorCode('LSsession_18');
699         }
700       }
701     }
702     return $recoveryPasswordInfos;
703   }
704   
705   /**
706    * Send recover password mail
707    * 
708    * @param[in] $mail string The user's mail
709    * @param[in] $step integer The step
710    * @param[in] $info string The info for formatted message
711    * 
712    * @retval boolean True on success or False
713    **/
714   private static function recoverPasswdSendMail($mail,$step,$info) {
715     // Header des mails
716     $sendParams=array();
717     if (self :: $ldapServer['recoverPassword']['recoveryEmailSender']) {
718       $sendParams['From']=self :: $ldapServer['recoverPassword']['recoveryEmailSender'];
719     }
720     
721     if ($step==1) {
722       if ($_SERVER['HTTPS']=='on') {
723         $recovery_url='https://';
724       }
725       else {
726         $recovery_url='http://';
727       }
728       $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$info;
729       
730       $subject = self :: $ldapServer['recoverPassword']['recoveryHashMail']['subject'];
731       $msg = getFData(
732         self :: $ldapServer['recoverPassword']['recoveryHashMail']['msg'],
733         $recovery_url
734       );
735     }
736     else {
737       $subject = self :: $ldapServer['recoverPassword']['newPasswordMail']['subject'];
738       $msg = getFData(
739         self :: $ldapServer['recoverPassword']['newPasswordMail']['msg'],
740         $info
741       );
742     }
743     
744     if (!sendMail($mail,$subject,$msg,$sendParams)) {
745       LSdebug("Problème durant l'envoie du mail");
746       LSerror :: addErrorCode('LSsession_20',4);
747       return;
748     }
749     return true;
750   }
751   
752   
753   /**
754    * Do first step of recovering password
755    * 
756    * @param[in] $user LSldapObject The LSldapObject of the user
757    * 
758    * @retval string|False The recory hash on success or False
759    **/
760   private static function recoverPasswdFirstStep($user) {
761     // Generer un hash
762     $rdn=$user -> getValue('rdn');
763     $rdn = $rdn[0];
764     $recovery_hash = md5($rdn . strval(time()) . strval(rand()));
765     
766     $lostPasswdForm = $user -> getForm('lostPassword');
767     $lostPasswdForm -> setPostData(
768       array(
769         self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash
770       )
771       ,true
772     );
773       
774     if($lostPasswdForm -> validate()) {
775       if ($user -> updateData('lostPassword')) {
776         // recoveryHash de l'utilisateur mis à jour
777         return $recovery_hash;
778       }
779       else {
780         // Erreur durant la mise à jour de l'objet
781         LSdebug("Erreur durant la mise à jour de l'objet");
782         LSerror :: addErrorCode('LSsession_20',6);
783       }
784     }
785     else {
786       // Erreur durant la validation du formulaire de modification de perte de password
787       LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
788       LSerror :: addErrorCode('LSsession_20',5);
789     }
790     return;
791   }
792
793   /**
794    * Do second step of recovering password
795    * 
796    * @param[in] $user LSldapObject The LSldapObject of the user
797    * 
798    * @retval string|False The new password on success or False
799    **/
800   private static function recoverPasswdSecondStep($user) {
801     $attr=$user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']];
802     if ($attr instanceof LSattribute) {
803       $mdp = generatePassword(
804        $attr -> config['html_options']['chars'],
805        $attr -> config['html_options']['lenght']
806       );
807       LSdebug('Nvx mpd : '.$mdp);
808       $lostPasswdForm = $user -> getForm('lostPassword');
809       $lostPasswdForm -> setPostData(
810         array(
811           self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
812           self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp)
813         )
814         ,true
815       );
816       if($lostPasswdForm -> validate()) {
817         if ($user -> updateData('lostPassword')) {
818           return $mdp;
819         }
820         else {
821           // Erreur durant la mise à jour de l'objet
822           LSdebug("Erreur durant la mise à jour de l'objet");
823           LSerror :: addErrorCode('LSsession_20',3);
824         }
825       }
826       else {
827         // Erreur durant la validation du formulaire de modification de perte de password
828         LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
829         LSerror :: addErrorCode('LSsession_20',2);
830       }
831     }
832     else {
833       // l'attribut password n'existe pas
834       LSdebug("L'attribut password n'existe pas");
835       LSerror :: addErrorCode('LSsession_20',1);
836     }
837     return;
838   }
839   
840  /**
841   * Retourne les informations du contexte
842   *
843   * @author Benjamin Renard <brenard@easter-eggs.com
844   * 
845   * @retval array Tableau associatif des informations du contexte
846   */
847   private static function getContextInfos() {
848     return array(
849       'tmp_file' => self :: $tmp_file,
850       'topDn' => self :: $topDn,
851       'dn' => self :: $dn,
852       'rdn' => self :: $rdn,
853       'ldapServerId' => self :: $ldapServerId,
854       'ldapServer' => self :: $ldapServer,
855       'LSprofiles' => self :: $LSprofiles,
856       'LSaccess' => self :: $LSaccess
857     );
858   }
859   
860   /**
861   * Retourne l'objet de l'utilisateur connecté
862   *
863   * @author Benjamin Renard <brenard@easter-eggs.com
864   * 
865   * @retval mixed L'objet de l'utilisateur connecté ou false si il n'a pas put
866   *               être créé
867   */
868   public static function getLSuserObject($dn=null) {
869     if ($dn) {
870       self :: $dn = $dn;
871     }
872     if (!self :: $LSuserObject) {
873       if (self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
874         self :: $LSuserObject = new self :: $ldapServer['authObjectType']();
875         self :: $LSuserObject -> loadData(self :: $dn);
876       }
877       else {
878         return;
879       }
880     }
881     return self :: $LSuserObject;
882   }
883   
884  /**
885   * Retourne le DN de l'utilisateur connecté
886   *
887   * @author Benjamin Renard <brenard@easter-eggs.com
888   * 
889   * @retval string Le DN de l'utilisateur connecté
890   */
891   public static function getLSuserObjectDn() {
892     return self :: $dn;
893   }
894
895  /**
896   * Modifie l'utilisateur connecté à la volé
897   * 
898   * @param[in] $object Mixed  L'objet Ldap du nouvel utilisateur
899   *                           le type doit correspondre à
900   *                           self :: $ldapServer['authObjectType']
901   * 
902   * @retval boolean True en cas de succès, false sinon
903   */
904  public static function changeAuthUser($object) {
905   if ($object instanceof self :: $ldapServer['authObjectType']) {
906     self :: $dn = $object -> getDn();
907     $rdn = $object -> getValue('rdn');
908     if(is_array($rdn)) {
909       $rdn = $rdn[0];
910     }
911     self :: $rdn = $rdn;
912     self :: $LSuserObject = $object;
913     
914     if(self :: loadLSprofiles()) {
915       self :: loadLSaccess();
916       $_SESSION['LSsession']=self :: getContextInfos();
917       return true;
918     }
919   }
920   return;
921  }
922
923  /**
924   * Définition du serveur Ldap de la session
925   *
926   * Définition du serveur Ldap de la session Ã  partir de son ID dans 
927   * le tableau LSconfig :: get('ldap_servers').
928   *
929   * @param[in] integer Index du serveur Ldap
930   *
931   * @retval boolean True sinon false.
932   */
933   public static function setLdapServer($id) {
934     $conf = LSconfig :: get("ldap_servers.$id");
935     if ( is_array($conf) ) {
936       self :: $ldapServerId = $id;
937       self :: $ldapServer = $conf;
938       self :: setLocale();
939       return true;
940     }
941     else {
942       return;
943     }
944   }
945
946  /**
947   * Connexion au serveur Ldap
948   *
949   * @retval boolean True sinon false.
950   */
951   public static function LSldapConnect() {
952     if (self :: $ldapServer) {
953       self :: includeFile(LSconfig :: get('NetLDAP2'));
954       if (!self :: loadLSclass('LSldap')) {
955         return;
956       }
957       LSldap :: connect(self :: $ldapServer['ldap_config']);
958       if (LSldap :: isConnected()) {
959         return true;
960       }
961       else {
962         return;
963       }
964     }
965     else {
966       LSerror :: addErrorCode('LSsession_03');
967       return;
968     }
969   }
970
971   /**
972    * Use this function to know if subDn is enabled for the curent LdapServer
973    * 
974    * @retval boolean
975    **/
976   public static function subDnIsEnabled() {
977     if (!isset(self :: $ldapServer['subDn'])) {
978       return;
979     }
980     if ( !is_array(self :: $ldapServer['subDn']) ) {
981       return;
982     }
983     return true;
984   }
985
986  /**
987   * Retourne les sous-dns du serveur Ldap courant
988   *
989   * @retval mixed Tableau des subDn, false si une erreur est survenue.
990   */
991   public static function getSubDnLdapServer($login=false) {
992     $login=(bool)$login;
993     if (self :: cacheSudDn() && isset(self :: $_subDnLdapServer[self :: $ldapServerId][$login])) {
994       return self :: $_subDnLdapServer[self :: $ldapServerId][$login];
995     }
996     if (!self::subDnIsEnabled()) {
997       return;
998     }
999     $return=array();
1000     foreach(self :: $ldapServer['subDn'] as $subDn_name => $subDn_config) {
1001       if ($login && isset($subDn_config['nologin']) && $subDn_config['nologin']) continue;
1002       if ($subDn_name == 'LSobject') {
1003         if (is_array($subDn_config)) {
1004           foreach($subDn_config as $LSobject_name => $LSoject_config) {
1005             if (isset($LSoject_config['basedn']) && !empty($LSoject_config['basedn'])) {
1006               $basedn = $LSoject_config['basedn'];
1007             }
1008             else {
1009               $basedn = self::getRootDn();
1010             }
1011             if (isset($LSoject_config['displayName']) && !empty($LSoject_config['displayName'])) {
1012               $displayName = $LSoject_config['displayName'];
1013             }
1014             else {
1015               $displayName = NULL;
1016             }
1017             if( self :: loadLSobject($LSobject_name) ) {
1018               if ($subdnobject = new $LSobject_name()) {
1019                 $tbl_return = $subdnobject -> getSelectArray(NULL,$basedn,$displayName);
1020                 if (is_array($tbl_return)) {
1021                   $return=array_merge($return,$tbl_return);
1022                 }
1023                 else {
1024                   LSerror :: addErrorCode('LSsession_17',3);
1025                 }
1026               }
1027               else {
1028                 LSerror :: addErrorCode('LSsession_17',2);
1029               }
1030             }
1031           }
1032         }
1033         else {
1034           LSerror :: addErrorCode('LSsession_17',1);
1035         }
1036       }
1037       else {
1038         if ((isCompatibleDNs($subDn_config['dn'],self :: $ldapServer['ldap_config']['basedn']))&&($subDn_config['dn']!="")) {
1039           $return[$subDn_config['dn']] = __($subDn_name);
1040         }
1041       }
1042     }
1043     if (self :: cacheSudDn()) {
1044       self :: $_subDnLdapServer[self :: $ldapServerId][$login]=$return;
1045       $_SESSION['LSsession_subDnLdapServer'] = self :: $_subDnLdapServer;
1046     }
1047     return $return;
1048   }
1049   
1050   /**
1051    * Retourne la liste de subDn du serveur Ldap utilise
1052    * trié par la profondeur dans l'arboressence (ordre décroissant)
1053    * 
1054    * @return array() Tableau des subDn trié
1055    */  
1056   public static function getSortSubDnLdapServer($login=false) {
1057     $subDnLdapServer = self :: getSubDnLdapServer($login);
1058     if (!$subDnLdapServer) {
1059       return array();
1060     }
1061     uksort($subDnLdapServer,"compareDn");
1062     return $subDnLdapServer;
1063   }
1064
1065  /**
1066   * Retourne les options d'une liste déroulante pour le choix du topDn
1067   * de connexion au serveur Ldap
1068   *
1069   * Liste les subdn (self :: $ldapServer['subDn'])
1070   *
1071   * @retval string Les options (<option>) pour la sélection du topDn.
1072   */
1073   public static function getSubDnLdapServerOptions($selected=NULL,$login=false) {
1074     $list = self :: getSubDnLdapServer($login);
1075     if ($list) {
1076       asort($list);
1077       $display='';
1078       foreach($list as $dn => $txt) {
1079         if ($selected && ($selected==$dn)) {
1080           $selected_txt = ' selected';
1081         }
1082         else {
1083           $selected_txt = '';
1084         }
1085         $display.="<option value=\"".$dn."\"$selected_txt>".$txt."</option>\n"; 
1086       }
1087       return $display;
1088     }
1089     return;
1090   }
1091
1092  /**
1093   * Vérifie qu'un subDn est déclaré
1094   *
1095   * @param[in] string Un subDn
1096   * 
1097   * @retval boolean True si le subDn existe, False sinon
1098   */
1099   public static function validSubDnLdapServer($subDn) {
1100     $listTopDn = self :: getSubDnLdapServer();
1101     if(is_array($listTopDn)) {
1102       foreach($listTopDn as $dn => $txt) {
1103         if ($subDn==$dn) {
1104           return true;
1105         } // end if
1106       } // end foreach
1107     } // end if
1108     return;
1109   }
1110
1111  /**
1112   * Test un couple LSobject/pwd
1113   *
1114   * Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni.
1115   *
1116   * @param[in] LSobject L'object "user" pour l'authentification
1117   * @param[in] string Le mot de passe Ã  tester
1118   *
1119   * @retval boolean True si l'authentification Ã  réussi, false sinon.
1120   */
1121   public static function checkUserPwd($object,$pwd) {
1122     return LSldap :: checkBind($object -> getValue('dn'),$pwd);
1123   }
1124
1125  /**
1126   * Affiche le formulaire de login
1127   *
1128   * Défini les informations pour le template Smarty du formulaire de login.
1129   *
1130   * @retval void
1131   */
1132   public static function displayLoginForm() {
1133     LStemplate :: assign('pagetitle',_('Connection'));
1134     if (isset($_GET['LSsession_logout'])) {
1135       LStemplate :: assign('loginform_action','index.php');
1136     }
1137     else {
1138       LStemplate :: assign('loginform_action',$_SERVER['REQUEST_URI']);
1139     }
1140     if (count(LSconfig :: get('ldap_servers'))==1) {
1141       LStemplate :: assign('loginform_ldapserver_style','style="display: none"');
1142     }
1143     LStemplate :: assign('loginform_label_ldapserver',_('LDAP server'));
1144     $ldapservers_name=array();
1145     $ldapservers_index=array();
1146     foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1147       $ldapservers_index[]=$id;
1148       $ldapservers_name[]=__($infos['name']);
1149     }
1150     LStemplate :: assign('loginform_ldapservers_name',$ldapservers_name);
1151     LStemplate :: assign('loginform_ldapservers_index',$ldapservers_index);
1152
1153     LStemplate :: assign('loginform_label_level',_('Level'));
1154     LStemplate :: assign('loginform_label_user',_('Identifier'));
1155     LStemplate :: assign('loginform_label_pwd',_('Password'));
1156     LStemplate :: assign('loginform_label_submit',_('Connect'));
1157     LStemplate :: assign('loginform_label_recoverPassword',_('Forgot your password ?'));
1158     
1159     self :: setTemplate('login.tpl');
1160     self :: addJSscript('LSsession_login.js');
1161   }
1162
1163  /**
1164   * Affiche le formulaire de récupération de mot de passe
1165   *
1166   * Défini les informations pour le template Smarty du formulaire de 
1167   * récupération de mot de passe
1168   * 
1169   * @param[in] $infos array() Information sur le status du processus de 
1170   *                           recouvrement de mot de passe
1171   *
1172   * @retval void
1173   */
1174   public static function displayRecoverPasswordForm($recoveryPasswordInfos) {
1175     LStemplate :: assign('pagetitle',_('Recovery of your credentials'));
1176     LStemplate :: assign('recoverpasswordform_action','index.php?LSsession_recoverPassword');
1177     
1178     if (count(LSconfig :: get('ldap_servers'))==1) {
1179       LStemplate :: assign('recoverpasswordform_ldapserver_style','style="display: none"');
1180     }
1181     
1182     LStemplate :: assign('recoverpasswordform_label_ldapserver',_('LDAP server'));
1183     $ldapservers_name=array();
1184     $ldapservers_index=array();
1185     foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1186       $ldapservers_index[]=$id;
1187       $ldapservers_name[]=$infos['name'];
1188     }
1189     LStemplate :: assign('recoverpasswordform_ldapservers_name',$ldapservers_name);
1190     LStemplate :: assign('recoverpasswordform_ldapservers_index',$ldapservers_index);
1191
1192     LStemplate :: assign('recoverpasswordform_label_user',_('Identifier'));
1193     LStemplate :: assign('recoverpasswordform_label_submit',_('Validate'));
1194     LStemplate :: assign('recoverpasswordform_label_back',_('Back'));
1195     
1196     $recoverpassword_msg = _('Please fill the identifier field to proceed recovery procedure');
1197     
1198     if (isset($recoveryPasswordInfos['recoveryHashMail'])) {
1199       $recoverpassword_msg = getFData(
1200         _("An email has been sent to  %{mail}. " .
1201         "Please follow the instructions on it."),
1202         $recoveryPasswordInfos['recoveryHashMail']
1203       );
1204     }
1205     
1206     if (isset($recoveryPasswordInfos['newPasswordMail'])) {
1207       $recoverpassword_msg = getFData(
1208         _("Your new password has been sent to %{mail}. "),
1209         $recoveryPasswordInfos['newPasswordMail']
1210       );
1211     }
1212     
1213     LStemplate :: assign('recoverpassword_msg',$recoverpassword_msg);
1214     
1215     self :: setTemplate('recoverpassword.tpl');
1216     self :: addJSscript('LSsession_recoverPassword.js');
1217   }
1218
1219  /**
1220   * Défini le template Smarty Ã  utiliser
1221   *
1222   * Remarque : les fichiers de templates doivent se trouver dans le dossier 
1223   * templates/.
1224   *
1225   * @param[in] string Le nom du fichier de template
1226   *
1227   * @retval void
1228   */
1229   public static function setTemplate($template) {
1230     self :: $template = $template;
1231   }
1232
1233  /**
1234   * Ajoute un script JS au chargement de la page
1235   *
1236   * Remarque : les scripts doivents Ãªtre dans le dossier LS_JS_DIR.
1237   *
1238   * @param[in] $script Le nom du fichier de script Ã  charger.
1239   *
1240   * @retval void
1241   */
1242   public static function addJSscript($file,$path=NULL) {
1243     $script=array(
1244       'file' => $file,
1245       'path' => $path
1246     );
1247     self :: $JSscripts[$path.$file]=$script;
1248   }
1249
1250  /**
1251   * Ajouter un paramètre de configuration Javascript
1252   * 
1253   * @param[in] $name string Nom de la variable de configuration
1254   * @param[in] $val mixed Valeur de la variable de configuration
1255   *
1256   * @retval void
1257   */
1258   public static function addJSconfigParam($name,$val) {
1259     self :: $_JSconfigParams[$name]=$val;
1260   }
1261
1262  /**
1263   * Ajoute une feuille de style au chargement de la page
1264   *
1265   * Remarque : les scripts doivents Ãªtre dans le dossier LS_CSS_DIR.
1266   *
1267   * @param[in] $script Le nom du fichier css Ã  charger.
1268   *
1269   * @retval void
1270   */
1271   public static function addCssFile($file,$path=NULL) {
1272     $cssFile=array(
1273       'file' => $file,
1274       'path' => $path
1275     );
1276     self :: $CssFiles[$path.$file]=$cssFile;
1277   }
1278
1279  /**
1280   * Affiche le template Smarty
1281   *
1282   * Charge les dépendances et affiche le template Smarty
1283   *
1284   * @retval void
1285   */
1286   public static function displayTemplate() {
1287     // JS
1288     $JSscript_txt='';
1289     foreach ($GLOBALS['defaultJSscipts'] as $script) {
1290       $JSscript_txt.="<script src='".LS_JS_DIR.$script."' type='text/javascript'></script>\n";
1291     }
1292
1293     foreach (self :: $JSscripts as $script) {
1294       if (!$script['path']) {
1295         $script['path']=LS_JS_DIR;
1296       }
1297       else {
1298         $script['path'].='/';
1299       }
1300       $JSscript_txt.="<script src='".$script['path'].$script['file']."' type='text/javascript'></script>\n";
1301     }
1302
1303     $KAconf = LSconfig :: get('keepLSsessionActive');
1304     if ( 
1305           (
1306             (!isset(self :: $ldapServer['keepLSsessionActive']))
1307             &&
1308             (!($KAconf === false))
1309           )
1310           ||
1311           (self :: $ldapServer['keepLSsessionActive'])
1312         ) {
1313       self :: addJSconfigParam('keepLSsessionActive',ini_get('session.gc_maxlifetime'));
1314     }
1315
1316     LStemplate :: assign('LSjsConfig',json_encode(self :: $_JSconfigParams));
1317     
1318     if (LSdebug) {
1319       $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n";
1320     }
1321     else {
1322       $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 0;</script>\n";
1323     }
1324     
1325     LStemplate :: assign('LSsession_js',$JSscript_txt);
1326
1327     // Css
1328     self :: addCssFile("LSdefault.css");
1329     $Css_txt='';
1330     foreach (self :: $CssFiles as $file) {
1331       if (!$file['path']) {
1332         $file['path']=LS_CSS_DIR.'/';
1333       }
1334       $Css_txt.="<link rel='stylesheet' type='text/css' href='".$file['path'].$file['file']."' />\n";
1335     }
1336     LStemplate :: assign('LSsession_css',$Css_txt);
1337   
1338     if (isset(self :: $LSaccess[self :: $topDn])) {
1339       LStemplate :: assign('LSaccess',self :: $LSaccess[self :: $topDn]);
1340     }
1341     
1342     // Niveau
1343     $listTopDn = self :: getSubDnLdapServer();
1344     if (is_array($listTopDn)) {
1345       asort($listTopDn);
1346       LStemplate :: assign('label_level',self :: getSubDnLabel());
1347       LStemplate :: assign('_refresh',_('Refresh'));
1348       $LSsession_topDn_index = array();
1349       $LSsession_topDn_name = array();
1350       foreach($listTopDn as $index => $name) {
1351         $LSsession_topDn_index[]  = $index;
1352         $LSsession_topDn_name[]   = $name;
1353       }
1354       LStemplate :: assign('LSsession_subDn_indexes',$LSsession_topDn_index);
1355       LStemplate :: assign('LSsession_subDn_names',$LSsession_topDn_name);
1356       LStemplate :: assign('LSsession_subDn',self :: $topDn);
1357       LStemplate :: assign('LSsession_subDnName',self :: getSubDnName());
1358     }
1359     
1360     LStemplate :: assign('LSlanguages',self :: getLangList());
1361     LStemplate :: assign('LSlang',self :: $lang);
1362     LStemplate :: assign('LSencoding',self :: $encoding);
1363     LStemplate :: assign('lang_label',_('Language'));
1364     
1365     LStemplate :: assign('displayLogoutBtn',LSauth :: displayLogoutBtn());
1366     LStemplate :: assign('displaySelfAccess',LSauth :: displaySelfAccess());
1367
1368     // Infos
1369     if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1370       $txt_infos="<ul>\n";
1371       foreach($_SESSION['LSsession_infos'] as $info) {
1372         $txt_infos.="<li>$info</li>\n";
1373       }
1374       $txt_infos.="</ul>\n";
1375       LStemplate :: assign('LSinfos',$txt_infos);
1376       $_SESSION['LSsession_infos']=array();
1377     }
1378     
1379     if (self :: $ajaxDisplay) {
1380       LStemplate :: assign('LSerror_txt',LSerror :: getErrors());
1381       LStemplate :: assign('LSdebug_txt',LSdebug_print(true));
1382     }
1383     else {
1384       LSerror :: display();
1385       LSdebug_print();
1386     }
1387     if (!self :: $template)
1388       self :: setTemplate('empty.tpl');
1389       
1390     LStemplate :: assign('connected_as',_("Connected as"));
1391     
1392     LStemplate :: display(self :: $template);
1393   }
1394   
1395  /**
1396   * Défini que l'affichage se fera ou non via un retour Ajax
1397   * 
1398   * @param[in] $val boolean True pour que l'affichage se fasse par un retour
1399   *                         Ajax, false sinon
1400   * @retval void
1401   */
1402   public static function setAjaxDisplay($val=true) {
1403     self :: $ajaxDisplay = (boolean)$val;
1404   }
1405   
1406  /**
1407   * Affiche un retour Ajax
1408   *
1409   * @retval void
1410   */
1411   public static function displayAjaxReturn($data=array()) {
1412     if (isset($data['LSredirect']) && (!LSdebugDefined()) ) {
1413       echo json_encode($data);
1414       return;
1415     }
1416     
1417     $data['LSjsConfig'] = self :: $_JSconfigParams;
1418     
1419     // Infos
1420     if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1421       $txt_infos="<ul>\n";
1422       foreach($_SESSION['LSsession_infos'] as $info) {
1423         $txt_infos.="<li>$info</li>\n";
1424       }
1425       $txt_infos.="</ul>\n";
1426       $data['LSinfos'] = $txt_infos;
1427       $_SESSION['LSsession_infos']=array();
1428     }
1429     
1430     if (LSerror :: errorsDefined()) {
1431       $data['LSerror'] = LSerror :: getErrors();
1432     }
1433
1434     if (isset($_REQUEST['imgload'])) {
1435       $data['imgload'] = $_REQUEST['imgload'];
1436     }
1437
1438     if (LSdebugDefined()) {
1439       $data['LSdebug'] = LSdebug_print(true,false);
1440     }
1441
1442     echo json_encode($data);  
1443   }
1444  
1445  /**
1446   * Retournne un template Smarty compilé
1447   *
1448   * @param[in] string $template Le template à retourner
1449   * @param[in] array $variables Variables Smarty à assigner avant l'affichage
1450   * 
1451   * @retval string Le HTML compilé du template
1452   */
1453   public static function fetchTemplate($template,$variables=array()) {
1454     foreach($variables as $name => $val) {
1455       LStemplate :: assign($name,$val);
1456     }
1457     return LStemplate :: fetch($template);
1458   }
1459   
1460   /**
1461    * Charge les droits LS de l'utilisateur
1462    * 
1463    * @retval boolean True si le chargement Ã  réussi, false sinon.
1464    **/
1465   private static function loadLSprofiles() {
1466     if (is_array(self :: $ldapServer['LSprofiles'])) {
1467       foreach (self :: $ldapServer['LSprofiles'] as $profile => $profileInfos) {
1468         if (is_array($profileInfos)) {
1469           foreach ($profileInfos as $topDn => $rightsInfos) {
1470             /*
1471              * If $topDn == 'LSobject', we search for each LSobject type to find
1472              * all items on witch the user will have powers.
1473              */
1474             if ($topDn == 'LSobjects') {
1475               if (is_array($rightsInfos)) {
1476                 foreach ($rightsInfos as $LSobject => $listInfos) {
1477                   if (self :: loadLSclass('LSsearch')) {
1478                     if (isset($listInfos['filter'])) {
1479                       $filter = self :: getLSuserObject() -> getFData($listInfos['filter']);
1480                     }
1481                     else {
1482                       $filter = '('.$listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']).')';
1483                     }
1484                     
1485                     $params = array (
1486                       'basedn' => (isset($listInfos['basedn'])?$listInfos['basedn']:null),
1487                       'filter' => $filter
1488                     );
1489                     
1490                     if (isset($listInfos['params']) && is_array($listInfos['params'])) {
1491                       $params = array_merge($listInfos['params'],$params);
1492                     }
1493                     
1494                     $LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true);
1495                     $LSsearch -> run(false);
1496                     
1497                     self :: $LSprofiles[$profile] = $LSsearch -> listObjectsDn();
1498                   }
1499                 }
1500               }
1501               else {
1502                 LSdebug('LSobjects => [] doit etre un tableau');
1503               }
1504             }
1505             else {
1506               if (is_array($rightsInfos)) {
1507                 foreach($rightsInfos as $dn => $conf) {
1508                   if ((isset($conf['attr'])) && (isset($conf['LSobject']))) {
1509                     if( self :: loadLSobject($conf['LSobject']) ) {
1510                       if ($object = new $conf['LSobject']()) {
1511                         if ($object -> loadData($dn)) {
1512                           $listDns=$object -> getValue($conf['attr']);
1513                           $valKey = (isset($conf['attr_value']))?$conf['attr_value']:'%{dn}';
1514                           $val = self :: getLSuserObject() -> getFData($valKey);
1515                           if (is_array($listDns)) {
1516                             if (in_array($val,$listDns)) {
1517                               self :: $LSprofiles[$profile][] = $topDn;
1518                             }
1519                           }
1520                         }
1521                         else {
1522                           LSdebug('Impossible de chargé le dn : '.$dn);
1523                         }
1524                       }
1525                       else {
1526                         LSdebug('Impossible de créer l\'objet de type : '.$conf['LSobject']);
1527                       }
1528                     }
1529                   }
1530                   else {
1531                     if (self :: $dn == $dn) {
1532                       self :: $LSprofiles[$profile][] = $topDn;
1533                     }
1534                   }
1535                 }
1536               }
1537               else {
1538                 if ( self :: $dn == $rightsInfos ) {
1539                   self :: $LSprofiles[$profile][] = $topDn;
1540                 }
1541               }
1542             } // fin else ($topDn == 'LSobjects')
1543           } // fin foreach($profileInfos)
1544         } // fin is_array($profileInfos)
1545       } // fin foreach LSprofiles
1546       LSdebug(self :: $LSprofiles);
1547       return true;
1548     }
1549     else {
1550       return;
1551     }
1552   }
1553   
1554   /**
1555    * Charge les droits d'accès de l'utilisateur pour construire le menu de l'interface
1556    *
1557    * @retval void
1558    */
1559   private static function loadLSaccess() {
1560     $LSaccess=array();
1561     if (isset(self :: $ldapServer['subDn']) && is_array(self :: $ldapServer['subDn'])) {
1562       foreach(self :: $ldapServer['subDn'] as $name => $config) {
1563         if ($name=='LSobject') {
1564           if (is_array($config)) {
1565
1566             // Définition des subDns 
1567             foreach($config as $objectType => $objectConf) {
1568               if (self :: loadLSobject($objectType)) {
1569                 if ($subdnobject = new $objectType()) {
1570                   $tbl = $subdnobject -> getSelectArray(NULL,self::getRootDn(),NULL,NULL,false);
1571                   if (is_array($tbl)) {
1572                     // Définition des accès
1573                     $access=array();
1574                     if (is_array($objectConf['LSobjects'])) {
1575                       foreach($objectConf['LSobjects'] as $type) {
1576                         if (self :: loadLSobject($type)) {
1577                           if (self :: canAccess($type)) {
1578                             $access[$type] = LSconfig :: get('LSobjects.'.$type.'.label');
1579                           }
1580                         }
1581                       }
1582                     }
1583                     foreach($tbl as $dn => $dn_name) {
1584                       $LSaccess[$dn]=$access;
1585                     }
1586                   }
1587                 }
1588               }
1589             }
1590           }
1591         }
1592         else {
1593           if ((isCompatibleDNs(self :: $ldapServer['ldap_config']['basedn'],$config['dn']))&&($config['dn']!='')) {
1594             $access=array();
1595             if (is_array($config['LSobjects'])) {
1596               foreach($config['LSobjects'] as $objectType) {
1597                 if (self :: loadLSobject($objectType)) {
1598                   if (self :: canAccess($objectType)) {
1599                     $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1600                   }
1601                 }
1602               }
1603             }
1604             $LSaccess[$config['dn']]=$access;
1605           }
1606         }
1607       }
1608     }
1609     else {
1610       if(is_array(self :: $ldapServer['LSaccess'])) {
1611         $access=array();
1612         foreach(self :: $ldapServer['LSaccess'] as $objectType) {
1613           if (self :: loadLSobject($objectType)) {
1614             if (self :: canAccess($objectType)) {
1615                 $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1616             }
1617           }
1618         }
1619         $LSaccess[self :: $topDn] = $access;
1620       }
1621     }
1622     if (LSauth :: displaySelfAccess()) {
1623       foreach($LSaccess as $dn => $access) {
1624         $LSaccess[$dn] = array_merge(
1625           array(
1626             'SELF' => 'My account'
1627           ),
1628           $access
1629         );
1630       }
1631     }
1632     self :: $LSaccess = $LSaccess;
1633     $_SESSION['LSsession']['LSaccess'] = $LSaccess;
1634   }
1635   
1636   /**
1637    * Dit si l'utilisateur est du profil pour le DN spécifié
1638    *
1639    * @param[in] string $profile de l'objet
1640    * @param[in] string $dn DN de l'objet
1641    * 
1642    * @retval boolean True si l'utilisateur est du profil sur l'objet, false sinon.
1643    */
1644   public static function isLSprofile($dn,$profile) {
1645     if (is_array(self :: $LSprofiles[$profile])) {
1646       foreach(self :: $LSprofiles[$profile] as $topDn) {
1647         if($dn == $topDn) {
1648           return true;
1649         }
1650         else if ( isCompatibleDNs($dn,$topDn) ) {
1651           return true;
1652         }
1653       }
1654     }
1655     return;
1656   }
1657   
1658   /**
1659    * Retourne qui est l'utilisateur par rapport Ã  l'object
1660    *
1661    * @param[in] string Le DN de l'objet
1662    * 
1663    * @retval string 'admin'/'self'/'user' pour Admin , l'utilisateur lui même ou un simple utilisateur
1664    */
1665   public static function whoami($dn) {
1666     $retval = array('user');
1667     
1668     foreach(self :: $LSprofiles as $profile => $infos) {
1669       if(self :: isLSprofile($dn,$profile)) {
1670        $retval[]=$profile;
1671       }
1672     }
1673     
1674     if (self :: $dn == $dn) {
1675       $retval[]='self';
1676     }
1677     
1678     return $retval;
1679   }
1680   
1681   /**
1682    * Retourne le droit de l'utilisateur Ã  accèder Ã  un objet
1683    * 
1684    * @param[in] string $LSobject Le type de l'objet
1685    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1686    * @param[in] string $right Le type de droit d'accès Ã  tester ('r'/'w')
1687    * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1688    *
1689    * @retval boolean True si l'utilisateur a accès, false sinon
1690    */
1691   public static function canAccess($LSobject,$dn=NULL,$right=NULL,$attr=NULL) {
1692     if (!self :: loadLSobject($LSobject)) {
1693       return;
1694     }
1695     if ($dn) {
1696       $whoami = self :: whoami($dn);
1697       if ($dn==self :: getLSuserObject() -> getValue('dn')) {
1698         if (!self :: in_menu('SELF')) {
1699           return;
1700         }
1701       }
1702       else {
1703         $obj = new $LSobject();
1704         $obj -> dn = $dn;
1705         if (!self :: in_menu($LSobject,$obj -> subDnValue)) {
1706           return;
1707         }
1708       }
1709     }
1710     else {
1711       $objectdn=LSconfig :: get('LSobjects.'.$LSobject.'.container_dn').','.self :: $topDn;
1712       $whoami = self :: whoami($objectdn);
1713     }
1714     
1715     // Pour un attribut particulier
1716     if ($attr) {
1717       if ($attr=='rdn') {
1718         $attr=LSconfig :: get('LSobjects.'.$LSobject.'.rdn');
1719       }
1720       if (!is_array(LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr))) {
1721         return;
1722       }
1723
1724       $r = 'n';
1725       foreach($whoami as $who) {
1726         $nr = LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr.'.rights.'.$who);
1727         if($nr == 'w') {
1728           $r = 'w';
1729         }
1730         else if($nr == 'r') {
1731           if ($r=='n') {
1732             $r='r';
1733           }
1734         }
1735       }
1736       
1737       if (($right=='r')||($right=='w')) {
1738         if ($r==$right) {
1739           return true;
1740         }
1741         return;
1742       }
1743       else {
1744         if ( ($r=='r') || ($r=='w') ) {
1745           return true;
1746         }
1747         return;
1748       }
1749     }
1750     
1751     // Pour un attribut quelconque
1752     $attrs_conf=LSconfig :: get('LSobjects.'.$LSobject.'.attrs');
1753     if (is_array($attrs_conf)) {
1754       if (($right=='r')||($right=='w')) {
1755         foreach($whoami as $who) {
1756           foreach ($attrs_conf as $attr_name => $attr_config) {
1757             if (isset($attr_config['rights'][$who]) && $attr_config['rights'][$who]==$right) {
1758               return true;
1759             }
1760           }
1761         }
1762       }
1763       else {
1764         foreach($whoami as $who) {
1765           foreach ($attrs_conf as $attr_name => $attr_config) {
1766             if ( (isset($attr_config['rights'][$who])) && ( ($attr_config['rights'][$who]=='r') || ($attr_config['rights'][$who]=='w') ) ) {
1767               return true;
1768             }
1769           }
1770         }
1771       }
1772     }
1773     return;
1774   }
1775   
1776   /**
1777    * Retourne le droit de l'utilisateur Ã  editer Ã  un objet
1778    * 
1779    * @param[in] string $LSobject Le type de l'objet
1780    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1781    * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1782    *
1783    * @retval boolean True si l'utilisateur a accès, false sinon
1784    */
1785   public static function canEdit($LSobject,$dn=NULL,$attr=NULL) {
1786     return self :: canAccess($LSobject,$dn,'w',$attr);
1787   }
1788
1789   /**
1790    * Retourne le droit de l'utilisateur Ã  supprimer un objet
1791    * 
1792    * @param[in] string $LSobject Le type de l'objet
1793    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1794    *
1795    * @retval boolean True si l'utilisateur a accès, false sinon
1796    */  
1797   public static function canRemove($LSobject,$dn) {
1798     return self :: canAccess($LSobject,$dn,'w','rdn');
1799   }
1800   
1801   /**
1802    * Retourne le droit de l'utilisateur Ã  créer un objet
1803    * 
1804    * @param[in] string $LSobject Le type de l'objet
1805    *
1806    * @retval boolean True si l'utilisateur a accès, false sinon
1807    */    
1808   public static function canCreate($LSobject) {
1809     if (!self :: loadLSobject($LSobject)) {
1810       return;
1811     }
1812     if (LSconfig :: get("LSobjects.$LSobject.disable_creation")) {
1813       return;
1814     }
1815     return self :: canAccess($LSobject,NULL,'w','rdn');
1816   }
1817   
1818   /**
1819    * Retourne le droit de l'utilisateur Ã  gérer la relation d'objet
1820    * 
1821    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1822    * @param[in] string $LSobject Le type de l'objet
1823    * @param[in] string $relationName Le nom de la relation avec l'objet
1824    * @param[in] string $right Le type de droit a vérifier ('r' ou 'w')
1825    *
1826    * @retval boolean True si l'utilisateur a accès, false sinon
1827    */
1828   public static function relationCanAccess($dn,$LSobject,$relationName,$right=NULL) {
1829     $relConf=LSconfig :: get('LSobjects.'.$LSobject.'.LSrelation.'.$relationName);
1830     if (!is_array($relConf))
1831       return;
1832     $whoami = self :: whoami($dn);
1833
1834     if (($right=='w') || ($right=='r')) {
1835       $r = 'n';
1836       foreach($whoami as $who) {
1837         $nr = ((isset($relConf['rights'][$who]))?$relConf['rights'][$who]:'');
1838         if($nr == 'w') {
1839           $r = 'w';
1840         }
1841         else if($nr == 'r') {
1842           if ($r=='n') {
1843             $r='r';
1844           }
1845         }
1846       }
1847       
1848       if ($r == $right) {
1849         return true;
1850       }
1851     }
1852     else {
1853       foreach($whoami as $who) {
1854         if ((isset($relConf['rights'][$who])) && ( ($relConf['rights'][$who] == 'w') || ($relConf['rights'][$who] == 'r') ) ) {
1855           return true;
1856         }
1857       }
1858     }
1859     return;
1860   }
1861
1862   /**
1863    * Retourne le droit de l'utilisateur Ã  modifier la relation d'objet
1864    * 
1865    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1866    * @param[in] string $LSobject Le type de l'objet
1867    * @param[in] string $relationName Le nom de la relation avec l'objet
1868    *
1869    * @retval boolean True si l'utilisateur a accès, false sinon
1870    */  
1871   public static function relationCanEdit($dn,$LSobject,$relationName) {
1872     return self :: relationCanAccess($dn,$LSobject,$relationName,'w');
1873   }
1874
1875   /**
1876    * Retourne le droit de l'utilisateur a executer une customAction
1877    * 
1878    * @param[in] string $dn Le DN de l'objet
1879    * @param[in] string $LSobject Le type de l'objet
1880    * @param[in] string $customActionName Le nom de la customAction
1881    *
1882    * @retval boolean True si l'utilisateur peut executer cette customAction, false sinon
1883    */
1884   public static function canExecuteCustomAction($dn,$LSobject,$customActionName) {
1885     $conf=LSconfig :: get('LSobjects.'.$LSobject.'.customActions.'.$customActionName);
1886     if (!is_array($conf))
1887       return;
1888     $whoami = self :: whoami($dn);
1889
1890     if (isset($conf['rights']) && is_array($conf['rights'])) {
1891       foreach($whoami as $who) {
1892         if (in_array($who,$conf['rights'])) {
1893           return True;
1894         }
1895       }
1896     }
1897     
1898     return;
1899   }
1900
1901   /**
1902    * Ajoute un fichier temporaire
1903    * 
1904    * @author Benjamin Renard <brenard@easter-eggs.com>
1905    * 
1906    * @retval void
1907    **/
1908   public static function addTmpFile($value,$filePath) {
1909     $hash = mhash(MHASH_MD5,$value);
1910     self :: $tmp_file[$filePath] = $hash;
1911     $_SESSION['LSsession']['tmp_file'][$filePath] = $hash;
1912   }
1913   
1914   /**
1915    * Retourne le chemin du fichier temporaire si l'existe
1916    * 
1917    * @author Benjamin Renard <brenard@easter-eggs.com>
1918    * 
1919    * @param[in] $value La valeur du fichier
1920    * 
1921    * @retval mixed 
1922    **/
1923   public static function tmpFileExist($value) {
1924     $hash = mhash(MHASH_MD5,$value);
1925     foreach(self :: $tmp_file as $filePath => $contentHash) {
1926       if ($hash == $contentHash) {
1927         return $filePath;
1928       }
1929     }
1930     return false;
1931   }
1932   
1933   /**
1934    * Retourne le chemin du fichier temporaire
1935    * 
1936    * Retourne le chemin du fichier temporaire qu'il créera Ã  partir de la valeur
1937    * s'il n'existe pas déjà.
1938    * 
1939    * @author Benjamin Renard <brenard@easter-eggs.com>
1940    * 
1941    * @param[in] $value La valeur du fichier
1942    * 
1943    * @retval mixed 
1944    **/
1945   public static function getTmpFile($value) {
1946     $exist = self :: tmpFileExist($value);
1947     if (!$exist) {
1948       $img_path = LS_TMP_DIR .rand().'.tmp';
1949       $fp = fopen($img_path, "w");
1950       fwrite($fp, $value);
1951       fclose($fp);
1952       self :: addTmpFile($value,$img_path);
1953       return $img_path;
1954     }
1955     else {
1956       return $exist;
1957     }
1958   }
1959   
1960   /**
1961    * Supprime les fichiers temporaires
1962    * 
1963    * @author Benjamin Renard <brenard@easter-eggs.com>
1964    * 
1965    * @retval void
1966    **/
1967   public static function deleteTmpFile($filePath=NULL) {
1968     if ($filePath) {
1969         @unlink($filePath);
1970         unset(self :: $tmp_file[$filePath]);
1971         unset($_SESSION['LSsession']['tmp_file'][$filePath]);
1972     }
1973     else {
1974       foreach(self :: $tmp_file as $file => $content) {
1975         @unlink($file);
1976       }
1977       self :: $tmp_file = array();
1978       $_SESSION['LSsession']['tmp_file'] = array();
1979     }
1980   }
1981
1982   /**
1983    * Retourne true si le cache des droits est activé
1984    *
1985    * @author Benjamin Renard <brenard@easter-eggs.com>
1986    * 
1987    * @retval boolean True si le cache des droits est activé, false sinon.
1988    */
1989   public static function cacheLSprofiles() {
1990     return ( (LSconfig :: get('cacheLSprofiles')) || (self :: $ldapServer['cacheLSprofiles']) );
1991   }
1992
1993   /**
1994    * Retourne true si le cache des subDn est activé
1995    *
1996    * @author Benjamin Renard <brenard@easter-eggs.com>
1997    * 
1998    * @retval boolean True si le cache des subDn est activé, false sinon.
1999    */
2000   public static function cacheSudDn() {
2001     return ( (LSconfig :: get('cacheSubDn')) || (self :: $ldapServer['cacheSubDn']));
2002   }
2003   
2004   /**
2005    * Retourne true si le cache des recherches est activé
2006    *
2007    * @author Benjamin Renard <brenard@easter-eggs.com>
2008    * 
2009    * @retval boolean True si le cache des recherches est activé, false sinon.
2010    */
2011   public static function cacheSearch() {
2012     return ( (LSconfig :: get('cacheSearch')) || (self :: $ldapServer['cacheSearch']));
2013   }
2014   
2015   /**
2016    * Retourne le label des niveaux pour le serveur ldap courant
2017    * 
2018    * @author Benjamin Renard <brenard@easter-eggs.com>
2019    * 
2020    * @retval string Le label des niveaux pour le serveur ldap dourant
2021    */
2022   public static function getSubDnLabel() {
2023     return (self :: $ldapServer['subDnLabel']!='')?__(self :: $ldapServer['subDnLabel']):_('Level');
2024   }
2025   
2026   /**
2027    * Retourne le nom du subDn
2028    * 
2029    * @param[in] $subDn string subDn
2030    * 
2031    * @retval string Le nom du subDn ou '' sinon
2032    */
2033   public static function getSubDnName($subDn=false) {
2034     if (!$subDn) {
2035       $subDn = self :: $topDn;
2036     }
2037     if (self :: getSubDnLdapServer(false)) {
2038       if (isset(self :: $_subDnLdapServer[self :: $ldapServerId][false][$subDn])) {
2039         return self :: $_subDnLdapServer[self :: $ldapServerId][false][$subDn];
2040       }
2041     }
2042     return '';
2043   }
2044
2045   /**
2046    * L'objet est t-il utilisé pour listé les subDnS
2047    * 
2048    * @param[in] $type string Le type d'objet
2049    * 
2050    * @retval boolean true si le type d'objet est un subDnObject, false sinon
2051    */
2052   public static function isSubDnLSobject($type) {
2053     $result = false;
2054     if (isset(self :: $ldapServer['subDn']['LSobject']) && is_array(self :: $ldapServer['subDn']['LSobject'])) {
2055       foreach(self :: $ldapServer['subDn']['LSobject'] as $key => $value) {
2056         if ($key==$type) {
2057           $result=true;
2058         }
2059       }
2060     }
2061     return $result;
2062   }
2063   
2064   /**
2065    * Indique si un type d'objet est dans le menu courant
2066    * 
2067    * @retval boolean true si le type d'objet est dans le menu, false sinon
2068    */
2069   public static function in_menu($LSobject,$topDn=NULL) {
2070     if (!$topDn) {
2071       $topDn=self :: $topDn;
2072     }
2073     return isset(self :: $LSaccess[$topDn][$LSobject]);
2074   }
2075   
2076   /**
2077    * Indique si le serveur LDAP courant a des subDn
2078    * 
2079    * @retval boolean true si le serveur LDAP courant a des subDn, false sinon
2080    */
2081   public static function haveSubDn() {
2082     return (isset(self :: $ldapServer['subDn']) && is_array(self :: $ldapServer['subDn']));
2083   }
2084
2085   /**
2086    * Ajoute une information à afficher
2087    * 
2088    * @param[in] $msg string Le message à afficher
2089    * 
2090    * @retval void
2091    */
2092   public static function addInfo($msg) {
2093     $_SESSION['LSsession_infos'][]=$msg;
2094   }
2095   
2096   /**
2097    * Redirection de l'utilisateur vers une autre URL
2098    * 
2099    * @param[in] $url string L'URL
2100    * @param[in] $exit boolean Si true, l'execution script s'arrête après la redirection
2101    * 
2102    * @retval void
2103    */  
2104   public static function redirect($url,$exit=true) {
2105     LStemplate :: assign('url',$url);
2106     LStemplate :: display('redirect.tpl');
2107     if ($exit) {
2108       exit();
2109     }
2110   }
2111   
2112   /**
2113    * Retourne l'adresse mail d'emission configurée pour le serveur courant
2114    * 
2115    * @retval string Adresse mail d'emission
2116    */
2117   public static function getEmailSender() {
2118     return self :: $ldapServer['emailSender'];  
2119   }
2120   
2121   /**
2122    * Ajout d'une information d'aide
2123    * 
2124    * @param[in] $group string Le nom du groupe d'infos dans lequels ajouter
2125    *                          celle-ci
2126    * @param[in] $infos array  Tableau array(name => value) des infos
2127    * 
2128    * @retval void
2129    */
2130   public static function addHelpInfos($group,$infos) {
2131     if (is_array($infos)) {
2132       if (isset(self :: $_JSconfigParams['helpInfos'][$group]) && is_array(self :: $_JSconfigParams['helpInfos'][$group])) {
2133         self :: $_JSconfigParams['helpInfos'][$group] = array_merge(self :: $_JSconfigParams['helpInfos'][$group],$infos);
2134       }
2135       else {
2136         self :: $_JSconfigParams['helpInfos'][$group] = $infos;
2137       }
2138     }
2139   }
2140   
2141  /**
2142   * Défini les codes erreur relative à la classe LSsession
2143   * 
2144   * @retval void
2145   */  
2146   private static function defineLSerrors() {
2147     /*
2148      * Error Codes
2149      */
2150     LSerror :: defineError('LSsession_01',
2151     _("LSsession : The constant %{const} is not defined.")
2152     );
2153     LSerror :: defineError('LSsession_02',
2154     _("LSsession : The %{addon} support is uncertain. Verify system compatibility and the add-on configuration.")
2155     );
2156     LSerror :: defineError('LSsession_03',
2157     _("LSsession : LDAP server's configuration data are invalid. Can't connect.")
2158     );
2159     LSerror :: defineError('LSsession_04',
2160     _("LSsession : Failed to load LSobject type %{type} : unknon type.")
2161     );
2162     LSerror :: defineError('LSsession_05',
2163     _("LSsession : Failed to load LSclass %{class}.")
2164     );
2165     LSerror :: defineError('LSsession_06',
2166     _("LSsession : Login or password incorrect.")
2167     );
2168     LSerror :: defineError('LSsession_07',
2169     _("LSsession : Impossible to identify you : Duplication of identities.")
2170     );
2171     LSerror :: defineError('LSsession_08',
2172     _("LSsession : Can't load class of authentification (%{class}).")
2173     );
2174     LSerror :: defineError('LSsession_09',
2175     _("LSsession : Can't connect to LDAP server.")
2176     );
2177     LSerror :: defineError('LSsession_10',
2178     _("LSsession : Impossible to authenticate you.")
2179     );
2180     LSerror :: defineError('LSsession_11',
2181     _("LSsession : Your are not authorized to do this action.")
2182     );
2183     LSerror :: defineError('LSsession_12',
2184     _("LSsession : Some informations are missing to display this page.")
2185     );
2186     LSerror :: defineError('LSsession_13',
2187     _("LSsession : The function of the custom action %{name} does not exists or is not configured.")
2188     );
2189     // 14 -> 16 : not yet used
2190     LSerror :: defineError('LSsession_17',
2191     _("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})")
2192     );
2193     LSerror :: defineError('LSsession_18',
2194     _("LSsession : The password recovery is disabled for this LDAP server.")
2195     );
2196     LSerror :: defineError('LSsession_19',
2197     _("LSsession : Some informations are missing to recover your password. Contact administrators.")
2198     );
2199     LSerror :: defineError('LSsession_20',
2200     _("LSsession : Error during password recovery. Contact administrators.(Step : %{step})")
2201     );
2202     // 21 : not yet used
2203     LSerror :: defineError('LSsession_22',
2204     _("LSsession : problem during initialisation.")
2205     );
2206   }
2207
2208   /**
2209    * Ajax method when change ldapserver on login form
2210    * 
2211    * @param[in] $data array The return data address
2212    * 
2213    * @retval void
2214    **/
2215   public static function ajax_onLdapServerChangedLogin(&$data) {  
2216     if ( isset($_REQUEST['server']) ) {
2217       self :: setLdapServer($_REQUEST['server']);
2218       $data = array();
2219       if ( self :: LSldapConnect() ) {
2220         if (session_id()=="") session_start();
2221         if (isset($_SESSION['LSsession_topDn'])) {
2222           $sel = $_SESSION['LSsession_topDn'];
2223         }
2224         else {
2225           $sel = NULL;
2226         }
2227         $list = self :: getSubDnLdapServerOptions($sel,true);
2228         if (is_string($list)) {
2229           $data['list_topDn'] = "<select name='LSsession_topDn' id='LSsession_topDn'>".$list."</select>";
2230           $data['subDnLabel'] = self :: getSubDnLabel();
2231         }
2232       }
2233       $data['recoverPassword'] = isset(self :: $ldapServer['recoverPassword']);
2234     }
2235   }
2236   
2237   /**
2238    * Ajax method when change ldapserver on recoverPassword form
2239    * 
2240    * @param[in] $data array The return data address
2241    * 
2242    * @retval void
2243    **/
2244   public static function ajax_onLdapServerChangedRecoverPassword(&$data) {  
2245     if ( isset($_REQUEST['server']) ) {
2246       self :: setLdapServer($_REQUEST['server']);
2247       $data=array('recoverPassword' => isset(self :: $ldapServer['recoverPassword']));
2248     }
2249   }
2250 }
2251
2252 ?>