From 2ff06e988b4eafc9709bfb02fffe0f861f6d7e02 Mon Sep 17 00:00:00 2001 From: Ross Addison Date: Mon, 6 May 2024 16:12:48 +0100 Subject: [PATCH] Pull request #602 (https://github.com/yiisoft/demo/pull/602) If a user (normally an administrator) has the permission 'changePasswordForAnyUser', the login form 'username' text box will be not readonly so that the administrator can change any username's password in the event of a user's personal request to change their password by typing in their username. --- resources/rbac/items.php | 10 ++- resources/views/changepassword/change.php | 10 ++- .../Controller/ChangePasswordController.php | 66 ++++++++++--------- 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/resources/rbac/items.php b/resources/rbac/items.php index 56c29f35..ad395e4a 100644 --- a/resources/rbac/items.php +++ b/resources/rbac/items.php @@ -12,7 +12,8 @@ 'viewPayment', 'editPayment', 'editUser', - 'editClientPeppol' + 'editClientPeppol', + 'canChangePasswordForAnyUser' ], ], @@ -91,4 +92,11 @@ 'updatedAt' => 1599036348, 'createdAt' => 1599036348, ], + + 'changePasswordForAnyUser' => [ + 'name' => 'changePasswordForAnyUser', + 'type' => 'permission', + 'updatedAt' => 1599036348, + 'createdAt' => 1599036348, + ], ]; diff --git a/resources/views/changepassword/change.php b/resources/views/changepassword/change.php index 72881039..9e76088d 100644 --- a/resources/views/changepassword/change.php +++ b/resources/views/changepassword/change.php @@ -34,10 +34,14 @@ ->csrf($csrf) ->id('changePasswordForm') ->open() ?> - addInputAttributes( + addInputAttributes( [ - 'value'=> $login ?? '', - 'readonly'=>'readonly' + 'value' => $login ?? '' + ] + ) : Field::text($formModel, 'login')->addInputAttributes( + [ + 'value' => $login ?? '', + 'readonly' => 'readonly' ] ); ?> diff --git a/src/Auth/Controller/ChangePasswordController.php b/src/Auth/Controller/ChangePasswordController.php index 561bddf5..c61f3b32 100644 --- a/src/Auth/Controller/ChangePasswordController.php +++ b/src/Auth/Controller/ChangePasswordController.php @@ -25,12 +25,12 @@ public function __construct( private Session $session, private Flash $flash, private Translator $translator, - private CurrentUser $current_user, + private CurrentUser $currentUser, private WebControllerService $webService, private ViewRenderer $viewRenderer, ) { - $this->current_user = $current_user; + $this->currentUser = $currentUser; $this->session = $session; $this->flash = new Flash($session); $this->translator = $translator; @@ -47,36 +47,38 @@ public function change( ): ResponseInterface { if ($authService->isGuest()) { return $this->redirectToMain(); - } - // permit an authenticated user, ie. not a guest, only and null!== current user - if (!$authService->isGuest()) { - if ($this->current_user->can('viewInv',[])) { - // readonly the login detail on the change form - $identity_id = $this->current_user->getIdentity()->getId(); - if (null!==$identity_id) { - $identity = $identityRepository->findIdentity($identity_id); - if (null!==$identity) { - // Identity and User are in a HasOne relationship so no null value - $login = $identity->getUser()?->getLogin(); - if ($request->getMethod() === Method::POST - && $formHydrator->populate($changePasswordForm, $request->getParsedBody()) - && $changePasswordForm->change() - ) { - // Identity implements CookieLoginIdentityInterface: ensure the regeneration of the cookie auth key by means of $authService->logout(); - // @see vendor\yiisoft\user\src\Login\Cookie\CookieLoginIdentityInterface - - // Specific note: "Make sure to invalidate earlier issued keys when you implement force user logout, - // PASSWORD CHANGE and other scenarios, that require forceful access revocation for old sessions. - // The authService logout function will regenerate the auth key here => overwriting any auth key - $authService->logout(); - $this->flash_message('success', $this->translator->translate('validator.password.change')); - return $this->redirectToMain(); - } - return $this->viewRenderer->render('change', ['formModel' => $changePasswordForm, 'login' => $login]); - } // identity - } // identity_id - } // current user - } // auth service + } + + $identity_id = $this->currentUser->getIdentity()->getId(); + if (null!==$identity_id) { + $identity = $identityRepository->findIdentity($identity_id); + if (null!==$identity) { + // Identity and User are in a HasOne relationship so no null value + $login = $identity->getUser()?->getLogin(); + if ($request->getMethod() === Method::POST + && $formHydrator->populate($changePasswordForm, $request->getParsedBody()) + && $changePasswordForm->change() + ) { + // Identity implements CookieLoginIdentityInterface: ensure the regeneration of the cookie auth key by means of $authService->logout(); + // @see vendor\yiisoft\user\src\Login\Cookie\CookieLoginIdentityInterface + // Specific note: "Make sure to invalidate earlier issued keys when you implement force user logout, + // PASSWORD CHANGE and other scenarios, that require forceful access revocation for old sessions. + // The authService logout function will regenerate the auth key here => overwriting any auth key + $authService->logout(); + $this->flash_message('success', $this->translator->translate('validator.password.change')); + return $this->redirectToMain(); + } + return $this->viewRenderer->render('change', [ + 'formModel' => $changePasswordForm, + 'login' => $login, + /** + * @see resources\rbac\items.php + * @see https://github.com/yiisoft/demo/pull/602 + */ + 'changePasswordForAnyUser' => $this->currentUser->can('changePasswordForAnyUser') + ]); + } // identity + } // identity_id return $this->redirectToMain(); } // reset