Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly fire events when user auto login after the password has been reset #2994

Merged
merged 6 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]