LSldapObject : fix foreach error in getObjectKeyValueInRelation() if attribute is...
[ldapsaisie.git] / public_html / includes / class / class.LSformElement_password.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 LSsession :: loadLSclass('LSformElement');
24
25 /**
26  * Element password d'un formulaire pour LdapSaisie
27  *
28  * Cette classe définis les éléments password des formulaires.
29  * Elle étant la classe basic LSformElement.
30  *
31  * @author Benjamin Renard <brenard@easter-eggs.com>
32  */
33
34 class LSformElement_password extends LSformElement {
35   
36   var $fieldTemplate = 'LSformElement_password_field.tpl';
37   var $template = 'LSformElement_password.tpl';
38   
39   var $sendMail = false;
40
41   /**
42    * Recupère la valeur de l'élement passée en POST
43    *
44    * Cette méthode vérifie la présence en POST de la valeur de l'élément et la récupère
45    * pour la mettre dans le tableau passer en paramètre avec en clef le nom de l'élément
46    *
47    * @param[] array Pointeur sur le tableau qui recupèrera la valeur.
48    *
49    * @retval boolean true si la valeur est présente en POST, false sinon
50    */
51   function getPostData(&$return) {
52     // Récupère la valeur dans _POST, et les vérifie avec la fonction générale
53     $retval = parent :: getPostData($return);
54     // Si une valeur est recupérée
55     if ($retval) {
56       $val = $this -> form -> ldapObject -> attrs[$this -> name] -> getValue(); 
57       if( (empty($return[$this -> name][0]) ) && ( ! empty( $val ) ) ) {
58         unset($return[$this -> name]);
59         $this -> form -> _notUpdate[$this -> name] == true;
60         return true;
61       }
62       
63       if ($this -> verifyPassword($return[$this -> name][0]) || (empty($return[$this -> name][0]) && empty($val))) {
64         LSdebug("Password : no change");
65         unset($return[$this -> name]);
66         $this -> form -> _notUpdate[$this -> name] == true;
67         return true;
68       }
69       
70       //Mail
71
72       // Do not send mail if password is not set :
73       if (empty($return[$this -> name])) {
74         return true;
75       }
76
77       if (isset($_POST['LSformElement_password_'.$this -> name.'_send'])) {
78         if ($_POST['LSformElement_password_'.$this -> name.'_send']==1) {
79           $this -> sendMail = true;
80           LSdebug ('send by form');
81         }
82       }
83       else if (isset($this -> params['html_options']['mail']['isset']) && $this -> params['html_options']['mail']['send']==1) {
84         $this -> sendMail = true;
85         LSdebug ('send by config');
86       }
87       if ($this -> sendMail && LSsession :: loadLSaddon('mail')) {
88         $msg = $this -> params['html_options']['mail']['msg'];
89         $subject = $this -> params['html_options']['mail']['subject'];
90         if (isset($_POST['LSformElement_password_'.$this -> name.'_msg'])) {
91           $msgInfos = json_decode($_POST['LSformElement_password_'.$this -> name.'_msg']);
92           if ($msgInfos -> subject) {
93             $subject = $msgInfos -> subject;
94           }
95           if ($msgInfos -> msg) {
96             $msg = $msgInfos -> msg;
97           }
98           if ($msgInfos -> mail) {
99             $mail = $msgInfos -> mail;
100           }
101         }
102         $this -> sendMail = array (
103           'subject' => $subject,
104           'msg' => $msg,
105           'mail' => $mail,
106           'pwd' => $return[$this -> name][0]
107         );
108         $this -> attr_html -> attribute -> addObjectEvent('after_modify',$this,'send');
109       }
110     }
111     return $retval;
112   }
113
114  /**
115   * Retourne les infos d'affichage de l'élément
116   * 
117   * Cette méthode retourne les informations d'affichage de l'élement
118   *
119   * @retval array
120   */
121   function getDisplay(){
122     LSsession :: addCssFile('LSformElement_password.css');
123     $return = $this -> getLabelInfos();
124     $pwd = "";
125     if ($this -> params['html_options']['clearView'] or $this -> params['html_options']['clearEdit']) {
126       $pwd = $this -> values[0];
127     }
128     if (!$this -> isFreeze()) {
129       
130       // Help Infos
131       LSsession :: addHelpInfos(
132         'LSformElement_password',
133         array(
134           'generate' => _('Generate a password.'),
135           'verify' => _('Compare with stored password.'),
136           'view' => _('Display password.'),
137           'viewHash' => _('Display hashed password.'),
138           'hide' => _('Hide password.'),
139           'mail' => _("The password will be sent by mail if changed. Click to disable automatic notification."),
140           'nomail' => _("The password will not be sent if changed. Click to enable automatic notification."),
141           'editmail' => _("Modify the mail sent to notice the user")
142         )
143       );
144       
145       if (($this -> params['html_options']['generationTool'])&&($this -> params['html_options']['autoGenerate'])&&(empty($this -> values))) {
146         $pwd=$this->generatePassword($this -> params);
147       }
148       
149       $params = array(
150         'generate' => ($this -> params['html_options']['generationTool']==True),
151         'clearEdit' => ($this -> params['html_options']['clearEdit']==True),
152         'viewHash' => ($this -> params['html_options']['viewHash']==True),
153         'verify' => ( (!$this -> attr_html -> attribute -> ldapObject-> isNew()) && ( (isset($this -> params['html_options']['verify']) && $this -> params['html_options']['verify']) || (!isset($this -> params['html_options']['verify'])) ) )
154       );
155       if (isset($this -> params['html_options']['mail'])) {
156         $params['mail'] = $this -> params['html_options']['mail'];
157       }
158       LSsession :: addJSconfigParam($this -> name,$params);
159       
160       LSsession :: addJSscript('LSformElement_password_field.js');
161       LSsession :: addJSscript('LSformElement_password.js');
162     }
163     $return['html'] = $this -> fetchTemplate(NULL,array('pwd' => $pwd,'clearView' => $this -> params['html_options']['clearView'],'clearEdit' => $this -> params['html_options']['clearEdit']));
164     return $return;
165   }
166   
167   function generatePassword($params=NULL) {
168     if ($params['html_options']['use_pwgen']) {
169       $args=(isset($params['html_options']['pwgen_opts'])?$params['html_options']['pwgen_opts']:'');
170       $len=(isset($params['html_options']['lenght'])?$params['html_options']['lenght']:8);
171       $bin=(isset($params['html_options']['pwgen_path'])?$params['html_options']['pwgen_path']:'pwgen');
172       $cmd="$bin ".escapeshellcmd($args)." $len 1";
173       exec($cmd,$ret,$retcode);
174       LSdebug("Generate password using pwgen. Cmd : '$cmd' / Return code : $retcode / Return : ".print_r($ret,1));
175       if ($retcode==0 && count($ret)>0) {
176         return $ret[0];
177       }
178       else {
179         LSerror :: addErrorCode('LSformElement_password_03');
180       }
181     }
182     return generatePassword($params['html_options']['chars'],$params['html_options']['lenght']);
183   }
184   
185   function verifyPassword($pwd) {
186     if ($this -> attr_html -> attribute -> ldapObject -> isNew()) {
187       return false;
188     }
189     if ($this -> isLoginPassword()) {
190       return LSsession :: checkUserPwd($this -> attr_html -> attribute -> ldapObject,$pwd);
191     }
192     else {
193       $hash = $this -> attr_html -> attribute -> ldap -> encodePassword($pwd);
194       $find=false;
195       if (is_array($this -> attr_html -> attribute -> data)) {
196         $data = $this -> attr_html -> attribute -> data;
197       }
198       elseif (!is_array($this -> attr_html -> attribute -> data) && !empty($this -> attr_html -> attribute -> data)) {
199         $data = array($this -> attr_html -> attribute -> data);
200       }
201       else {
202         return $find;
203       }
204       foreach($data as $val) {
205         if ($hash == $val)
206           $find=true;
207       }
208       return $find;
209     }
210   }
211   
212   function send($params) {
213     if (is_array($this -> sendMail)) {
214       $mail = (String)$this -> sendMail['mail'];
215       Lsdebug($mail);
216       if ($mail=="") {
217         $mail_attrs = $this -> params['html_options']['mail']['mail_attr'];
218         if (!is_array($mail_attrs)) {
219           $mail_attrs=array($mail_attrs);
220         }
221         foreach($mail_attrs as $attr) {
222           $mail_attr = $this -> attr_html -> attribute -> ldapObject -> attrs[$attr];
223           if ($mail_attr instanceOf LSattribute) {
224             $mail = $mail_attr -> getValue();
225             if (!empty($mail) && checkEmail($mail[0],NULL,true)) {
226               $mail=$mail[0];
227               break;
228             }
229             else {
230               $mail="";
231             }
232           }
233           else {
234             LSdebug("L'attribut $mail_attr pour l'envoie du nouveau mot de passe n'existe pas.");
235           }
236         }
237         if ($mail=="") {
238           LSerror :: addErrorCode('LSformElement_password_01');
239           return;
240         }
241       }
242               
243       if (checkEmail($mail,NULL,true)) {
244         $this -> attr_html -> attribute -> ldapObject -> registerOtherValue('password',$this -> sendMail['pwd']);
245         $msg = $this -> attr_html -> attribute -> ldapObject -> getFData($this -> sendMail['msg']);
246         if (isset($this -> params['html_options']['mail']['headers'])) {
247           $headers = $this -> params['html_options']['mail']['headers'];
248         }
249         else {
250           $headers = array();
251         }
252         if ($this -> params['html_options']['mail']['bcc']) {
253                 $headers['Bcc']=$this -> params['html_options']['mail']['bcc'];
254         }
255         if (sendMail(
256           $mail,
257           $this -> sendMail['subject'],
258           $msg,
259           $headers
260         )) {
261           LSsession :: addInfo(_('Notice mail sent.'));
262         }
263       }
264       else {
265         LSerror :: addErrorCode('LSformElement_password_02',$mail);
266         return;
267       }
268     }
269     return true;
270   }
271   
272   public static function ajax_verifyPassword(&$data) {
273     if ((isset($_REQUEST['attribute'])) && (isset($_REQUEST['objecttype'])) && (isset($_REQUEST['fieldValue'])) && (isset($_REQUEST['idform'])) && (isset($_REQUEST['objectdn'])) ) {
274       if (LSsession ::loadLSobject($_REQUEST['objecttype'])) {
275         $object = new $_REQUEST['objecttype']();
276         $object -> loadData($_REQUEST['objectdn']);
277         $form = $object -> getForm($_REQUEST['idform']);
278         if ($form) {
279           $field=$form -> getElement($_REQUEST['attribute']);
280           if ($field) {
281             $val = $field -> verifyPassword($_REQUEST['fieldValue']);
282             $data = array(
283               'verifyPassword' => $val
284             );
285           }
286           else {
287             LSdebug('Impossible de récupérer le LSformElement');
288           }
289         }
290         else {
291           LSdebug('Impossible de recuperer le LSform.');
292         }
293       }
294     }
295   }
296   
297   public static function ajax_generatePassword(&$data) {
298     if ((isset($_REQUEST['attribute'])) && (isset($_REQUEST['objecttype'])) && (isset($_REQUEST['objectdn'])) && (isset($_REQUEST['idform'])) ) {
299       if (LSsession ::loadLSobject($_REQUEST['objecttype'])) {
300         $params = LSconfig :: get("LSobjects.".$_REQUEST['objecttype'].".attrs.".$_REQUEST['attribute']);
301         $val = self :: generatePassword($params);
302         if ( $val ) {
303           $data = array(
304             'generatePassword' => $val
305           );
306         }
307       }
308     }
309   }
310
311   public static function ajax_viewHash(&$data) {
312     if ((isset($_REQUEST['attribute'])) && (isset($_REQUEST['objecttype'])) && (isset($_REQUEST['objectdn'])) ) {
313       if (LSsession ::loadLSobject($_REQUEST['objecttype'])) {
314         $object = new $_REQUEST['objecttype']();
315         $object -> loadData($_REQUEST['objectdn']);
316         if (LSsession::canAccess($_REQUEST['objecttype'],$_REQUEST['objectdn'],null,$_REQUEST['attribute'])) {
317           $values = $object -> getValue($_REQUEST['attribute']);
318           if (is_string($values[0])) {
319             $data = array (
320               'hash' => $values[0]
321             );
322           }
323         }
324       }
325     }
326   }
327
328   public function isLoginPassword() {
329     if (!isset($this -> params['html_options']['isLoginPassword']) || $this -> params['html_options']['isLoginPassword']) {
330       return true;
331     }
332     return false;
333   }
334
335 }
336
337 /*
338  * Error Codes
339  */
340 LSerror :: defineError('LSformElement_password_01',
341 _("LSformElement_password : No contact mail available to send password.")
342 );
343 LSerror :: defineError('LSformElement_password_02',
344 _("LSformElement_password : Contact mail invalid (%{mail}). Can't send password.")
345 );
346 LSerror :: defineError('LSformElement_password_03',
347 _("LSformElement_password : Fail to exec pwgen. Check it's correctly installed.")
348 );