19declare(strict_types=1);
23use ILIAS\User\RedirectOnMissingWrite;
34use Psr\Http\Message\ServerRequestInterface;
38 use RedirectOnMissingWrite;
44 private readonly \
ilCtrl $ctrl,
48 private readonly UIFactory $ui_factory,
49 private readonly UIRenderer $ui_renderer,
51 private readonly ServerRequestInterface $request,
52 private readonly ProfileConfigurationRepository $profile_configuration_repository
59 $this->redirectOnMissingWrite($this->
access, $this->
ctrl, $this->tpl, $this->
lng);
60 $cmd = $this->
ctrl->getCmd() .
'Cmd';
64 private function showCmd(?StandardForm $form =
null): void
67 $this->tpl->setContent(
68 $this->ui_renderer->render($form)
77 if ($this->
modal !==
null) {
81 $this->tpl->setContent(
82 $this->ui_renderer->render($content)
88 $form = $this->
buildForm()->withRequest($this->request);
89 $data = $form->getData();
91 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'form_input_not_valid'));
99 $security->setPasswordCharsAndNumbersEnabled(
100 $data[
'password'][
'password_chars_and_numbers_enabled']
102 $security->setPasswordSpecialCharsEnabled(
103 $data[
'password'][
'password_special_chars_enabled']
105 $security->setPasswordMinLength(
106 $data[
'password'][
'password_min_length']
108 $security->setPasswordMaxLength(
109 $data[
'password'][
'password_max_length']
111 $security->setPasswordNumberOfUppercaseChars(
112 $data[
'password'][
'password_min_uppercase_chars']
114 $security->setPasswordNumberOfLowercaseChars(
115 $data[
'password'][
'password_min_lowercase_chars']
117 $security->setPasswordMaxAge(
118 $data[
'password'][
'password_max_age']
120 $security->setLoginMaxAttempts(
121 $data[
'security'][
'login_max_attempts']
123 $security->setPreventionOfSimultaneousLogins(
124 $data[
'security'][
'prevent_simultaneous_logins']
126 $security->setPasswordChangeOnFirstLoginEnabled(
127 $data[
'password'][
'password_change_on_first_login_enabled']
129 $security->setPasswordMustNotContainLoginnameStatus(
130 $data[
'password'][
'password_must_not_contain_loginame']
136 $data[
'general'][
'local_user_administration']
139 $data[
'general'][
'restrict_search_in_user_accounts']
143 if ($this->profile_configuration_repository->getByClass(Alias::class)->isChangeableByUser()) {
146 'create_history_loginname',
147 $data[
'login_name'][
'create_history_loginname'] ?
'1' :
'0'
150 'reuse_of_loginnames',
151 $data[
'login_name'][
'allow_reuse_of_loginnames'] ?
'1' :
'0'
154 'loginname_change_blocking_time',
155 $this->
refinery->kindlyTo()->string()->transform(
156 $data[
'login_name'][
'loginname_change_blocking_time']
162 'user_reactivate_code',
163 $data[
'general'][
'reactivate_by_code'] ?
'1' :
'0'
167 'user_delete_own_account',
168 $data[
'general'][
'allow_account_deletion'][
'allow_account_deletion'] ?
'1' :
'0'
171 if (
$data[
'general'][
'allow_account_deletion'][
'allow_account_deletion']) {
173 'user_delete_own_account_email',
174 $data[
'general'][
'allow_account_deletion'][
'notification_email']
179 'tos_withdrawal_usr_deletion',
180 $data[
'general'][
'tos_withdrawal_usr_deletion'] ?
'1' :
'0'
184 'dpro_withdrawal_usr_deletion',
185 $data[
'general'][
'dpro_withdrawal_usr_deletion'] ?
'1' :
'0'
189 'session_reminder_lead_time',
190 $data[
'general'][
'session_reminder_lead_time']
194 'password_assistance',
195 $data[
'password'][
'password_assistance'] ?
'1' :
'0'
200 $data[
'login_name'][
'letter_avatars'] ?
'1' :
'0'
208 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'saved_successfully'));
216 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'ps_passwd_policy_change_force_user_reset_succ'),
true);
221 string $password_settings_hash_from_form,
224 if ($password_settings_hash_from_form ===
'') {
233 $this->
modal = $this->ui_factory->modal()->interruptive(
234 $this->
lng->txt(
'ps_password_force_user_reset'),
235 $this->lng->txt(
'ps_passwd_policy_changed_force_user_reset'),
236 $this->ctrl->getFormActionByClass(self::class,
'forcePasswordReset')
237 )->withActionButtonLabel($this->
lng->txt(
'yes'))
238 ->withCancelButtonLabel($this->
lng->txt(
'no'));
240 $this->
modal = $this->
modal->withOnLoad($this->
modal->getShowSignal());
248 return $this->ui_factory->input()->container()->form()->standard(
249 $this->
ctrl->getFormActionByClass(
250 [\ilAdministrationGUI::class, \ilObjUserFolderGUI::class, self::class],
255 'password' => $this->buildPasswordSettings($security_settings),
256 'security' => $this->buildSecuritySettings($security_settings),
257 'login_name' => $this->buildLoginNameSettings()
265 $ff = $this->ui_factory->input()->field();
269 'local_user_administration' => $ff->checkbox(
270 $this->lng->txt(
'enable_local_user_administration'),
271 $this->lng->txt(
'enable_local_user_administration_info')
273 'restrict_search_in_user_accounts' => $ff->checkbox(
274 $this->lng->txt(
'restrict_user_access'),
275 $this->lng->txt(
'restrict_user_access_info')
277 'reactivate_by_code' => $ff->checkbox(
278 $this->lng->txt(
'user_account_code_setting'),
279 $this->lng->txt(
'user_account_code_setting_info')
280 )->withValue($this->settings->get(
'user_reactivate_code') ===
'1'),
281 'allow_account_deletion' => $ff->optionalGroup(
283 'notification_email' => $ff->text(
284 $this->lng->txt(
'user_delete_own_account_notification_email')
285 )->withValue($this->settings->get(
'user_delete_own_account_email',
''))
287 $this->lng->txt(
'user_allow_delete_own_account')
288 )->withAdditionalTransformation(
289 $this->buildAllowAccountDeletionTrafo()
291 $this->settings->get(
'user_delete_own_account') ===
'1'
293 'notification_email' => $this->settings->get(
'user_delete_own_account_email',
'')
296 'tos_withdrawal_usr_deletion' => $ff->checkbox(
297 $this->lng->txt(
'tos_withdrawal_usr_deletion'),
298 $this->lng->txt(
'tos_withdrawal_usr_deletion_desc')
299 )->withValue($this->settings->get(
'tos_withdrawal_usr_deletion') ===
'1'),
300 'dpro_withdrawal_usr_deletion' => $ff->checkbox(
301 $this->lng->txt(
'dpro_withdrawal_usr_deletion'),
302 $this->lng->txt(
'dpro_withdrawal_usr_deletion_desc')
303 )->withValue($this->settings->get(
'dpro_withdrawal_usr_deletion') ===
'1'),
304 'session_reminder_lead_time' => $ff->numeric(
305 $this->lng->txt(
'session_reminder_input'),
307 $this->
lng->txt(
'session_reminder_default_lead_time_info'),
312 )->withRequired(
true)
313 ->withAdditionalTransformation($this->refinery->kindlyTo()->string())
318 $this->lng->txt(
'general_settings')
325 $ff = $this->ui_factory->input()->field();
329 'password_change_on_first_login_enabled' => $ff->checkbox(
330 $this->lng->txt(
'ps_password_change_on_first_login_enabled'),
331 $this->lng->txt(
'ps_password_change_on_first_login_enabled_info')
333 'password_must_not_contain_loginame' => $ff->checkbox(
334 $this->lng->txt(
'ps_password_must_not_contain_loginame'),
335 $this->lng->txt(
'ps_password_must_not_contain_loginame_info')
337 'password_chars_and_numbers_enabled' => $ff->checkbox(
338 $this->lng->txt(
'ps_password_chars_and_numbers_enabled'),
339 $this->lng->txt(
'ps_password_chars_and_numbers_enabled_info')
341 'password_special_chars_enabled' => $ff->checkbox(
342 $this->lng->txt(
'ps_password_special_chars_enabled'),
343 $this->lng->txt(
'ps_password_special_chars_enabled_info')
345 'password_min_length' => $ff->numeric(
346 $this->lng->txt(
'ps_password_min_length'),
347 $this->lng->txt(
'ps_password_min_length_info')
348 )->withRequired(
true)
349 ->withAdditionalTransformation($this->refinery->int()->isGreaterThan(0))
351 'password_max_length' => $ff->numeric(
352 $this->lng->txt(
'ps_password_max_length'),
353 $this->lng->txt(
'ps_password_max_length_info')
354 )->withRequired(
true)
356 'password_min_uppercase_chars' => $ff->numeric(
357 $this->lng->txt(
'ps_password_uppercase_chars_num'),
358 $this->lng->txt(
'ps_password_uppercase_chars_num_info')
359 )->withRequired(
true)
361 'password_min_lowercase_chars' => $ff->numeric(
362 $this->lng->txt(
'ps_password_lowercase_chars_num'),
363 $this->lng->txt(
'ps_password_lowercase_chars_num_info')
364 )->withRequired(
true)
366 'password_max_age' => $ff->numeric(
367 $this->lng->txt(
'ps_password_max_age'),
368 $this->lng->txt(
'ps_password_max_age_info')
369 )->withRequired(
true)
371 'password_assistance' => $ff->checkbox(
372 $this->lng->txt(
'enable_password_assistance'),
373 $this->lng->txt(
'password_assistance_info')
374 )->withValue($this->settings->get(
'password_assistance') ===
'1'),
375 'password_policy_hash' => $ff->hidden()->withValue(
376 $this->getPasswordPolicySettingsHash($security_settings)
379 $this->lng->txt(
'ps_password_settings')
381 ->withAdditionalTransformation($this->buildCheckPasswordMaxLengthConstraint());
387 $ff = $this->ui_factory->input()->field();
391 'login_max_attempts' => $ff->numeric(
392 $this->lng->txt(
'ps_login_max_attempts'),
393 $this->lng->txt(
'ps_login_max_attempts_info')
394 )->withRequired(
true)
395 ->withAdditionalTransformation(
398 'prevent_simultaneous_logins' => $ff->checkbox(
399 $this->lng->txt(
'ps_prevent_simultaneous_logins'),
400 $this->lng->txt(
'ps_prevent_simultaneous_logins_info')
403 $this->lng->txt(
'ps_security_protection')
409 $ff = $this->ui_factory->input()->field();
410 $alias_changeable_by_user = $this->profile_configuration_repository->getByClass(Alias::class)->isChangeableByUser();
413 'create_history_loginname' => $ff->checkbox(
414 $this->lng->txt(
'history_loginname'),
415 $alias_changeable_by_user
416 ? $this->lng->txt(
'loginname_history_info')
417 : $this->lng->txt(
'activate_in_profile_fields')
418 )->withValue($this->settings->get(
'create_history_loginname') ===
'1')
419 ->withDisabled(!$alias_changeable_by_user),
420 'allow_reuse_of_loginnames' => $ff->checkbox(
421 $this->lng->txt(
'reuse_of_loginnames_contained_in_history'),
422 $alias_changeable_by_user
423 ? $this->lng->txt(
'reuse_of_loginnames_contained_in_history_info')
424 : $this->lng->txt(
'activate_in_profile_fields')
425 )->withValue($this->settings->get(
'reuse_of_loginnames') ===
'1')
426 ->withDisabled(!$alias_changeable_by_user),
427 'loginname_change_blocking_time' => $ff->numeric(
428 $this->lng->txt(
'loginname_change_blocking_time'),
429 $alias_changeable_by_user
430 ? $this->lng->txt(
'loginname_change_blocking_time_info')
431 : $this->lng->txt(
'activate_in_profile_fields')
434 )->withAdditionalTransformation(
435 $this->refinery->custom()->transformation(
436 fn(?
float $v): ?
float => $v ===
null ?
null : $v * 86400
439 (
float) $this->
settings->get(
'loginname_change_blocking_time') / 86400
440 )->withDisabled(!$alias_changeable_by_user),
441 'letter_avatars' => $ff->checkbox(
442 $this->lng->txt(
'usr_letter_avatars'),
443 $this->lng->txt(
'usr_letter_avatars_info')
444 )->withValue($this->settings->get(
'letter_avatars') ===
'1'),
446 $this->lng->txt(
'loginname_settings')
452 return $this->
refinery->custom()->transformation(
453 function (?array $vs): array {
456 'allow_account_deletion' => false
460 $vs[
'allow_account_deletion'] =
true;
468 return $this->
refinery->custom()->constraint(
469 static fn(array $vs):
bool => $vs[
'password_min_length'] > 1 + $vs[
'password_min_uppercase_chars']
470 + $vs[
'password_min_lowercase_chars'] + (
int) $vs[
'password_special_chars_enabled']
471 + (
int) $vs[
'password_chars_and_numbers_enabled'],
472 $this->
lng->txt(
'ps_min_value_too_small_for_requirements')
478 return $this->
refinery->custom()->constraint(
479 static fn(array $vs):
bool => $vs[
'password_min_length'] > $vs[
'password_max_length'],
480 $this->
lng->txt(
'ps_error_message_password_max_less_min')
static getInstance()
Singleton method to reduce footprint (included files, created instances)
Builds a Color from either hex- or rgb values.
buildCheckPasswordMaxLengthConstraint()
buildGeneralSettings(\ilUserAccountSettings $account_settings)
buildAllowAccountDeletionTrafo()
buildPasswordSettings(\ilSecuritySettings $security_settings)
getPasswordPolicySettingsHash(\ilSecuritySettings $security)
buildSecuritySettings(\ilSecuritySettings $security_settings)
buildCheckPasswordMinLengthConstraint()
needsPasswortResetPrompt(string $password_settings_hash_from_form, \ilSecuritySettings $security)
__construct(private readonly \ILIAS\Language\Language $lng, private readonly \ilCtrl $ctrl, private readonly \ilAccess $access, private readonly \ilSetting $settings, private readonly \ilGlobalTemplateInterface $tpl, private readonly UIFactory $ui_factory, private readonly UIRenderer $ui_renderer, private readonly Refinery $refinery, private readonly ServerRequestInterface $request, private readonly ProfileConfigurationRepository $profile_configuration_repository)
showCmd(?StandardForm $form=null)
Class ilAccessHandler Checks access for ILIAS objects.
Class ilCtrl provides processing control methods.
static secondsToString(int $seconds, bool $force_with_seconds=false, ?ilLanguage $a_lng=null)
converts seconds to string: Long: 7 days 4 hour(s) ...
Singleton class that stores all security settings.
isPasswordSpecialCharsEnabled()
get boolean if the passwords have to contain special characters
getLoginMaxAttempts()
get the maximum count of login attempts
getPasswordMustNotContainLoginnameStatus()
Return whether the password must not contain the loginname or not.
getPasswordMinLength()
get the minimum length for passwords
getPasswordMaxLength()
get the maximum length for passwords
isPreventionOfSimultaneousLoginsEnabled()
Prevention of simultaneous logins with the same account.
getPasswordNumberOfUppercaseChars()
Returns number of uppercase characters required.
isPasswordCharsAndNumbersEnabled()
get boolean if the passwords have to contain characters and numbers
isPasswordChangeOnFirstLoginEnabled()
get boolean if the passwords have to be changed by users on first login
getPasswordMaxAge()
get the maximum password age
static _getInstance()
Get instance of ilSecuritySettings.
getPasswordNumberOfLowercaseChars()
Returns number of lowercase characters required.
const int LEAD_TIME_DISABLED
const int SUGGESTED_LEAD_TIME
static getSessionExpireValue()
Returns the session expiration value.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
isLocalUserAdministrationEnabled()
Check if local user administration is enabled.
isUserAccessRestricted()
Check if user access is restricted.
An entity that renders components to a string output.
modal(string $title="", string $cancel_label="")
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
if(!file_exists('../ilias.ini.php'))