ILIAS  release_8 Revision v8.23
class.ilSecuritySettings.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
25 {
29 
38 
39  private static ?self $instance = null;
40  private ilDBInterface $db;
43  protected ilHTTPS $https;
44 
45  private bool $https_enable;
46 
49  public const DEFAULT_PASSWORD_MIN_LENGTH = 8;
50  public const DEFAULT_PASSWORD_MAX_LENGTH = 0;
51  public const DEFAULT_PASSWORD_MAX_AGE = 90;
52  public const DEFAULT_LOGIN_MAX_ATTEMPTS = 5;
53 
56 
57  private bool $password_chars_and_numbers_enabled = self::DEFAULT_PASSWORD_CHARS_AND_NUMBERS_ENABLED;
58  private bool $password_special_chars_enabled = self::DEFAULT_PASSWORD_SPECIAL_CHARS_ENABLED;
59  private int $password_min_length = self::DEFAULT_PASSWORD_MIN_LENGTH;
60  private int $password_max_length = self::DEFAULT_PASSWORD_MAX_LENGTH;
61  private int $password_max_age = self::DEFAULT_PASSWORD_MAX_AGE;
62  private int $password_ucase_chars_num = 0;
63  private int $password_lcase_chars_num = 0;
64  private int $login_max_attempts = self::DEFAULT_LOGIN_MAX_ATTEMPTS;
66 
67  private bool $password_change_on_first_login_enabled = self::DEFAULT_PASSWORD_CHANGE_ON_FIRST_LOGIN_ENABLED;
68  private bool $prevent_simultaneous_logins = self::DEFAULT_PREVENT_SIMULTANEOUS_LOGINS;
69 
70  private bool $protect_admin_role = false;
71 
75  private function __construct()
76  {
77  global $DIC;
78 
79  $this->db = $DIC->database();
80  $this->settings = $DIC->settings();
81  $this->review = $DIC->rbac()->review();
82  $this->https = $DIC['https'];
83 
84  $this->read();
85  }
86 
92  public static function _getInstance(): ilSecuritySettings
93  {
94  if (!self::$instance instanceof self) {
95  self::$instance = new self();
96  }
97  return self::$instance;
98  }
99 
104  public function setPasswordCharsAndNumbersEnabled(bool $a_chars_and_numbers_enabled): void
105  {
106  $this->password_chars_and_numbers_enabled = $a_chars_and_numbers_enabled;
107  }
108 
113  public function isPasswordCharsAndNumbersEnabled(): bool
114  {
116  }
117 
122  public function setPasswordSpecialCharsEnabled(bool $a_password_special_chars_enabled): void
123  {
124  $this->password_special_chars_enabled = $a_password_special_chars_enabled;
125  }
126 
131  public function isPasswordSpecialCharsEnabled(): bool
132  {
134  }
135 
139  public function setPasswordMinLength(int $a_password_min_length): void
140  {
141  $this->password_min_length = $a_password_min_length;
142  }
143 
147  public function getPasswordMinLength(): int
148  {
150  }
151 
155  public function setPasswordMaxLength(int $a_password_max_length): void
156  {
157  $this->password_max_length = $a_password_max_length;
158  }
159 
163  public function getPasswordMaxLength(): int
164  {
166  }
167 
171  public function setPasswordMaxAge(int $a_password_max_age): void
172  {
173  $this->password_max_age = $a_password_max_age;
174  }
175 
179  public function getPasswordMaxAge(): int
180  {
182  }
183 
187  public function setLoginMaxAttempts(int $a_login_max_attempts): void
188  {
189  $this->login_max_attempts = $a_login_max_attempts;
190  }
191 
195  public function getLoginMaxAttempts(): int
196  {
198  }
199 
203  public function setHTTPSEnabled(bool $value): void
204  {
205  $this->https_enable = $value;
206  }
207 
211  public function isHTTPSEnabled(): bool
212  {
213  return $this->https_enable;
214  }
215 
220  public function setPasswordChangeOnFirstLoginEnabled(bool $a_password_change_on_first_login_enabled): void
221  {
222  $this->password_change_on_first_login_enabled = $a_password_change_on_first_login_enabled;
223  }
224 
229  public function isPasswordChangeOnFirstLoginEnabled(): bool
230  {
232  }
233 
234  public function isAdminRoleProtected(): bool
235  {
236  return (bool) $this->protect_admin_role;
237  }
238 
239  public function protectedAdminRole(bool $a_stat): void
240  {
241  $this->protect_admin_role = $a_stat;
242  }
243 
247  public function checkAdminRoleAccessible(int $a_usr_id): bool
248  {
249  if (!$this->isAdminRoleProtected()) {
250  return true;
251  }
252  if ($this->review->isAssigned($a_usr_id, SYSTEM_ROLE_ID)) {
253  return true;
254  }
255  return false;
256  }
257 
261  public function save(): void
262  {
263  $this->settings->set('https', (string) $this->isHTTPSEnabled());
264 
265  $this->settings->set('ps_password_chars_and_numbers_enabled', (string) $this->isPasswordCharsAndNumbersEnabled());
266  $this->settings->set('ps_password_special_chars_enabled', (string) $this->isPasswordSpecialCharsEnabled());
267  $this->settings->set('ps_password_min_length', (string) $this->getPasswordMinLength());
268  $this->settings->set('ps_password_max_length', (string) $this->getPasswordMaxLength());
269  $this->settings->set('ps_password_max_age', (string) $this->getPasswordMaxAge());
270  $this->settings->set('ps_login_max_attempts', (string) $this->getLoginMaxAttempts());
271  $this->settings->set('ps_password_uppercase_chars_num', (string) $this->getPasswordNumberOfUppercaseChars());
272  $this->settings->set('ps_password_lowercase_chars_num', (string) $this->getPasswordNumberOfLowercaseChars());
273  $this->settings->set(
274  'ps_password_must_not_contain_loginame',
276  );
277 
278  $this->settings->set(
279  'ps_password_change_on_first_login_enabled',
280  (string) $this->isPasswordChangeOnFirstLoginEnabled()
281  );
282  $this->settings->set('ps_prevent_simultaneous_logins', (string) $this->isPreventionOfSimultaneousLoginsEnabled());
283  $this->settings->set('ps_protect_admin', (string) $this->isAdminRoleProtected());
284  }
285 
291  private function read(): void
292  {
293  $query = "SELECT object_reference.ref_id FROM object_reference,tree,object_data " .
294  "WHERE tree.parent = " . $this->db->quote(SYSTEM_FOLDER_ID, 'integer') . " " .
295  "AND object_data.type = 'ps' " .
296  "AND object_reference.ref_id = tree.child " .
297  "AND object_reference.obj_id = object_data.obj_id";
298  $res = $this->db->query($query);
299  $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
300 
301  $this->https_enable = (bool) $this->settings->get('https', null);
302 
303  $this->password_chars_and_numbers_enabled = (bool) $this->settings->get(
304  'ps_password_chars_and_numbers_enabled',
305  (string) self::DEFAULT_PASSWORD_CHARS_AND_NUMBERS_ENABLED
306  );
307  $this->password_special_chars_enabled = (bool) $this->settings->get(
308  'ps_password_special_chars_enabled',
309  (string) self::DEFAULT_PASSWORD_SPECIAL_CHARS_ENABLED
310  );
311  $this->password_min_length = (int) $this->settings->get(
312  'ps_password_min_length',
313  (string) self::DEFAULT_PASSWORD_MIN_LENGTH
314  );
315  $this->password_max_length = (int) $this->settings->get(
316  'ps_password_max_length',
317  (string) self::DEFAULT_PASSWORD_MAX_LENGTH
318  );
319  $this->password_max_age = (int) $this->settings->get('ps_password_max_age', (string) self::DEFAULT_PASSWORD_MAX_AGE);
320  $this->login_max_attempts = (int) $this->settings->get(
321  'ps_login_max_attempts',
322  (string) self::DEFAULT_LOGIN_MAX_ATTEMPTS
323  );
324  $this->password_ucase_chars_num = (int) $this->settings->get('ps_password_uppercase_chars_num', "0");
325  $this->password_lcase_chars_num = (int) $this->settings->get('ps_password_lowercase_chars_num', "0");
326  $this->password_must_not_contain_loginname = (bool) $this->settings->get(
327  'ps_password_must_not_contain_loginame',
328  null
329  );
330  $this->password_change_on_first_login_enabled = (bool) $this->settings->get(
331  'ps_password_change_on_first_login_enabled',
332  (string) self::DEFAULT_PASSWORD_CHANGE_ON_FIRST_LOGIN_ENABLED
333  );
334  $this->prevent_simultaneous_logins = (bool) $this->settings->get(
335  'ps_prevent_simultaneous_logins',
336  (string) self::DEFAULT_PREVENT_SIMULTANEOUS_LOGINS
337  );
338  $this->protect_admin_role = (bool) $this->settings->get('ps_protect_admin', (string) $this->protect_admin_role);
339  }
340 
346  public function validate(ilPropertyFormGUI $a_form = null): ?int
347  {
348  $code = null;
349 
350  if ($this->isHTTPSEnabled()) {
351  if (!$this->https->checkHTTPS()) {
353  if (!$a_form) {
354  return $code;
355  } else {
356  $a_form->getItemByPostVar('https_enabled')
357  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
358  }
359  }
360  }
361 
362  if ($this->getPasswordMinLength() < 0) {
363  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MIN_LENGTH;
364  if (!$a_form) {
365  return $code;
366  } else {
367  $a_form->getItemByPostVar('password_min_length')
368  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
369  }
370  }
371 
372  if ($this->getPasswordMaxLength() < 0) {
373  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MAX_LENGTH;
374  if (!$a_form) {
375  return $code;
376  } else {
377  $a_form->getItemByPostVar('password_max_length')
378  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
379  }
380  }
381 
382  $password_min_length = 1;
383  $password_min_length_error_code = null;
384 
385  if ($this->getPasswordNumberOfUppercaseChars() > 0 || $this->getPasswordNumberOfLowercaseChars() > 0) {
386  $password_min_length = 0;
387  if ($this->getPasswordNumberOfUppercaseChars() > 0) {
388  $password_min_length += $this->getPasswordNumberOfUppercaseChars();
389  }
390  if ($this->getPasswordNumberOfLowercaseChars() > 0) {
391  $password_min_length += $this->getPasswordNumberOfLowercaseChars();
392  }
393  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN1;
394  }
395 
396  if ($this->isPasswordCharsAndNumbersEnabled()) {
397  $password_min_length++;
398  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN2;
399 
400  if ($this->isPasswordSpecialCharsEnabled()) {
401  $password_min_length++;
402  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN3;
403  }
404  } elseif ($password_min_length > 1 && $this->isPasswordSpecialCharsEnabled()) {
405  $password_min_length++;
406  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN3;
407  }
408 
409  if ($this->getPasswordMinLength() > 0 && $this->getPasswordMinLength() < $password_min_length) {
410  $code = $password_min_length_error_code;
411  if (!$a_form) {
412  return $code;
413  } else {
414  $a_form->getItemByPostVar('password_min_length')
415  ->setAlert(sprintf(ilObjPrivacySecurityGUI::getErrorMessage($code), $password_min_length));
416  }
417  }
418  if ($this->getPasswordMaxLength() > 0 && $this->getPasswordMaxLength() < $this->getPasswordMinLength()) {
419  $code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MAX_LENGTH_LESS_MIN_LENGTH;
420  if (!$a_form) {
421  return $code;
422  } else {
423  $a_form->getItemByPostVar('password_max_length')
424  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
425  }
426  }
427  if ($this->getPasswordMaxAge() < 0) {
428  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MAX_AGE;
429  if (!$a_form) {
430  return $code;
431  } else {
432  $a_form->getItemByPostVar('password_max_age')
433  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
434  }
435  }
436 
437  if ($this->getLoginMaxAttempts() < 0) {
438  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_LOGIN_MAX_ATTEMPTS;
439  if (!$a_form) {
440  return $code;
441  } else {
442  $a_form->getItemByPostVar('login_max_attempts')
443  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
444  }
445  }
446 
447  /*
448  * todo: have to check for local auth if first login password change is enabled??
449  * than: add errorcode
450  */
451 
452  if (!$a_form) {
453  return 0;
454  } else {
455  return $code;
456  }
457  }
458 
464  {
466  }
467 
471  public function setPreventionOfSimultaneousLogins(bool $value): void
472  {
473  $this->prevent_simultaneous_logins = $value;
474  }
475 
479  public function setPasswordNumberOfUppercaseChars(int $password_ucase_chars_num): void
480  {
481  $this->password_ucase_chars_num = $password_ucase_chars_num;
482  }
483 
488  {
490  }
491 
495  public function setPasswordNumberOfLowercaseChars(int $password_lcase_chars_num): void
496  {
497  $this->password_lcase_chars_num = $password_lcase_chars_num;
498  }
499 
504  {
506  }
507 
511  public function setPasswordMustNotContainLoginnameStatus($status): void
512  {
513  $this->password_must_not_contain_loginname = (bool) $status;
514  }
515 
520  {
522  }
523 }
$res
Definition: ltiservices.php:69
setPasswordSpecialCharsEnabled(bool $a_password_special_chars_enabled)
set if the passwords have to contain special characters
const SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN2
const SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MIN_LENGTH
checkAdminRoleAccessible(int $a_usr_id)
Check if the administrator role is accessible for a specific user.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
isHTTPSEnabled()
read access to https enabled property
const SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MAX_LENGTH
const SYSTEM_ROLE_ID
Definition: constants.php:29
setPasswordChangeOnFirstLoginEnabled(bool $a_password_change_on_first_login_enabled)
set if the passwords have to be changed by users on first login
isPasswordCharsAndNumbersEnabled()
get boolean if the passwords have to contain characters and numbers
setPasswordNumberOfLowercaseChars(int $password_lcase_chars_num)
Set number of lowercase characters required.
__construct()
Private constructor: use _getInstance()
validate(ilPropertyFormGUI $a_form=null)
validate settings
static int $SECURITY_SETTINGS_ERR_CODE_HTTP_NOT_AVAILABLE
const SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MAX_AGE
const SYSTEM_FOLDER_ID
Definition: constants.php:35
setPasswordMaxLength(int $a_password_max_length)
set the maximum length for passwords
static int $SECURITY_SETTINGS_ERR_CODE_AUTO_HTTPS
getPasswordMaxLength()
get the maximum length for passwords
setPasswordNumberOfUppercaseChars(int $password_ucase_chars_num)
Set number of uppercase characters required.
global $DIC
Definition: feed.php:28
isPasswordChangeOnFirstLoginEnabled()
get boolean if the passwords have to be changed by users on first login
getPasswordNumberOfLowercaseChars()
Returns number of lowercase characters required.
setHTTPSEnabled(bool $value)
Enable https for certain scripts.
static getErrorMessage(int $code)
return error message for error code
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getPasswordNumberOfUppercaseChars()
Returns number of uppercase characters required.
isPasswordSpecialCharsEnabled()
get boolean if the passwords have to contain special characters
getPasswordMinLength()
get the minimum length for passwords
setPasswordMaxAge(int $a_password_max_age)
set the maximum password age
setLoginMaxAttempts(int $a_login_max_attempts)
set the maximum count of login attempts
getPasswordMaxAge()
get the maximum password age
$query
setPasswordMinLength(int $a_password_min_length)
set the minimum length for passwords
isPreventionOfSimultaneousLoginsEnabled()
Prevention of simultaneous logins with the same account.
setPasswordMustNotContainLoginnameStatus($status)
Set whether the password must not contain the loginname or not.
const SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN3
static int $SECURITY_SETTINGS_ERR_CODE_HTTPS_NOT_AVAILABLE
setPreventionOfSimultaneousLogins(bool $value)
Enable/Disable prevention of simultaneous logins with the same account.
const SECURITY_SETTINGS_ERR_CODE_INVALID_LOGIN_MAX_ATTEMPTS
const SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN1
const SECURITY_SETTINGS_ERR_CODE_PASSWORD_MAX_LENGTH_LESS_MIN_LENGTH
getLoginMaxAttempts()
get the maximum count of login attempts
setPasswordCharsAndNumbersEnabled(bool $a_chars_and_numbers_enabled)
set if the passwords have to contain characters and numbers
read()
read settings private
static _getInstance()
Get instance of ilSecuritySettings.
getPasswordMustNotContainLoginnameStatus()
Return whether the password must not contain the loginname or not.
const DEFAULT_PASSWORD_CHANGE_ON_FIRST_LOGIN_ENABLED