diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php index caab4012..eb78f2c4 100644 --- a/src/Controller/AdminPages/BaseAdminController.php +++ b/src/Controller/AdminPages/BaseAdminController.php @@ -33,6 +33,7 @@ namespace App\Controller\AdminPages; use App\Entity\Base\NamedDBElement; use App\Entity\Base\StructuralDBElement; +use App\Entity\UserSystem\User; use App\Form\AdminPages\ImportType; use App\Form\AdminPages\MassCreationForm; use App\Services\EntityExporter; @@ -42,6 +43,9 @@ use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface; +use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; +use Symfony\Component\Security\Core\Tests\Encoder\PasswordEncoder; use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Contracts\Translation\TranslatorInterface; @@ -53,15 +57,18 @@ abstract class BaseAdminController extends AbstractController protected $twig_template = ''; protected $route_base = ''; + + protected $passwordEncoder; protected $translator; - public function __construct(TranslatorInterface $translator) + public function __construct(TranslatorInterface $translator, UserPasswordEncoderInterface $passwordEncoder) { if ($this->entity_class === '' || $this->form_class === '' || $this->twig_template === '' || $this->route_base === '') { throw new \InvalidArgumentException('You have to override the $entity_class, $form_class, $route_base and $twig_template value in your subclasss!'); } $this->translator = $translator; + $this->passwordEncoder = $passwordEncoder; } protected function _edit(NamedDBElement $entity, Request $request, EntityManagerInterface $em) @@ -73,6 +80,14 @@ abstract class BaseAdminController extends AbstractController $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + //Check if we editing a user and if we need to change the password of it + if ($entity instanceof User && !empty($form['new_password']->getData())) { + $password = $this->passwordEncoder->encodePassword($entity, $form['new_password']->getData()); + $entity->setPassword($password); + //By default the user must change the password afterwards + $entity->setNeedPwChange(true); + } + $em->persist($entity); $em->flush(); $this->addFlash('success', $this->translator->trans('entity.edit_flash')); @@ -103,6 +118,12 @@ abstract class BaseAdminController extends AbstractController $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + if ($new_entity instanceof User && !empty($form['new_password']->getData())) { + $password = $this->passwordEncoder->encodePassword($new_entity, $form['new_password']->getData()); + $new_entity->setPassword($password); + //By default the user must change the password afterwards + $new_entity->setNeedPwChange(true); + } $em->persist($new_entity); $em->flush(); $this->addFlash('success', $this->translator->trans('entity.created_flash')); @@ -172,12 +193,14 @@ abstract class BaseAdminController extends AbstractController if ($entity instanceof StructuralDBElement && $request->get('delete_recursive', false)) { $recursionHelper->delete($entity, false); } else { - $parent = $entity->getParent(); + if ($entity instanceof StructuralDBElement) { + $parent = $entity->getParent(); - //Move all sub entities to the current parent - foreach ($entity->getSubelements() as $subelement) { - $subelement->setParent($parent); - $entityManager->persist($subelement); + //Move all sub entities to the current parent + foreach ($entity->getSubelements() as $subelement) { + $subelement->setParent($parent); + $entityManager->persist($subelement); + } } //Remove current element diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index 1505c0ea..3e8c615a 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -328,10 +328,32 @@ class User extends NamedDBElement implements UserInterface, HasPermissionsInterf return $this->permissions; } + /** + * Check if the user needs a password change + * @return bool + */ + public function isNeedPwChange(): bool + { + return $this->need_pw_change; + } + + /** + * Set the status, if the user needs a password change. + * @param bool $need_pw_change + * @return User + */ + public function setNeedPwChange(bool $need_pw_change): User + { + $this->need_pw_change = $need_pw_change; + return $this; + } + /************************************************ * Getters ************************************************/ + + /** * Returns the full name in the format FIRSTNAME LASTNAME [(USERNAME)]. * Example: Max Muster (m.muster). diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php index a8388db6..341c531c 100644 --- a/src/Form/UserAdminForm.php +++ b/src/Form/UserAdminForm.php @@ -42,14 +42,18 @@ use App\Form\Type\StructuralEntityType; use FOS\CKEditorBundle\Form\Type\CKEditorType; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\LanguageType; +use Symfony\Component\Form\Extension\Core\Type\PasswordType; +use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\ResetType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\Extension\Core\Type\TimezoneType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Validator\Constraints\Length; use Symfony\Contracts\Translation\TranslatorInterface; class UserAdminForm extends AbstractType @@ -146,6 +150,25 @@ class UserAdminForm extends AbstractType 'disabled' => !$this->security->isGranted('change_user_settings', $entity) ]) + ->add('new_password', RepeatedType::class, [ + 'type' => PasswordType::class, + 'first_options' => ['label' => $this->trans->trans('user.settings.pw_new.label')], + 'second_options' => ['label' => $this->trans->trans('user.settings.pw_confirm.label')], + 'invalid_message' => 'password_must_match', + 'required' => false, + 'mapped' => false, + 'constraints' => [new Length([ + 'min' => 6, + 'max' => 128, + ])] + ]) + + ->add('need_pw_change', CheckboxType::class, [ + 'required' => false, + 'label_attr' => ['class' => 'checkbox-custom'], + 'label' => $this->trans->trans('user.edit.needs_pw_change') + ]) + //Permission section ->add('permissions', PermissionsType::class, [ 'mapped' => false, diff --git a/templates/AdminPages/UserAdmin.html.twig b/templates/AdminPages/UserAdmin.html.twig index 748ae5e1..613289ed 100644 --- a/templates/AdminPages/UserAdmin.html.twig +++ b/templates/AdminPages/UserAdmin.html.twig @@ -8,6 +8,7 @@ {% block additional_pills %} + {% endblock %} @@ -28,6 +29,11 @@ {{ form_row(form.currency) }} +
+ {{ form_row(form.new_password) }} + {{ form_row(form.need_pw_change) }} +
+
{{ form_row(form.permissions) }}