ILIAS  release_8 Revision v8.24
class.ilSecuritySettingsChecker.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
22{
26 public static function isPassword(string $a_passwd, ?string &$customError = null): bool
27 {
28 global $DIC;
29
30 $lng = $DIC->language();
31
33
34 // check if password is empty
35 if (empty($a_passwd)) {
36 $customError = $lng->txt('password_empty');
37 return false;
38 }
39
40 $isPassword = true;
41 $errors = [];
42
43 // check if password to short
44 if ($security->getPasswordMinLength() > 0 && strlen($a_passwd) < $security->getPasswordMinLength()) {
45 $errors[] = sprintf($lng->txt('password_to_short'), $security->getPasswordMinLength());
46 $isPassword = false;
47 }
48
49 // check if password not to long
50 // Hmmmmm, maybe we should discuss this limitation. In my opinion it is stupid to limit the password length ;-). There should only be a technical limitation (field size in database).
51 if ($security->getPasswordMaxLength() > 0 && strlen($a_passwd) > $security->getPasswordMaxLength()) {
52 $errors[] = sprintf($lng->txt('password_to_long'), $security->getPasswordMaxLength());
53 $isPassword = false;
54 }
55
56 // if password must contains Chars and Numbers
57 if ($security->isPasswordCharsAndNumbersEnabled()) {
58 $hasCharsAndNumbers = true;
59
60 // check password for existing chars
61 if (!preg_match('/[A-Za-z]+/', $a_passwd)) {
62 $hasCharsAndNumbers = false;
63 }
64
65 // check password for existing numbers
66 if (!preg_match('/[0-9]+/', $a_passwd)) {
67 $hasCharsAndNumbers = false;
68 }
69
70 if (!$hasCharsAndNumbers) {
71 $errors[] = $lng->txt('password_must_chars_and_numbers');
72 $isPassword = false;
73 }
74 }
75
76 if ($security->getPasswordNumberOfUppercaseChars() > 0) {
77 if (ilStr::strLen($a_passwd) - ilStr::strLen(
78 preg_replace('/[A-Z]/', '', $a_passwd)
79 ) < $security->getPasswordNumberOfUppercaseChars()) {
80 $errors[] = sprintf(
81 $lng->txt('password_must_contain_ucase_chars'),
82 $security->getPasswordNumberOfUppercaseChars()
83 );
84 $isPassword = false;
85 }
86 }
87
88 if ($security->getPasswordNumberOfLowercaseChars() > 0) {
89 if (ilStr::strLen($a_passwd) - ilStr::strLen(
90 preg_replace('/[a-z]/', '', $a_passwd)
91 ) < $security->getPasswordNumberOfLowercaseChars()) {
92 $errors[] = sprintf(
93 $lng->txt('password_must_contain_lcase_chars'),
94 $security->getPasswordNumberOfLowercaseChars()
95 );
96 $isPassword = false;
97 }
98 }
99
100 // if password must contains Special-Chars
101 if ($security->isPasswordSpecialCharsEnabled()) {
102 // check password for existing special-chars
103 if (!preg_match(self::getPasswordValidChars(true, true), $a_passwd)) {
104 $errors[] = $lng->txt('password_must_special_chars');
105 $isPassword = false;
106 }
107 }
108
109 // ensure password matches the positive list of chars/special-chars
110 if (!preg_match(self::getPasswordValidChars(), $a_passwd)) {
111 $errors[] = $lng->txt('password_contains_invalid_chars');
112 $isPassword = false;
113 }
114
115 // build custom error message
116 if (count($errors) == 1) {
117 $customError = $errors[0];
118 } elseif (count($errors) > 1) {
119 $customError = $lng->txt('password_multiple_errors');
120 $customError .= '<br />' . implode('<br />', $errors);
121 }
122
123 return $isPassword;
124 }
125
133 public static function getPasswordValidChars(bool $a_as_regex = true, bool $a_only_special_chars = false): ?string
134 {
135 if ($a_as_regex) {
136 if ($a_only_special_chars) {
137 return '/[_\.\+\?\#\-\*\@!\$\%\~\/\:\;]+/';
138 } else {
139 return '/^[A-Za-z0-9_\.\+\?\#\-\*\@!\$\%\~\/\:\;]+$/';
140 }
141 } else {
142 return 'A-Z a-z 0-9 _.+?#-*@!$%~/:;';
143 }
144 }
145
152 public static function isPasswordValidForUserContext(
153 string $clear_text_password,
154 $user,
155 ?string &$error_language_variable = null
156 ): bool {
157 $security = ilSecuritySettings::_getInstance();
158
159 $login = null;
160
161 if (is_string($user)) {
162 $login = $user;
163 } elseif (is_array($user)) {
164 // Try to get loginname and user_id from array
165 $login = $user['login'];
166 $userId = $user['id'];
167 } elseif ($user instanceof ilObjUser) {
168 $login = $user->getLogin();
169 $userId = $user->getId();
170 }
171
172 // The user context (user instance or id) can be used for further validation (e.g. compare a password with the users' password history, etc.) in future releases.
173
174 if ($login && (int) $security->getPasswordMustNotContainLoginnameStatus() &&
175 strpos(strtolower($clear_text_password), strtolower($login)) !== false
176 ) {
177 $error_language_variable = 'password_contains_parts_of_login_err';
178 return false;
179 }
180
181 return true;
182 }
183
190 public static function getPasswordRequirementsInfo(): string
191 {
192 global $DIC;
193
194 $lng = $DIC->language();
195
197
198 $infos = [sprintf($lng->txt('password_allow_chars'), self::getPasswordValidChars(false))];
199
200 // check if password to short
201 if ($security->getPasswordMinLength() > 0) {
202 $infos[] = sprintf($lng->txt('password_to_short'), $security->getPasswordMinLength());
203 }
204
205 // check if password not to long
206 if ($security->getPasswordMaxLength() > 0) {
207 $infos[] = sprintf($lng->txt('password_to_long'), $security->getPasswordMaxLength());
208 }
209
210 // if password must contains Chars and Numbers
211 if ($security->isPasswordCharsAndNumbersEnabled()) {
212 $infos[] = $lng->txt('password_must_chars_and_numbers');
213 }
214
215 // if password must contains Special-Chars
216 if ($security->isPasswordSpecialCharsEnabled()) {
217 $infos[] = $lng->txt('password_must_special_chars');
218 }
219
220 if ($security->getPasswordNumberOfUppercaseChars() > 0) {
221 $infos[] = sprintf(
222 $lng->txt('password_must_contain_ucase_chars'),
223 $security->getPasswordNumberOfUppercaseChars()
224 );
225 }
226
227 if ($security->getPasswordNumberOfLowercaseChars() > 0) {
228 $infos[] = sprintf(
229 $lng->txt('password_must_contain_lcase_chars'),
230 $security->getPasswordNumberOfLowercaseChars()
231 );
232 }
233
234 return implode('<br />', $infos);
235 }
236
243 public static function generatePasswords(int $a_number): array
244 {
245 $ret = [];
246 srand((int) microtime() * 1000000);
247
249
250 for ($i = 1; $i <= $a_number; $i++) {
251 $min = ($security->getPasswordMinLength() > 0)
252 ? $security->getPasswordMinLength()
253 : 6;
254 $max = ($security->getPasswordMaxLength() > 0)
255 ? $security->getPasswordMaxLength()
256 : 10;
257 if ($min > $max) {
258 $max = $max + 1;
259 }
260 $random = new ilRandom();
261 $length = $random->int($min, $max);
262 $next = $random->int(1, 2);
263 $vowels = "aeiou";
264 $vowels_uc = strtoupper($vowels);
265 $consonants = "bcdfghjklmnpqrstvwxyz";
266 $consonants_uc = strtoupper($consonants);
267 $numbers = "1234567890";
268 $special = "_.+?#-*@!$%~";
269 $pw = "";
270
271 if ($security->getPasswordNumberOfUppercaseChars() > 0) {
272 for ($j = 0; $j < $security->getPasswordNumberOfUppercaseChars(); $j++) {
273 switch ($next) {
274 case 1:
275 $pw .= $consonants_uc[$random->int(0, strlen($consonants_uc) - 1)];
276 $next = 2;
277 break;
278
279 case 2:
280 $pw .= $vowels_uc[$random->int(0, strlen($vowels_uc) - 1)];
281 $next = 1;
282 break;
283 }
284 }
285 }
286
287 if ($security->isPasswordCharsAndNumbersEnabled()) {
288 $pw .= $numbers[$random->int(0, strlen($numbers) - 1)];
289 }
290
291 if ($security->isPasswordSpecialCharsEnabled()) {
292 $pw .= $special[$random->int(0, strlen($special) - 1)];
293 }
294
295 $num_lcase_chars = max($security->getPasswordNumberOfLowercaseChars(), $length - strlen($pw));
296 for ($j = 0; $j < $num_lcase_chars; $j++) {
297 switch ($next) {
298 case 1:
299 $pw .= $consonants[$random->int(0, strlen($consonants) - 1)];
300 $next = 2;
301 break;
302
303 case 2:
304 $pw .= $vowels[$random->int(0, strlen($vowels) - 1)];
305 $next = 1;
306 break;
307 }
308 }
309
310 $pw = str_shuffle($pw);
311
312 $ret[] = $pw;
313 }
314 return $ret;
315 }
316}
User class.
Wrapper for generation of random numbers, strings, bytes.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static isPassword(string $a_passwd, ?string &$customError=null)
static getPasswordValidChars(bool $a_as_regex=true, bool $a_only_special_chars=false)
All valid chars for password.
static isPasswordValidForUserContext(string $clear_text_password, $user, ?string &$error_language_variable=null)
static getPasswordRequirementsInfo()
infotext for ilPasswordInputGUI setInfo()
static generatePasswords(int $a_number)
Generate a number of passwords.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getInstance()
Get instance of ilSecuritySettings.
static strLen(string $a_string)
Definition: class.ilStr.php:63
global $DIC
Definition: feed.php:28
$errors
Definition: imgupload.php:65
$i
Definition: metadata.php:41
$lng