Password reset tool for Plone
The Password Reset Tool hooks into the standard mechanisms for password mailing provided by the CMF in the Registration Tool and certain skins and replaces this with a facility for resetting passwords with email authentication.
This is useful not only to keep passwords out of cleartext email and is absolutely necessary if you choose to encrypt your passwords (and you should.)
See the INSTALL.txt file for details on installation, and the LICENSE.txt file for the license this Product is under.
Note, of course, that you must have a working MailHost to send email!
The Password Reset Sequence from the User’s Point of View
The user will observe the following steps.
- User forgets a password and
- clicks “Forgot your password?”, which
- goes to a form that asks for a username. User fills this in and clicks a button to proceed, which
- goes to a form explaining that an email has been sent.
- User receives an email with a URL containing a random, unguessable key and opens it in a web browser.
- This is a form that asks for username and password, which goes to
- a form reporting success (or failure, if expired or illegitimate.)
Configuration of the tool is done through the ‘Overview’ page in the ZMI. The options are explained there.
Reset requests are stored in a persistent dictionary in the tool. Removing the tool or uninstalling the product will destroy all reset requests.
A facility for clearing expired requests is not yet provided. It will be in the next release. This should be used occasionally to clear out the storage. A cron script using ‘wget’ or ‘curl’ (or the Windows equivalent) to automate the procedure is suggested.
You can turn username entry off, if you so desire, as this will streamline the process. You SHOULD NOT DO THIS if you are concerned about account security. Not requiring re-entry of the user name allows trivial email-sniffing attacks and makes brute-forcing of the reset request keys possible (if unlikely). Only private portals should even consider this.
The URL for the confirmation visit now uses traversal-style URL parameters to encode the key. The old get-parameter paths will still work, so don’t worry about password reset request performed before an upgrade
The traversal_subpath urls (like passwordreset/123lkj43508) are now the default. If you like the old style, you’ll have to modify the skins yourself.
This tool replaces the built-in password mailing feature. This means that the first half of a “forgotten password transaction” depends on skin names set in CMF code.
However, it can be made independent, if you so desire. Simply provide an equivalent to:
- ‘mail_password_form’: Asks for your username, and provides instructions as to what’s to come.
- ‘mail_password’: Receives the request from mail_password_form, calls ‘requestReset’ on the tool, and sends a message with the return URL however you care to construct it (usually in ‘pwreset_constructURL’, which depends on what the equivalent to ‘passwordreset’ is named.) Returns the equivalent of ‘mail_password_response’.
- ‘mail_password_template’: Provides the text of the email.
- ‘mail_password_response’: Informs that the mail has been sent. Naturally, the methods and templates on the other side will need to be migrated over or have equivalents made as well. If outside the CMF, certain source changes will also be needed, such as overriding ‘getValidUser’.
This tool has been made with customization in mind. There are several customization points in the code that should allow you to change certain policies simply by subclassing the tool and overriding one or two methods.
- Password reset emails will now be sent from the navigation root instead the portal, enabling support for multilingual sites and other subsites to keep the correct language, title, menus and designs. [regebro]
- Nothing changed yet.
- Always try to look up what the user entered as a login name before treating it as a user id. [davisagli]
- Make sure password reset form action url is based on the reset tool and not the “passwordreset” python script. Fixes issue where the “passwordreset” was executed before the pwreset_form action handler was traversed to and caused an error before the reset request could even be attempted. [vangheem]
- Fix exception when use_email_as_login is on and the user enters an invalid login on pwreset_form. [davisagli]
- Fixed typo in registered_notify_template.pt: capitalization of sentence start.
- Fixed undefined django_crypto. [maurits]
- Use system random when available. This is part of the fix for https://plone.org/products/plone/security/advisories/20121106/24 [davisagli]
- registered_notify_template.pt: show login name instead of user id. Normally this is the same, but this is not necessarily true when using the email address as login name. [maurits]
- Changed deprecated getSiteEncoding to hardcoded utf-8 [tom_gross]
- Be less sensitive for white space differences in tests. [maurits]
- getExpirationTimeout() now returns the correct number of hours, and not a value 24*24 times too low. (The code was never used though, since _timedelta does currently not store a timedelta but an int.) [kleist]
2.0.6 - 2011-06-02
- Apply patch to prevent exploitation of CVE-2011-1948 (Hotfix 20110531.) [elro]
- Fix edge case where member.fullname returns None instead of a string (ZMI or emergency user resets) [eleddy]
2.0.5 - 2011-01-03
- Depend on Products.CMFPlone instead of Plone. [elro]
- URL for login form is now ‘/login’ instead of ‘login_form’, adjust tests accordingly. [esteele]
2.0.4 - 2010-11-23
- Fallback import to work with Plone 3. [elro]
2.0.3 - 2010-09-20
- Fix the fix to http://dev.plone.org/plone/ticket/11136. [davisagli]
- Fix string exceptions in pwreset_action.cpy [davisagli]
2.0.2 - 2010-09-17
- Fix userid/login mixup which made it impossible to reset the password in environments where userid and login name are not equal. This fixes Plone ticket 1136. [wichert]
2.0.1 - 2010-07-31
- Added line feed after the reset_url in mail_password_template. It was impossible to reset the password by clicking the url because there was “(This” at the end. [vincentfretin]
2.0 - 2010-07-18
- Updated markup of password reset form. This closes http://dev.plone.org/plone/ticket/10768. [hannosch]
2.0b7 - 2010-03-03
- Avoid test failures caused by access to hardcoded temp directories. [hannosch]
2.0b6 - 2010-02-18
- Allow imports of PasswordResetTool exceptions from restricted Python. [esteele]
- Updated templates to recent markup conventions. References http://dev.plone.org/old/plone/ticket/9981 [spliter]
- Convert the string exceptions into class exceptions, since string ones don’t work in Python 2.6. Fixes http://dev.plone.org/plone/ticket/9743 [dukebody]
- Changed registration email to not rely on the request to hold the full name; instead the new member object is queried. [mj]
2.0b5 - 2010-01-28
Changed mail_password_template.pt to the one proposed by limi:
The following link will take you to a page where you can reset your password for XYZsite:
http://example.com/resetpassword/c635bf8d892f4f30dd868d16c1 (This link is valid for X days)
If you didn’t expect to receive this email, please ignore it. Your password has not been changed.
This close ticket http://dev.plone.org/plone/ticket/8694 [amleczko]
The activation email no longer enumerates the hours before expiry, but gives a date/time instead. This fixes http://dev.plone.org/plone/ticket/9116. [limi]
2.0b4 - 2009-12-27
- Fixed package dependencies. [hannosch]
2.0b3 - 2009-12-16
- Fixed failing test after recent plone.app.users change: we never send the password in the email, only a link to set the password. [maurits]
2.0b2 - 2009-12-03
- Put a new line before greetings in registered_notify_template.pt [vincentfretin]
2.0b1 - 2009-12-02
- Make adjustments to fit with Plone 4’s new @@register and @@new-user. [maurits]
- Fix issue where subject headers got double-encoded. [davisagli]
2.0a1 - 2009-11-15
- Properly encode mail headers (From and Subject). Fixes #8070 [naro]
- When the new (Plone 4) property use_email_as_login is present and is True, we try to get the member by login name when userid gives no results. Refs http://dev.plone.org/plone/ticket/9214. [maurits]
- Avoid acquiring portal_properties and call it via a proper API. [hannosch]
- Converted installation code to a GenericSetup profile. [hannosch]
- Cleaned up package metadata and general codebase. [hannosch]
- Declare package dependencies, fixed deprecation warnings for use of Globals and fixed deprecation warnings for the md5 module. [hannosch]
1.2 - 2009-05-16
- Cleanup package metadata and add it to the egg description. [wichert]
- Internationalized dates in mail_password_template [vincentfretin]
- Removed duplicate DOCTYPE definition from mail_password_form. [limi]
- Adjusted browser tests to no longer rely on the login portlet. [hannosch]
- Catch RunTimeError when changing a password fails. Fixes #5742. [maurits]
- Added i18n domain for the userid label in the password reset form. [markvl]
- Purged old Zope 2 Interface interfaces for Zope 2.12 compatibility. [elro]
1.1 - 2008-03-26
- Fixed browser tests. [hannosch]
- Set correct i18n:domain on subject, fixes #7217. [martior]
- Move trunk into the egg. [wichert]
- Removed i18n folder. Translations are part of the PloneTranslations product for some time now. [hannosch]
- Providing ‘fullname’ now for email notification. This does not really close http://dev.plone.org/plone/ticket/6680, but makes it possible to use the information the user provided in the mail notification (and its translations). [gogo]
- Fixed four occurrences of the term login name which wasn’t used anywhere so far. We only use user id and user name. [hannosch]
- Updated tests to work with Zope 2.10 / Plone 3.0. [hannosch]
- Converted mail_password_template from a dtml page to a Page Template, as dtml pages cannot be translated anymore. [hannosch]
- If available use the email_charset property instead of default_charset to encode mails. [hannosch]
- Added the portal name to the subject in the registered_notify_template.pt, so it’s easier to distinguish those mails for various websites. This closes http://dev.plone.org/plone/ticket/5242. [hannosch]
- Replaced some last occurrences of the term member with user. [hannosch]
- Fixed some minor whitespace issue in registered_notify_template.pt. [hannosch]
- allow password reset token to be passed in, in cases where we might not have the permission to request a reset from within the template [rafrombrc]
- protect requestRest method of the tool so it can not be called anonymously through the web interface
- Removed unused import in install code
- use virtual host forwarded IP if present
- i18n markup (translations in PloneTranslations)
- fixed DTML markup to not fail on missing translations
- fixed root link in pwreset_expired template
- deprectation warnings removed
- tabindex not assumed present to be more CMF-friendly
- add stats to ZMI page
- implement expired record clearing on every request
- work around traversal bug with python: expressions instead of path expressions for attributes
- Updated to use CMFFormController
- Support for using to set initial account passwords
- Verify token before prompting user for new password
- Generated URLs don’t use query strings
- Fixes to work with CMFMember