Преглед на файлове

Remove password fields when logged in with Github

If a user has used Github authentication to create their account,
they are not able to update their password as one does not exist.
This resolves the issue by removing the Change Password form, and
also the Password input on the Edit Profile page.

One possible improvement that could be made in future would be
additional checks to ensure the user is still authenticated with
Github, though I've spent all day on this already so I'll leave
that to somebody else to add in ;)
Dave Shoreman преди 11 години
родител
ревизия
1c142b9b86

+ 2 - 0
app/Resources/FOSUserBundle/views/Profile/edit_content.html.twig

@@ -19,6 +19,7 @@
         </div>
     </div>
 
+    {% if not user.githubId %}
     <div class="form-group clearfix">
         {{ form_label(form.current_password) }}
         <div class="input-group">
@@ -27,6 +28,7 @@
             <span class="input-group-addon"><span class="icon-lock"></span></span>
         </div>
     </div>
+    {% endif %}
 
     <div class="notifications form-group">
         {{ form_errors(form.failureNotifications) }}

+ 4 - 0
app/config/routing.yml

@@ -11,6 +11,10 @@ fos_user_profile_show:
     defaults: { _controller: PackagistWebBundle:User:myProfile }
     methods: [GET]
 
+fos_user_profile_edit:
+    pattern: /profile/edit/
+    defaults: { _controller: PackagistWebBundle:Profile:edit }
+
 fos_user_register:
     resource: '@FOSUserBundle/Resources/config/routing/registration.xml'
     prefix: /register

+ 34 - 0
src/Packagist/WebBundle/Controller/ProfileController.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace Packagist\WebBundle\Controller;
+
+use FOS\UserBundle\Controller\ProfileController as BaseController;
+use FOS\UserBundle\Model\UserInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\Security\Core\Exception\AccessDeniedException;
+
+class ProfileController extends BaseController
+{
+    public function editAction()
+    {
+        $user = $this->container->get('security.context')->getToken()->getUser();
+        if (!is_object($user) || !$user instanceof UserInterface) {
+            throw new AccessDeniedException('This user does not have access to this section.');
+        }
+
+        $form = $this->container->get('fos_user.profile.form');
+        $formHandler = $this->container->get('fos_user.profile.form.handler');
+
+        $process = $formHandler->process($user);
+        if ($process) {
+            $this->setFlash('fos_user_success', 'profile.flash.updated');
+
+            return new RedirectResponse($this->getRedirectionUrl($user));
+        }
+
+        return $this->container->get('templating')->renderResponse(
+            'FOSUserBundle:Profile:edit.html.'.$this->container->getParameter('fos_user.template.engine'),
+            array('form' => $form->createView(), 'user' => $user)
+        );
+    }
+}

+ 43 - 1
src/Packagist/WebBundle/Form/Type/ProfileFormType.php

@@ -14,21 +14,63 @@ namespace Packagist\WebBundle\Form\Type;
 
 use FOS\UserBundle\Form\Type\ProfileFormType as BaseType;
 use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Form\FormEvents;
+use Symfony\Component\Form\FormEvent;
+use Symfony\Component\Security\Core\SecurityContext;
+use Symfony\Component\Security\Core\Validator\Constraint\UserPassword as OldUserPassword;
+use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
 
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
  */
 class ProfileFormType extends BaseType
 {
+    private $securityContext;
+
+    public function __construct($class, SecurityContext $securityContext)
+    {
+        parent::__construct($class);
+
+        $this->securityContext = $securityContext;
+    }
+
     public function buildForm(FormBuilderInterface $builder, array $options)
     {
-        parent::buildForm($builder, $options);
+        $builder->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle'))
+                ->add('email', 'email', array('label' => 'form.email', 'translation_domain' => 'FOSUserBundle'));
+
+        $user = $this->securityContext->getToken()->getUser();
+
+        $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) use ($user)
+        {
+            if ( ! $user->getGithubId())
+            {
+                $this->addPasswordField($event);
+            }
+        });
 
         $builder->add('failureNotifications', null, array(
             'required' => false,
         ));
     }
 
+    private function addPasswordField(&$event)
+    {
+        if (class_exists('Symfony\Component\Security\Core\Validator\Constraints\UserPassword')) {
+            $constraint = new UserPassword();
+        } else {
+            // Symfony 2.1 support with the old constraint class
+            $constraint = new OldUserPassword();
+        }
+
+        $event->getForm()->add('current_password', 'password', array(
+            'label' => 'form.current_password',
+            'translation_domain' => 'FOSUserBundle',
+            'mapped' => false,
+            'constraints' => $constraint,
+        ));
+    }
+
     /**
      * {@inheritdoc}
      */

+ 1 - 1
src/Packagist/WebBundle/Resources/config/services.yml

@@ -111,7 +111,7 @@ services:
 
     packagist.profile.form.type:
         class: Packagist\WebBundle\Form\Type\ProfileFormType
-        arguments: ['%fos_user.model.user.class%']
+        arguments: ['%fos_user.model.user.class%', '@security.context']
         tags:
             - { name: form.type, alias: packagist_user_profile }