ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilLocalUserPasswordSettingsGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22use ILIAS\UI\Factory as UIFactory;
23use ILIAS\UI\Renderer as UIRenderer;
24use ILIAS\Refinery\Factory as Refinery;
25use Psr\Http\Message\ServerRequestInterface;
30
32{
33 private const string NEW_PASSWORD = 'new_password';
34 private const string CURRENT_PASSWORD = 'current_password';
35 public const string CMD_SHOW_PASSWORD = 'showPassword';
36 public const string CMD_SAVE_PASSWORD = 'savePassword';
37 private readonly ServerRequestInterface $request;
38 private readonly ilErrorHandling $error;
39 private readonly Refinery $refinery;
40 private readonly UIFactory $ui_factory;
41 private readonly UIRenderer $ui_renderer;
43 private readonly ilLanguage $lng;
44 private readonly ilObjUser $user;
45 private readonly ilCtrlInterface $ctrl;
47
48 public function __construct()
49 {
50 global $DIC;
51 $this->user = $DIC->user();
52 $this->ctrl = $DIC->ctrl();
53 $this->error = $DIC['ilErr'];
54 $this->lng = $DIC->language();
55 $this->refinery = $DIC->refinery();
56 $this->tpl = $DIC->ui()->mainTemplate();
57 $this->request = $DIC->http()->request();
58 $this->ui_factory = $DIC->ui()->factory();
59 $this->ui_renderer = $DIC->ui()->renderer();
60 $this->password_manager = LocalUserPasswordManager::getInstance();
61 $this->lng->loadLanguageModule('user');
62 }
63
64 public function executeCommand(): void
65 {
66 $this->tpl->setTitle($this->lng->txt('chg_password'));
67 $cmd = $this->ctrl->getCmd();
68 switch ($cmd) {
69 default:
70 if (method_exists($this, $cmd)) {
71 $this->$cmd();
72 } else {
73 $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->MESSAGE);
74 }
75
76 break;
77 }
78 }
79
80 public function showPassword(
81 ?Form $form = null,
82 bool $hide_form = false,
83 ?MessageBox $message_box = null
84 ): void {
85 // check whether password of user have to be changed
86 // due to first login or password of user is expired
87 if ($this->user->isPasswordChangeDemanded()) {
88 $this->tpl->setOnScreenMessage(
89 $this->tpl::MESSAGE_TYPE_INFO,
90 $this->lng->txt('password_change_on_first_login_demand')
91 );
92 } elseif ($this->user->isPasswordExpired()) {
93 $msg = $this->lng->txt('password_expired');
94 $password_age = $this->user->getPasswordAge();
95 $this->tpl->setOnScreenMessage($this->tpl::MESSAGE_TYPE_INFO, sprintf($msg, $password_age));
96 }
97
98 if (!$form && !$hide_form) {
99 $form = $this->getPasswordForm();
100 }
101 $this->tpl->setContent(
102 !$hide_form ? $this->ui_renderer->render($form) : $this->ui_renderer->render($message_box)
103 );
104 $this->tpl->printToStdout();
105 }
106
107 public function getPasswordForm(
108 ?ServerRequestInterface $request = null,
109 array $errors = []
110 ): Form {
111 $items = [];
112 if ($this->password_manager->allowPasswordChange($this->user)) {
113 $pw_info_set = false;
114 if ((int) $this->user->getAuthMode(true) === ilAuthUtils::AUTH_LOCAL) {
115 $cpass = $this->ui_factory->input()->field()->password(
116 $this->lng->txt(self::CURRENT_PASSWORD),
118 );
119
120 $pw_info_set = true;
121 if ($this->user->getPasswd()) {
122 $cpass = $cpass->withRequired(true);
123 }
124 $cpass = $cpass->withRevelation(true);
125 $cpass_error = $errors[self::CURRENT_PASSWORD] ?? [];
126 if ($cpass_error !== []) {
127 $cpass = $cpass->withError(implode('<br>', $cpass_error));
128 }
129 $cpass = $cpass->withAdditionalTransformation(
130 $this->refinery->custom()->constraint(function (Password $value): bool {
131 return
132 ((int) $this->user->getAuthMode(true) !== ilAuthUtils::AUTH_LOCAL) ||
133 LocalUserPasswordManager::getInstance()->verifyPassword(
134 $this->user,
135 $value->toString()
136 );
137 }, $this->lng->txt('passwd_wrong'))
138 );
139
140 $items[self::CURRENT_PASSWORD] = $cpass;
141 }
142
143 // new password
144 $ipass = $this->ui_factory->input()->field()->password(
145 $this->lng->txt('desired_password'),
146 );
147 if ($pw_info_set === false) {
148 $ipass = $ipass->withByline(ilSecuritySettingsChecker::getPasswordRequirementsInfo());
149 }
150 $ipass = $ipass->withRequired(true);
151 $ipass = $ipass->withRevelation(true);
152 $ipass_error = $errors[self::NEW_PASSWORD] ?? [];
153 if ($ipass_error !== []) {
154 $ipass = $ipass->withError(implode('<br>', $ipass_error));
155 }
156 $ipass = $ipass->withAdditionalTransformation(
157 $this->refinery->custom()->constraint(function (Password $value): bool {
158 return ilSecuritySettingsChecker::isPassword($value->toString(), $custom_error);
159 }, function (Closure $txt, Password $value): string {
160 $custom_error = '';
161 !ilSecuritySettingsChecker::isPassword($value->toString(), $custom_error);
162 if ($custom_error !== '' && $custom_error !== null) {
163 return $custom_error;
164 }
165
166 return $this->lng->txt('passwd_invalid');
167 })
168 );
169 $ipass = $ipass->withAdditionalTransformation(
170 $this->refinery->custom()->constraint(
171 function (Password $value): bool {
173 $value->toString(),
174 $this->user,
175 $error_lng_var
176 );
177 },
178 function (Closure $cls, Password $value): string {
180 $value->toString(),
181 $this->user,
182 $error_lng_var
183 );
184
185 return $this->lng->txt($error_lng_var ?? '');
186 }
187 )
188 );
189 $items[self::NEW_PASSWORD] = $ipass;
190
191 switch ($this->user->getAuthMode(true)) {
193 $title = $this->lng->txt('chg_password');
194
195 break;
197 default:
198 $title = $this->lng->txt('chg_ilias_password');
199
200 break;
201 }
202 $section = $this->ui_factory->input()->field()->section($items, $title);
203 $items = ['password' => $section];
204 }
205
206 return $this->ui_factory->input()->container()->form()->standard(
207 $this->ctrl->getLinkTarget($this, 'savePassword'),
208 $items
209 )->withSubmitLabel($this->lng->txt('save'));
210 }
211
212 public function savePassword(): void
213 {
214 if (!$this->password_manager->allowPasswordChange($this->user)) {
215 $this->ctrl->redirect($this, 'showPersonalData');
216
217 return;
218 }
219
220 $form = $this->getPasswordForm()->withRequest($this->request);
221 $section = $form->getInputs()['password'];
226 $cp = $section->getInputs()[self::CURRENT_PASSWORD] ?? null;
227 $np = $section->getInputs()[self::NEW_PASSWORD];
228 $errors = [self::CURRENT_PASSWORD => [], self::NEW_PASSWORD => []];
229
230 if (!$form->getError()) {
231 $error = false;
232 if ($cp && $cp->getError()) {
233 $error = true;
234 $errors[self::CURRENT_PASSWORD][] = $cp->getError();
235 }
236 if ($np->getError()) {
237 $error = true;
238 $errors[self::NEW_PASSWORD][] = $np->getError();
239 }
240
241 $entered_current_password = $cp ? $cp->getValue() : '';
242 $entered_new_password = $np->getValue();
243
244 if (
245 $entered_current_password === $entered_new_password &&
246 ($this->user->isPasswordExpired() || $this->user->isPasswordChangeDemanded())
247 ) {
248 $error = true;
249 $errors[self::NEW_PASSWORD][] = $this->lng->txt('new_pass_equals_old_pass');
250 }
251
252 if (!$error) {
253 $this->user->resetPassword($entered_new_password);
254 if ($entered_current_password !== $entered_new_password) {
255 $this->user->setLastPasswordChangeToNow();
256 $this->user->setPasswordPolicyResetStatus(false);
257 $this->user->update();
258 }
259
260 if (ilSession::get('orig_request_target')) {
261 $this->tpl->setOnScreenMessage(
262 $this->tpl::MESSAGE_TYPE_SUCCESS,
263 $this->lng->txt('saved_successfully'),
264 true
265 );
266 $target = ilSession::get('orig_request_target');
267 ilSession::set('orig_request_target', '');
268 $this->ctrl->redirectToURL($target);
269 } else {
270 $this->showPassword(
271 null,
272 true,
273 $this->ui_factory->messageBox()->success($this->lng->txt('saved_successfully'))
274 );
275
276 return;
277 }
278 }
279 }
280
281 $this->showPassword($this->getPasswordForm($this->request, $errors));
282 }
283}
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Builds data types.
Definition: Factory.php:36
A password is used as part of credentials for authentication.
Definition: Password.php:31
error(string $a_errmsg)
const int AUTH_SHIBBOLETH
const int AUTH_LOCAL
Error Handling & global info handling.
language handling
readonly LocalUserPasswordManager $password_manager
showPassword(?Form $form=null, bool $hide_form=false, ?MessageBox $message_box=null)
getPasswordForm(?ServerRequestInterface $request=null, array $errors=[])
User class.
static isPassword(string $a_passwd, ?string &$customError=null)
static isPasswordValidForUserContext(string $clear_text_password, $user, ?string &$error_language_variable=null)
static getPasswordRequirementsInfo()
infotext for ilPasswordInputGUI setInfo()
static get(string $a_var)
static set(string $a_var, $a_val)
Set a value.
$txt
Definition: error.php:31
This describes a standard form.
Definition: Standard.php:29
This describes password inputs.
Definition: Password.php:29
An entity that renders components to a string output.
Definition: Renderer.php:31
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26