Skip to content

Commit

Permalink
Correctly fire events when user auto login after the password has bee…
Browse files Browse the repository at this point in the history
…n reset (#2994)

* Test if events fired after auto login have the correct principal

* At this point the user is not logged in yet, so we get it from the membership_tool.

* Update changelog

* Remove adapter registration for IUserLoggedInEvent

* Fix unregistering of adapter

* Deal with cases where username/email were not the userid
  • Loading branch information
ericof committed Dec 3, 2019
1 parent 6a8afc8 commit fd7224f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
15 changes: 13 additions & 2 deletions Products/CMFPlone/browser/login/password_reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -89,15 +90,25 @@ 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,
self.request.response,
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))
Expand Down
29 changes: 29 additions & 0 deletions Products/CMFPlone/tests/pwreset_browser.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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:

Expand All @@ -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
<PloneUser 'bsmith'>

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
---------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions news/2993.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Correctly fire events when user autologin after the password has been reset.
[ericof]

0 comments on commit fd7224f

Please sign in to comment.