ILIAS  trunk Revision v11.0_alpha-1769-g99a433fe2dc
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilSecuritySettings.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
28 {
32 
41 
42  private static ?self $instance = null;
43  private ilDBInterface $db;
46  protected ilHTTPS $https;
47 
48  private bool $https_enable;
49 
52  public const DEFAULT_PASSWORD_MIN_LENGTH = 8;
53  public const DEFAULT_PASSWORD_MAX_LENGTH = 0;
54  public const DEFAULT_PASSWORD_MAX_AGE = 90;
55  public const DEFAULT_LOGIN_MAX_ATTEMPTS = 5;
56  public const MAX_LOGIN_ATTEMPTS = 99;
57 
60 
61  private bool $password_chars_and_numbers_enabled = self::DEFAULT_PASSWORD_CHARS_AND_NUMBERS_ENABLED;
62  private bool $password_special_chars_enabled = self::DEFAULT_PASSWORD_SPECIAL_CHARS_ENABLED;
63  private int $password_min_length = self::DEFAULT_PASSWORD_MIN_LENGTH;
64  private int $password_max_length = self::DEFAULT_PASSWORD_MAX_LENGTH;
65  private int $password_max_age = self::DEFAULT_PASSWORD_MAX_AGE;
66  private int $password_ucase_chars_num = 0;
67  private int $password_lcase_chars_num = 0;
68  private int $login_max_attempts = self::DEFAULT_LOGIN_MAX_ATTEMPTS;
70 
71  private bool $password_change_on_first_login_enabled = self::DEFAULT_PASSWORD_CHANGE_ON_FIRST_LOGIN_ENABLED;
72  private bool $prevent_simultaneous_logins = self::DEFAULT_PREVENT_SIMULTANEOUS_LOGINS;
73 
74  private bool $protect_admin_role = false;
75 
79  private function __construct()
80  {
81  global $DIC;
82 
83  $this->db = $DIC->database();
84  $this->settings = $DIC->settings();
85  $this->review = $DIC->rbac()->review();
86  $this->https = $DIC['https'];
87 
88  $this->read();
89  }
90 
96  public static function _getInstance(): ilSecuritySettings
97  {
98  if (!self::$instance instanceof self) {
99  self::$instance = new self();
100  }
101  return self::$instance;
102  }
103 
108  public function setPasswordCharsAndNumbersEnabled(bool $a_chars_and_numbers_enabled): void
109  {
110  $this->password_chars_and_numbers_enabled = $a_chars_and_numbers_enabled;
111  }
112 
117  public function isPasswordCharsAndNumbersEnabled(): bool
118  {
120  }
121 
126  public function setPasswordSpecialCharsEnabled(bool $a_password_special_chars_enabled): void
127  {
128  $this->password_special_chars_enabled = $a_password_special_chars_enabled;
129  }
130 
135  public function isPasswordSpecialCharsEnabled(): bool
136  {
138  }
139 
143  public function setPasswordMinLength(int $a_password_min_length): void
144  {
145  $this->password_min_length = $a_password_min_length;
146  }
147 
151  public function getPasswordMinLength(): int
152  {
154  }
155 
159  public function setPasswordMaxLength(int $a_password_max_length): void
160  {
161  $this->password_max_length = $a_password_max_length;
162  }
163 
167  public function getPasswordMaxLength(): int
168  {
170  }
171 
175  public function setPasswordMaxAge(int $a_password_max_age): void
176  {
177  $this->password_max_age = $a_password_max_age;
178  }
179 
183  public function getPasswordMaxAge(): int
184  {
186  }
187 
191  public function setLoginMaxAttempts(int $a_login_max_attempts): void
192  {
193  $this->login_max_attempts = $a_login_max_attempts;
194  }
195 
199  public function getLoginMaxAttempts(): int
200  {
202  }
203 
207  public function setHTTPSEnabled(bool $value): void
208  {
209  $this->https_enable = $value;
210  }
211 
215  public function isHTTPSEnabled(): bool
216  {
217  return $this->https_enable;
218  }
219 
224  public function setPasswordChangeOnFirstLoginEnabled(bool $a_password_change_on_first_login_enabled): void
225  {
226  $this->password_change_on_first_login_enabled = $a_password_change_on_first_login_enabled;
227  }
228 
233  public function isPasswordChangeOnFirstLoginEnabled(): bool
234  {
236  }
237 
238  public function isAdminRoleProtected(): bool
239  {
240  return (bool) $this->protect_admin_role;
241  }
242 
243  public function protectedAdminRole(bool $a_stat): void
244  {
245  $this->protect_admin_role = $a_stat;
246  }
247 
251  public function checkAdminRoleAccessible(int $a_usr_id): bool
252  {
253  if (!$this->isAdminRoleProtected()) {
254  return true;
255  }
256  if ($this->review->isAssigned($a_usr_id, SYSTEM_ROLE_ID)) {
257  return true;
258  }
259  return false;
260  }
261 
265  public function save(): void
266  {
267  $this->settings->set('https', (string) $this->isHTTPSEnabled());
268 
269  $this->settings->set('ps_password_chars_and_numbers_enabled', (string) $this->isPasswordCharsAndNumbersEnabled());
270  $this->settings->set('ps_password_special_chars_enabled', (string) $this->isPasswordSpecialCharsEnabled());
271  $this->settings->set('ps_password_min_length', (string) $this->getPasswordMinLength());
272  $this->settings->set('ps_password_max_length', (string) $this->getPasswordMaxLength());
273  $this->settings->set('ps_password_max_age', (string) $this->getPasswordMaxAge());
274  $this->settings->set('ps_login_max_attempts', (string) $this->getLoginMaxAttempts());
275  $this->settings->set('ps_password_uppercase_chars_num', (string) $this->getPasswordNumberOfUppercaseChars());
276  $this->settings->set('ps_password_lowercase_chars_num', (string) $this->getPasswordNumberOfLowercaseChars());
277  $this->settings->set(
278  'ps_password_must_not_contain_loginame',
280  );
281 
282  $this->settings->set(
283  'ps_password_change_on_first_login_enabled',
284  (string) $this->isPasswordChangeOnFirstLoginEnabled()
285  );
286  $this->settings->set('ps_prevent_simultaneous_logins', (string) $this->isPreventionOfSimultaneousLoginsEnabled());
287  $this->settings->set('ps_protect_admin', (string) $this->isAdminRoleProtected());
288  }
289 
295  private function read(): void
296  {
297  $query = "SELECT object_reference.ref_id FROM object_reference,tree,object_data " .
298  "WHERE tree.parent = " . $this->db->quote(SYSTEM_FOLDER_ID, 'integer') . " " .
299  "AND object_data.type = 'ps' " .
300  "AND object_reference.ref_id = tree.child " .
301  "AND object_reference.obj_id = object_data.obj_id";
302  $res = $this->db->query($query);
303  $row = $res->fetchRow(ilDBConstants::FETCHMODE_ASSOC);
304 
305  $this->https_enable = (bool) $this->settings->get('https', null);
306 
307  $this->password_chars_and_numbers_enabled = (bool) $this->settings->get(
308  'ps_password_chars_and_numbers_enabled',
309  (string) self::DEFAULT_PASSWORD_CHARS_AND_NUMBERS_ENABLED
310  );
311  $this->password_special_chars_enabled = (bool) $this->settings->get(
312  'ps_password_special_chars_enabled',
313  (string) self::DEFAULT_PASSWORD_SPECIAL_CHARS_ENABLED
314  );
315  $this->password_min_length = (int) $this->settings->get(
316  'ps_password_min_length',
317  (string) self::DEFAULT_PASSWORD_MIN_LENGTH
318  );
319  $this->password_max_length = (int) $this->settings->get(
320  'ps_password_max_length',
321  (string) self::DEFAULT_PASSWORD_MAX_LENGTH
322  );
323  $this->password_max_age = (int) $this->settings->get('ps_password_max_age', (string) self::DEFAULT_PASSWORD_MAX_AGE);
324  $this->login_max_attempts = (int) $this->settings->get(
325  'ps_login_max_attempts',
326  (string) self::DEFAULT_LOGIN_MAX_ATTEMPTS
327  );
328  $this->password_ucase_chars_num = (int) $this->settings->get('ps_password_uppercase_chars_num', "0");
329  $this->password_lcase_chars_num = (int) $this->settings->get('ps_password_lowercase_chars_num', "0");
330  $this->password_must_not_contain_loginname = (bool) $this->settings->get(
331  'ps_password_must_not_contain_loginame',
332  null
333  );
334  $this->password_change_on_first_login_enabled = (bool) $this->settings->get(
335  'ps_password_change_on_first_login_enabled',
336  (string) self::DEFAULT_PASSWORD_CHANGE_ON_FIRST_LOGIN_ENABLED
337  );
338  $this->prevent_simultaneous_logins = (bool) $this->settings->get(
339  'ps_prevent_simultaneous_logins',
340  (string) self::DEFAULT_PREVENT_SIMULTANEOUS_LOGINS
341  );
342  $this->protect_admin_role = (bool) $this->settings->get('ps_protect_admin', (string) $this->protect_admin_role);
343  }
344 
350  public function validate(?ilPropertyFormGUI $a_form = null): ?int
351  {
352  $code = null;
353 
354  if ($this->isHTTPSEnabled()) {
355  if (!$this->https->checkHTTPS()) {
357  if (!$a_form) {
358  return $code;
359  } else {
360  $a_form->getItemByPostVar('https_enabled')
361  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
362  }
363  }
364  }
365 
366  if ($this->getPasswordMinLength() < 0) {
367  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MIN_LENGTH;
368  if (!$a_form) {
369  return $code;
370  } else {
371  $a_form->getItemByPostVar('password_min_length')
372  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
373  }
374  }
375 
376  if ($this->getPasswordMaxLength() < 0) {
377  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MAX_LENGTH;
378  if (!$a_form) {
379  return $code;
380  } else {
381  $a_form->getItemByPostVar('password_max_length')
382  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
383  }
384  }
385 
386  $password_min_length = 1;
387  $password_min_length_error_code = null;
388 
389  if ($this->getPasswordNumberOfUppercaseChars() > 0 || $this->getPasswordNumberOfLowercaseChars() > 0) {
390  $password_min_length = 0;
391  if ($this->getPasswordNumberOfUppercaseChars() > 0) {
392  $password_min_length += $this->getPasswordNumberOfUppercaseChars();
393  }
394  if ($this->getPasswordNumberOfLowercaseChars() > 0) {
395  $password_min_length += $this->getPasswordNumberOfLowercaseChars();
396  }
397  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN1;
398  }
399 
400  if ($this->isPasswordCharsAndNumbersEnabled()) {
401  $password_min_length++;
402  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN2;
403 
404  if ($this->isPasswordSpecialCharsEnabled()) {
405  $password_min_length++;
406  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN3;
407  }
408  } elseif ($password_min_length > 1 && $this->isPasswordSpecialCharsEnabled()) {
409  $password_min_length++;
410  $password_min_length_error_code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MIN_LENGTH_MIN3;
411  }
412 
413  if ($this->getPasswordMinLength() > 0 && $this->getPasswordMinLength() < $password_min_length) {
414  $code = $password_min_length_error_code;
415  if (!$a_form) {
416  return $code;
417  } else {
418  $a_form->getItemByPostVar('password_min_length')
419  ->setAlert(sprintf(ilObjPrivacySecurityGUI::getErrorMessage($code), $password_min_length));
420  }
421  }
422  if ($this->getPasswordMaxLength() > 0 && $this->getPasswordMaxLength() < $this->getPasswordMinLength()) {
423  $code = self::SECURITY_SETTINGS_ERR_CODE_PASSWORD_MAX_LENGTH_LESS_MIN_LENGTH;
424  if (!$a_form) {
425  return $code;
426  } else {
427  $a_form->getItemByPostVar('password_max_length')
428  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
429  }
430  }
431  if ($this->getPasswordMaxAge() < 0) {
432  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_PASSWORD_MAX_AGE;
433  if (!$a_form) {
434  return $code;
435  } else {
436  $a_form->getItemByPostVar('password_max_age')
437  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
438  }
439  }
440 
441  if ($this->getLoginMaxAttempts() < 0) {
442  $code = self::SECURITY_SETTINGS_ERR_CODE_INVALID_LOGIN_MAX_ATTEMPTS;
443  if (!$a_form) {
444  return $code;
445  } else {
446  $a_form->getItemByPostVar('login_max_attempts')
447  ->setAlert(ilObjPrivacySecurityGUI::getErrorMessage($code));
448  }
449  }
450 
451  /*
452  * todo: have to check for local auth if first login password change is enabled??
453  * than: add errorcode
454  */
455 
456  if (!$a_form) {
457  return 0;
458  } else {
459  return $code;
460  }
461  }
462 
468  {
470  }
471 
475  public function setPreventionOfSimultaneousLogins(bool $value): void
476  {
477  $this->prevent_simultaneous_logins = $value;
478  }
479 
483  public function setPasswordNumberOfUppercaseChars(int $password_ucase_chars_num): void
484  {
485  $this->password_ucase_chars_num = $password_ucase_chars_num;
486  }
487 
492  {
494  }
495 
499  public function setPasswordNumberOfLowercaseChars(int $password_lcase_chars_num): void
500  {
501  $this->password_lcase_chars_num = $password_lcase_chars_num;
502  }
503 
508  {
510  }
511 
515  public function setPasswordMustNotContainLoginnameStatus($status): void
516  {
517  $this->password_must_not_contain_loginname = (bool) $status;
518  }
519 
524  {
526  }
527 }
$res
Definition: ltiservices.php:66
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.
Singleton class that stores all security settings.
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
validate(?ilPropertyFormGUI $a_form=null)
validate settings
setPasswordNumberOfLowercaseChars(int $password_lcase_chars_num)
Set number of lowercase characters required.
__construct()
Private constructor: use _getInstance()
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.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
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
global $DIC
Definition: shib_login.php:22
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
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