Symfony2: edit user without password

In my application, only the admin user can create and, theoretically, edit users. Until now, using only the Symfony security system (without FOSUserBundle management - its complexity is not required), creating users with different roles is normal. The problem that completely eludes me is how to edit the user without knowing the user password. I continue to work with the expected validation error

Password cannot be empty

. How can I edit? Of course, I missed something very important here.

Change action:

public function editAction($id) { $em = $this->getDoctrine()->getManager(); $user = $em->getRepository('ManaClientBundle:User')->find($id); $form = $this->createForm(new UserType(), $user); return array( 'form' => $form->createView(), 'user' => $user, 'title' => 'Edit user', ); } 

Update action:

  public function updateAction(Request $request, $id) { $em = $this->getDoctrine()->getManager(); $user = $em->getRepository('ManaClientBundle:User')->find($id); $originalPassword = $user->getPassword(); $form = $this->createForm(new UserType(), $user); $form->bind($request); if ($form->isValid()) { $plainPassword = $form->get('password')->getData(); if (!empty($plainPassword)) { //encode the password $encoder = $this->container->get('security.encoder_factory')->getEncoder($entity); //get encoder for hashing pwd later $tempPassword = $encoder->encodePassword($entity->getPassword(), $entity->getSalt()); $user->setPassword($tempPassword); } else { $user->setPassword($originalPassword); } $em->persist($user); $em->flush(); return $this->redirect($this->generateUrl('user_main', array())); } 

User Form:

 public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('enabled', 'choice', array( 'choices' => array('Yes' => 'Yes', 'No' => 'No'), 'expanded' => true, 'multiple' => false, 'label' => 'Enabled: ', )) ->add('fname') ->add('sname') ->add('email') ->add('username') ->add('password', 'repeated', array( 'type' => 'password', 'invalid_message' => 'Password fields do not match', 'first_options' => array('label' => 'Password'), 'second_options' => array('label' => 'Repeat Password'), )) ->add('role', 'choice', array( 'choices' => array('ROLE_USER' => 'User', 'ROLE_ADMIN' => 'Admin'), 'expanded' => true, 'multiple' => false, 'label' => 'Group: ', )) ; } 
+6
source share
4 answers

Until I see a more elegant solution, here's what I came up with:

  • Create a UserEditType form class with all fields except password fields (s)
  • Assign UserEditType to a validation group other than Default
  • Set the password length restriction on the verification group to 2.
  • Modify edit and update actions to use UserEditType

And now users can edit without a password!

UserEditType:

 class UserEditType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('enabled', 'choice', array( 'choices' => array('Yes' => 'Yes', 'No' => 'No'), 'expanded' => true, 'multiple' => false, 'label' => 'Enabled: ', )) ->add('fname') ->add('sname') ->add('email') ->add('username') ->add('role', 'choice', array( 'choices' => array('ROLE_USER' => 'User', 'ROLE_ADMIN' => 'Admin'), 'expanded' => true, 'multiple' => false, 'label' => 'Group: ', )) ; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Mana\ClientBundle\Entity\User', 'validation_groups' => array('edit'), )); } 

Password in user object:

  * @ORM\Column(name="userpass", type="string", length=100, nullable=false) * @Assert\NotBlank(message="Password may not be empty") * @Assert\Length( * min = "5", * max = "12", * minMessage = "Password must be at least 5 characters long", * maxMessage = "Password cannot be longer than than 12 characters", * groups = {"Default"} * ) 

Update action:

 public function updateAction(Request $request, $id) { $em = $this->getDoctrine()->getManager(); $user = $em->getRepository('ManaClientBundle:User')->find($id); $form = $this->createForm(new UserEditType(), $user); $form->bind($request); if ($form->isValid()) { $em->persist($user); $em->flush(); return $this->redirect($this->generateUrl('user_main', array())); } return array( 'form' => $form->createView(), 'user' => $user, 'title' => 'Edit user', ); } 
+7
source

I had the same problem in my project.

I solved this by removing the password field from the form for my edit action only.

So, in my UserController I changed editAction :

 //find the line where the form is created $editForm = $this->createForm(new UserType($this->container), $entity) ->remove('password'); //add this to remove the password field 
+6
source

If you want to use the remove() function, apply it also when setting up the form. At least in Symfony 3.3. This way you will avoid confirming the password specified by @pusle above:

  $form = $this->formFactory->createForm()->remove("current_password"); $form->setData($user)->remove("current_password"); 

Here is the whole method in ProfileController from FOSUserBundle. It works for me:

 public function editDiffAction($id, Request $request) { $userManager = $this->get('fos_user.user_manager'); $user = $userManager->findUserBy(['id' => $id]); $event = new GetResponseUserEvent($user, $request); if (null !== $event->getResponse()) { return $event->getResponse(); } $form = $this->formFactory->createForm()->remove("current_password"); $form->setData($user)->remove("current_password"); $form->handleRequest($request); if ($form->isValid()) { $event = new FormEvent($form, $request); $userManager = $this->get('fos_user.user_manager'); $userManager->updateUser($user); $url = $this->generateUrl('fos_user_profile_show_diff', array('id' => $user->getId() )); $response = new RedirectResponse($url); return $response; } return $this->render('@FOSUser/Profile/edit_diff.html.twig', array( 'form' => $form->createView(), 'user_id' => $user->getId(), )); } 
0
source

Just add 'disabled' => 'disabled' and this field will not be taken into account.

-1
source

All Articles