dolibarr 18.0.6
modGeneratePassPerso.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2006-2011 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2014 Teddy Andreotti <125155@supinfo.com>
4 * Copyright (C) 2017 Regis Houssin <regis.houssin@inodbox.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 * or see https://www.gnu.org/
19 */
20
27require_once DOL_DOCUMENT_ROOT.'/core/modules/security/generate/modules_genpassword.php';
28
29
34{
38 public $id;
39
40 public $picto = 'fa-shield-alt';
41
47 public $length;
48
54 public $length2;
55
56 public $NbMaj;
57 public $NbNum;
58 public $NbSpe;
59 public $NbRepeat;
60
66 public $WithoutAmbi = 0;
67
71 public $db;
72
73 public $conf;
74 public $lang;
75 public $user;
76
77 public $Maj;
78 public $Min;
79 public $Nb;
80 public $Spe;
81 public $Ambi;
82 public $All;
83
92 public function __construct($db, $conf, $langs, $user)
93 {
94 $this->id = "Perso";
95 $this->length = $langs->trans("SetupPerso");
96
97 $this->db = $db;
98 $this->conf = $conf;
99 $this->langs = $langs;
100 $this->user = $user;
101
102 if (empty($conf->global->USER_PASSWORD_PATTERN)) {
103 // default value at auto generation (12 chars, 1 uppercase, 1 digit, 0 special char, 3 repeat max, exclude ambiguous characters).
104 dolibarr_set_const($db, "USER_PASSWORD_PATTERN", '12;1;1;0;3;1', 'chaine', 0, '', $conf->entity);
105 }
106
107 $this->Maj = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
108 $this->Min = strtolower($this->Maj);
109 $this->Nb = "0123456789";
110 $this->Spe = "!@#$%&*()_-+={}[]\\|:;'/";
111 $this->Ambi = array("1", "I", "l", "|", "O", "0");
112
113 $tabConf = explode(";", $conf->global->USER_PASSWORD_PATTERN);
114 $this->length2 = $tabConf[0];
115 $this->NbMaj = $tabConf[1];
116 $this->NbNum = $tabConf[2];
117 $this->NbSpe = $tabConf[3];
118 $this->NbRepeat = $tabConf[4];
119 $this->WithoutAmbi = $tabConf[5];
120 }
121
127 private function initAll()
128 {
129 if ($this->WithoutAmbi) {
130 $this->Maj = str_replace($this->Ambi, "", $this->Maj);
131 $this->Min = str_replace($this->Ambi, "", $this->Min);
132 $this->Nb = str_replace($this->Ambi, "", $this->Nb);
133 $this->Spe = str_replace($this->Ambi, "", $this->Spe);
134 }
135
136 $pattern = $this->Min.(!empty($this->NbMaj) ? $this->Maj : '').(!empty($this->NbNum) ? $this->Nb : '').(!empty($this->NbSpe) ? $this->Spe : '');
137 $this->All = str_shuffle($pattern);
138 }
139
145 public function getDescription()
146 {
147 global $langs;
148 return $langs->trans("PasswordGenerationPerso");
149 }
150
156 public function getExample()
157 {
158 return $this->getNewGeneratedPassword();
159 }
160
166 public function getNewGeneratedPassword()
167 {
168 $this->initAll();
169
170 $pass = "";
171 for ($i = 0; $i < $this->NbMaj; $i++) {
172 // Y
173 $pass .= $this->Maj[mt_rand(0, strlen($this->Maj) - 1)];
174 }
175
176 for ($i = 0; $i < $this->NbNum; $i++) {
177 // X
178 $pass .= $this->Nb[mt_rand(0, strlen($this->Nb) - 1)];
179 }
180
181 for ($i = 0; $i < $this->NbSpe; $i++) {
182 // @
183 $pass .= $this->Spe[mt_rand(0, strlen($this->Spe) - 1)];
184 }
185
186 for ($i = strlen($pass); $i < $this->length2; $i++) {
187 // y
188 $pass .= $this->All[mt_rand(0, strlen($this->All) - 1)];
189 }
190
191 $pass = str_shuffle($pass);
192
193 if ($this->validatePassword($pass)) {
194 return $pass;
195 }
196
197 return $this->getNewGeneratedPassword(); // warning, may generate infinite loop if conditions are not possible
198 }
199
207 public function validatePassword($password)
208 {
209 global $langs;
210
211 $this->initAll(); // For the case this method is called alone
212
213 $password_a = preg_split('//u', $password, null, PREG_SPLIT_NO_EMPTY);
214 $maj = preg_split('//u', $this->Maj, null, PREG_SPLIT_NO_EMPTY);
215 $num = preg_split('//u', $this->Nb, null, PREG_SPLIT_NO_EMPTY);
216 $spe = preg_split('//u', $this->Spe, null, PREG_SPLIT_NO_EMPTY);
217 /*
218 $password_a = str_split($password);
219 $maj = str_split($this->Maj);
220 $num = str_split($this->Nb);
221 $spe = str_split($this->Spe);
222 */
223
224 if (dol_strlen($password) < $this->length2) {
225 $langs->load("other");
226 $this->error = $langs->trans("YourPasswordMustHaveAtLeastXChars", $this->length2);
227 return 0;
228 }
229
230 if (count(array_intersect($password_a, $maj)) < $this->NbMaj) {
231 $langs->load("other");
232 $this->error = $langs->trans('PasswordNeedAtLeastXUpperCaseChars', $this->NbMaj);
233 return 0;
234 }
235
236 if (count(array_intersect($password_a, $num)) < $this->NbNum) {
237 $langs->load("other");
238 $this->error = $langs->trans('PasswordNeedAtLeastXDigitChars', $this->NbNum);
239 return 0;
240 }
241
242 if (count(array_intersect($password_a, $spe)) < $this->NbSpe) {
243 $langs->load("other");
244 $this->error = $langs->trans('PasswordNeedAtLeastXSpecialChars', $this->NbSpe);
245 return 0;
246 }
247
248 if (!$this->consecutiveIterationSameCharacter($password)) {
249 $langs->load("other");
250 $this->error = $langs->trans('PasswordNeedNoXConsecutiveChars', $this->NbRepeat);
251 return 0;
252 }
253
254 return 1;
255 }
256
263 public function consecutiveIterationSameCharacter($password)
264 {
265 $this->initAll();
266
267 if (empty($this->NbRepeat)) {
268 return true;
269 }
270
271 $char = preg_split('//u', $password, null, PREG_SPLIT_NO_EMPTY);
272
273 $last = "";
274 $count = 0;
275 foreach ($char as $c) {
276 if ($c != $last) {
277 $last = $c;
278 $count = 1;
279 //print "Char $c - count = $count\n";
280 continue;
281 }
282
283 $count++;
284 //print "Char $c - count = $count\n";
285
286 if ($count > $this->NbRepeat) {
287 return false;
288 }
289 }
290
291 return true;
292 }
293}
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
Parent class for password rules/management modules.
Class to generate a password according to personal rules.
validatePassword($password)
Validate a password.
consecutiveIterationSameCharacter($password)
Check the consecutive iterations of the same character.
__construct($db, $conf, $langs, $user)
Constructor.
getExample()
Return an example of password generated by this module.
initAll()
Init the property ->All and clean ->Maj, ->Min, ->Nb and ->Spe with list of valid chars.
getNewGeneratedPassword()
Build new password.
getDescription()
Return description of module.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
conf($dolibarr_main_document_root)
Load conf file (file must exists)
Definition inc.php:400
$conf db user
Definition repair.php:124