Repository: pennersr/django-allauth

Issue:
Automatically Sign In on Password Reset
When a password reset link is clicked you are able to set the password for a certain account. Afterwards you still have to sign in with your credentials (which you just entered). This feels unnecessary since you clearly know the password for the account. 
Is there a reason why this is not done currently?



Discussion:
I don't think either way is inherently wrong, but I think the reasoning for this is the expectation of the user. 

When I change my password, I sort of expect to have to log in since I never actually logged in the first time. If you automatically log a user in after changing their password, you introduce an element of surprise to the user - they may not even realize they are now logged in.

I think that you could attain this functionality, though, by simply customizing the reset form or adapter.

I'm facing the same situation as the OP, and as I see it's not possible to implement this behavior by customizing the form or the adapter — the `PasswordResetFromKeyView` view needs to be adjusted.

Doing this in 3rd party code is possible but a mess at the same time because you have to override the URL pattern to route to your custom view. Doing it directly in allauth looks simple OTOH: conditionally implement the requested behavior behind a setting in [`form_valid()`](https://github.com/pennersr/django-allauth/blob/ef8fe4ec2d7013e517bd1c480834cf2bcb131545/allauth/account/views.py#L592-L600).

@pennersr would you be willing to accept such a PR?

You could probably log the user in by hooking into the signal that is that is sent in the form_valid method of `PasswordResetFromKeyView`:

`signals.password_reset`

If you do this, make sure you update the template, `password_reset_from_key_done.html` so that you inform the user they are now logged in.

Oh, undocumented signals :) I'm creating a PR for those as a start.

Allowing this flow in Allauth directly wouldn't hurt IMO. Moreover, there's already the `ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION` setting for a similar behavior. Let's hear from @pennersr.

@julen @pennersr I guess I'm generally a fan of not adding settings if they can be avoided. Settings like these build up and create a ton of forks in the logical flow of the code. AllAuth is already very easy to extend for your own needs. I think that it's power is in the ability to take the framework built in and adapt it if and when you have to. 

Yes I agree on the point of setting bloat, but in this specific case my understanding is that it aligns with what Allauth currently has.

Oh, forgot to comment here. Last week I tried to implement this using the `account.password_reset` signal, but it has the obvious drawback that redirects from `utils.perform_login()` are not taken into account. Therefore still the `/password/reset/key/done/` page is displayed, which is superfluous and not the best UX so far.

@pennersr would appreciate to hear from you if you'd be fine to consider this feature.

Django 1.7 onwards, this helper function can be used by inheriting from one of the password set/reset views, and changing `form_valid`

https://docs.djangoproject.com/en/1.8/topics/auth/default/#django.contrib.auth.decorators.update_session_auth_hash

On this topic, opinions vary. This provides a nice summary:

http://security.stackexchange.com/a/40735

Personally, I tend to agree with the reasoning for not logging in. As a matter of fact, I`ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION` should be reverted to default to `False` as well for this reason. 

I prefer to keep the number of settings as small as possible, but in cases like these where opinions vary and no convincing case can be made for always choosing one or the other, I feel it is valid to add support for this via a setting.


Resolving patch:
diff --git a/allauth/account/app_settings.py b/allauth/account/app_settings.py
--- a/allauth/account/app_settings.py
+++ b/allauth/account/app_settings.py
@@ -185,9 +185,16 @@ def CONFIRM_EMAIL_ON_GET(self):
     @property
     def LOGIN_ON_EMAIL_CONFIRMATION(self):
         """
-        Autmatically log the user in once they confirmed their email address
+        Automatically log the user in once they confirmed their email address
         """
-        return self._setting('LOGIN_ON_EMAIL_CONFIRMATION', True)
+        return self._setting('LOGIN_ON_EMAIL_CONFIRMATION', False)
+
+    @property
+    def LOGIN_ON_PASSWORD_RESET(self):
+        """
+        Automatically log the user in immediately after resetting their password.
+        """
+        return self._setting('LOGIN_ON_PASSWORD_RESET', False)
 
     @property
     def LOGOUT_REDIRECT_URL(self):
diff --git a/allauth/account/views.py b/allauth/account/views.py
--- a/allauth/account/views.py
+++ b/allauth/account/views.py
@@ -614,6 +614,11 @@ def form_valid(self, form):
         signals.password_reset.send(sender=self.reset_user.__class__,
                                     request=self.request,
                                     user=self.reset_user)
+
+        if app_settings.LOGIN_ON_PASSWORD_RESET:
+            return perform_login(request, self.reset_user,
+                                 email_verification=app_settings.EMAIL_VERIFICATION)
+
         return super(PasswordResetFromKeyView, self).form_valid(form)
 
 password_reset_from_key = PasswordResetFromKeyView.as_view()


Test patch: