diff --git a/Products/CMFPlone/browser/login/password_reset.py b/Products/CMFPlone/browser/login/password_reset.py index c56810c857..54610c2f28 100644 --- a/Products/CMFPlone/browser/login/password_reset.py +++ b/Products/CMFPlone/browser/login/password_reset.py @@ -10,6 +10,7 @@ from Products.CMFPlone.interfaces.controlpanel import IMailSchema from Products.CMFPlone.PasswordResetTool import ExpiredRequestError from Products.CMFPlone.PasswordResetTool import InvalidRequestError +from Products.CMFPlone.RegistrationTool import get_member_by_login_name from Products.CMFPlone.utils import safe_unicode from Products.CMFPlone.utils import safeToInt from Products.Five import BrowserView @@ -89,7 +90,8 @@ class PasswordResetView(BrowserView): subpath = None def _auto_login(self, userid, password): - aclu = getToolByName(self.context, 'acl_users') + context = self.context + aclu = getToolByName(context, 'acl_users') for name, plugin in aclu.plugins.listPlugins(ICredentialsUpdatePlugin): plugin.updateCredentials( self.request, @@ -97,7 +99,16 @@ def _auto_login(self, userid, password): userid, password ) - user = getSecurityManager().getUser() + + member = get_member_by_login_name(context, userid, False) + + if member: + user = member.getUser() + else: + # Fallback in case we cannot find a user + # with the given userid + user = getSecurityManager().getUser() + login_time = user.getProperty('login_time', None) if login_time is None: notify(UserInitialLoginInEvent(user)) diff --git a/Products/CMFPlone/tests/pwreset_browser.rst b/Products/CMFPlone/tests/pwreset_browser.rst index 922468f087..65bd1d1315 100644 --- a/Products/CMFPlone/tests/pwreset_browser.rst +++ b/Products/CMFPlone/tests/pwreset_browser.rst @@ -343,6 +343,19 @@ What we do here is quite similiar to 1A, but instead of typing in the password ourselves, we will be sent an e-mail with the URL to set our password. +We will setup an adapter to capture IUserLoggedInEvent events: + + >>> from zope.component import adapter + >>> from Products.PluggableAuthService.interfaces.events import IUserLoggedInEvent + >>> from zope.component import getGlobalSiteManager + >>> events_fired = [] + >>> @adapter(IUserLoggedInEvent) + ... def got_user_logged_in_event(event): + ... events_fired.append(event) + >>> gsm = getGlobalSiteManager() + >>> gsm.registerHandler(got_user_logged_in_event) + + First off, we need to set ``validate_mail`` to False: >>> browser.open('http://nohost/plone/login') @@ -389,6 +402,10 @@ We should have received an e-mail at this point: 3 >>> msg = str(mailhost.messages[-1]) +Let's clear the events storage: + + >>> events_fired = [] + Now that we have the message, we want to look at its contents, and then we extract the address that lets us reset our password: @@ -415,12 +432,24 @@ Now that we have the address, we will reset our password: >>> "Password reset successful, you are logged in now!" in browser.contents True +User is logged in, let's check the event fired for the correct user: + + >>> len(events_fired) == 1 + True + >>> events_fired[0].principal + + Log out again: >>> browser.getLink('Log out').click() >>> "You are now logged out" in browser.contents True +Remove got_user_logged_in_event registration: + + >>> gsm.unregisterHandler(got_user_logged_in_event) + True + 2B. Administrator adds user with email validation enabled --------------------------------------------------------- diff --git a/news/2993.bugfix b/news/2993.bugfix new file mode 100644 index 0000000000..f4be72869c --- /dev/null +++ b/news/2993.bugfix @@ -0,0 +1,2 @@ +Correctly fire events when user autologin after the password has been reset. +[ericof]