-
-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change Password #602
base: master
Are you sure you want to change the base?
Change Password #602
Conversation
rossaddison
commented
Oct 28, 2023
Q | A |
---|---|
Is bugfix? | ❌ |
New feature? | ✔️ |
Breaks BC? | ❌ |
Fixed issues | None |
Include a change password function in the demo.
PR Summary
|
blog/README.md
Outdated
@@ -67,6 +67,11 @@ The code is statically analyzed with [Psalm](https://psalm.dev/). To run static | |||
./vendor/bin/psalm | |||
``` | |||
|
|||
### Installing Bootstrap Node Modules with WAMP | |||
|
|||
1. Make a directory node_modules in the blog directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't npm
creating node_modules
automatically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
Functionally a change password and not a reset password form that is included in the main layout and not on the login form. (Change Password)[yiisoft#602]
Adopt suggestions in (#602)[yiisoft/demo#602]
Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
Please review these changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added several comments, fix several errors and adapt PR to last changes in Yii Form.
{ | ||
private string $login = ''; | ||
private string $password = ''; | ||
private string $passwordVerify = ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private string $passwordVerify = ''; | |
private string $passwordVerify = ''; |
Not need field for duplicate old password.
Removved passwordVerify field in the form
@rossaddison would you please resolve conflicts? Thanks. |
return $this->redirectToMain(); | ||
} | ||
// permit an authenticated user, ie. not a guest, only and null!== current user | ||
if (!$authService->isGuest()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!$authService->isGuest()) {
already not need, we have this check above.
In the same way, you can remove "if" nesting in further code.
->id('changeForm') | ||
->open() ?> | ||
|
||
<?= Field::text($formModel, 'login')->addInputAttributes(['value'=> $login ?? '', 'readonly'=>'readonly']) ?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want add ability to change password for any user? Not only current?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I will need to add a permission to the readonly => readonly e.g.
!$this->currentUser->can('changePasswordForAnyUser',[]) ? 'readonly'=>'readonly' : '';
This will make sure that only administrators with the canChangePasswordForAnyUser permission can insert a username in the login textbox in place of the {login} in order to change the password.
...And remove the
if ($this->currentUser->can('viewInv',[])) {
since all authenticated users with a lesser permission (of viewInv) should be able to change their password.
changepassword.php
<?= $canChangePasswordForAnyUser ? Field::text($formModel, 'login')->addInputAttributes(['value'=> $login ?? ''])
: Field::text($formModel, 'login')->addInputAttributes(['value'=> $login ?? '', 'readonly'=>'readonly']); ?>
Controller.php
public function change(
AuthService $authService,
Identity $identity,
IdentityRepository $identityRepository,
ServerRequestInterface $request,
FormHydrator $formHydrator,
ChangePasswordForm $changePasswordForm
): ResponseInterface {
if ($authService->isGuest()) {
return $this->redirectToMain();
}
// readonly the login detail on the change form
$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,
'canChangePasswordForAnyUser' => $this->currentUser->can('changePasswordForAnyUser')
]);
} // identity
} // identity_id
} // r
} | ||
// permit an authenticated user, ie. not a guest, only and null!== current user | ||
if (!$authService->isGuest()) { | ||
if ($this->current_user->can('viewInv',[])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
viewInv
isn't a good name for permission. Let's not shorten names.
Co-authored-by: Sergei Predvoditelev <sergey.predvoditelev@gmail.com>
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.
…ysis I am currently introducing Psalm Level 1 testing to other directories on an individual basis.
"rossaddison/mailer": "dev-master", | ||
"rossaddison/mailer-symfony": "*", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rossaddison you can link your packages locally with yiisoft/yii-dev-tool
Take a look at it
"rossaddison/yii-swagger": "dev-master", | ||
"rossaddison/yii-view": "*" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
* @var array $params['yiisoft/aliases'] | ||
* @var array $params['yiisoft/aliases']['aliases'] | ||
* @var string $params['yiisoft/aliases']['aliases']['@root'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that work in PhpStorm? Elsewhere?
'reset' => function (array $defaultArguments = []) { | ||
$defaultArguments = ['_language', 'en']; | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks suspicious. What does it reset?
->addGroup( | ||
Group::create('/{_language}')->routes(...$config->get('app-routes')), | ||
) | ||
->addGroup( | ||
Group::create()->routes(...$config->get('routes')), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was that created to exclude debug routes from language routing?
$this->currentUser = $currentUser; | ||
$this->session = $session; | ||
$this->flash = new Flash($session); | ||
$this->translator = $translator; | ||
$this->viewRenderer = $viewRenderer->withControllerName('changepassword'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->currentUser = $currentUser; | |
$this->session = $session; | |
$this->flash = new Flash($session); | |
$this->translator = $translator; | |
$this->viewRenderer = $viewRenderer->withControllerName('changepassword'); | |
$this->flash = new Flash($session); | |
$this->viewRenderer = $viewRenderer->withControllerName('changepassword'); |
return $this->redirectToMain(); | ||
} | ||
|
||
$identity_id = $this->currentUser->getIdentity()->getId(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$identity_id = $this->currentUser->getIdentity()->getId(); | |
$identityId = $this->currentUser->getIdentity()->getId(); |
// 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')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->flash_message('success', $this->translator->translate('validator.password.change')); | |
$this->flashMessage('success', $this->translator->translate('validator.password.change')); |
function (mixed $value): Result { | ||
$result = new Result(); | ||
if ($this->userRepository->findByLogin((string)$value) == null) { | ||
$result->addError($this->translator->translate('validator.user.exist.not')); | ||
} | ||
return $result; | ||
}, | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, that should be implemented by catching a database exception on inserting a record because SELECT
and then INSERT
aren't atomic and, thus, can cause an exception anyway if a value is inserted by another user in between.
'password' => $this->PasswordRules(), | ||
'newPassword' => [ | ||
new Required(), | ||
new Length(min: 8), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd not limit password length because it weakens security overall.