2019-03-20 12:27:11 +01:00
< ? php
2020-02-22 18:14:36 +01:00
/**
* This file is part of Part - DB ( https :// github . com / Part - DB / Part - DB - symfony ) .
*
2022-11-29 22:28:53 +01:00
* Copyright ( C ) 2019 - 2022 Jan Böhmer ( https :// github . com / jbtronics )
2020-02-22 18:14:36 +01:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
2020-01-05 15:46:58 +01:00
declare ( strict_types = 1 );
2022-08-04 21:49:16 +02:00
namespace App\Command\User ;
2019-03-20 12:27:11 +01:00
2019-08-12 18:04:53 +02:00
use App\Entity\UserSystem\User ;
2020-04-03 18:27:47 +02:00
use App\Events\SecurityEvent ;
use App\Events\SecurityEvents ;
2019-03-20 12:27:11 +01:00
use Doctrine\ORM\EntityManagerInterface ;
use Symfony\Component\Console\Command\Command ;
use Symfony\Component\Console\Input\InputArgument ;
use Symfony\Component\Console\Input\InputInterface ;
use Symfony\Component\Console\Output\OutputInterface ;
use Symfony\Component\Console\Style\SymfonyStyle ;
2020-04-03 18:27:47 +02:00
use Symfony\Component\EventDispatcher\EventDispatcherInterface ;
2021-10-02 20:41:14 +02:00
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface ;
2019-03-20 12:27:11 +01:00
2023-05-28 01:21:05 +02:00
#[\Symfony\Component\Console\Attribute\AsCommand('partdb:users:set-password|app:set-password|users:set-password|partdb:user:set-password', 'Sets the password of a user')]
2019-03-20 12:27:11 +01:00
class SetPasswordCommand extends Command
{
2023-06-11 14:15:46 +02:00
public function __construct ( protected EntityManagerInterface $entityManager , protected UserPasswordHasherInterface $encoder , protected EventDispatcherInterface $eventDispatcher )
2019-03-20 12:27:11 +01:00
{
parent :: __construct ();
}
2020-01-05 15:46:58 +01:00
protected function configure () : void
2019-03-20 12:27:11 +01:00
{
2023-05-28 01:21:05 +02:00
$this -> setHelp ( 'This password allows you to set the password of a user, without knowing the old password.' )
2023-02-23 23:39:29 +01:00
-> addArgument ( 'user' , InputArgument :: REQUIRED , 'The username or email of the user' )
2019-03-20 12:27:11 +01:00
;
}
2020-02-01 17:00:03 +01:00
protected function execute ( InputInterface $input , OutputInterface $output ) : int
2019-03-20 12:27:11 +01:00
{
$io = new SymfonyStyle ( $input , $output );
$user_name = $input -> getArgument ( 'user' );
2023-02-23 23:39:29 +01:00
$user = $this -> entityManager -> getRepository ( User :: class ) -> findByEmailOrName ( $user_name );
2019-03-20 12:27:11 +01:00
2023-06-11 14:15:46 +02:00
if ( ! $user instanceof \App\Entity\UserSystem\User ) {
2019-03-20 12:27:11 +01:00
$io -> error ( sprintf ( 'No user with the given username %s found in the database!' , $user_name ));
2019-03-20 23:16:07 +01:00
2023-05-28 01:21:05 +02:00
return \Symfony\Component\Console\Command\Command :: FAILURE ;
2019-03-20 12:27:11 +01:00
}
$io -> note ( 'User found!' );
2023-02-21 21:58:27 +01:00
if ( $user -> isSamlUser ()) {
$io -> error ( 'This user is a SAML user, so you can not change the password!' );
2023-05-28 01:21:05 +02:00
return \Symfony\Component\Console\Command\Command :: FAILURE ;
2023-02-21 21:58:27 +01:00
}
2019-03-20 12:27:11 +01:00
$proceed = $io -> confirm (
sprintf ( 'You are going to change the password of %s with ID %d. Proceed?' ,
$user -> getFullName ( true ), $user -> getID ()));
2020-08-21 21:36:22 +02:00
if ( ! $proceed ) {
2023-05-28 01:21:05 +02:00
return \Symfony\Component\Console\Command\Command :: FAILURE ;
2019-03-20 12:27:11 +01:00
}
$success = false ;
2019-03-20 23:16:07 +01:00
$new_password = '' ;
2019-03-20 12:27:11 +01:00
2020-08-21 21:36:22 +02:00
while ( ! $success ) {
2019-03-20 23:16:07 +01:00
$pw1 = $io -> askHidden ( 'Please enter new password:' );
2019-03-20 12:27:11 +01:00
$pw2 = $io -> askHidden ( 'Please confirm:' );
2019-03-20 23:16:07 +01:00
if ( $pw1 !== $pw2 ) {
2019-03-20 12:27:11 +01:00
$io -> error ( 'The entered password did not match! Please try again.' );
} else {
//Exit loop
$success = true ;
$new_password = $pw1 ;
}
}
//Encode password
2021-10-02 20:41:14 +02:00
$hash = $this -> encoder -> hashPassword ( $user , $new_password );
2019-03-20 12:27:11 +01:00
$user -> setPassword ( $hash );
//And save it to databae
$this -> entityManager -> persist ( $user );
$this -> entityManager -> flush ();
$io -> success ( 'Password was set successful! You can now log in using the new password.' );
2020-03-15 13:56:31 +01:00
2020-04-03 18:27:47 +02:00
$security_event = new SecurityEvent ( $user );
$this -> eventDispatcher -> dispatch ( $security_event , SecurityEvents :: PASSWORD_CHANGED );
2023-05-28 01:21:05 +02:00
return \Symfony\Component\Console\Command\Command :: SUCCESS ;
2019-03-20 12:27:11 +01:00
}
}