Ticket #9214 (closed PLIP: fixed)
support logins using e-mail address instead of user id
Reported by: | davisagli | Owned by: | maurits |
---|---|---|---|
Priority: | minor | Milestone: | 4.0 |
Component: | Unknown | Version: | |
Keywords: | Cc: | dukebody, plip-advisories@…, grahamperrin@…, daftdog |
Description (last modified by maurits) (diff)
Proposer: Maurits van Rees
Seconder: Alexander Limi
Motivation
It's a fairly common request to be able to let users log in using their e-mail address rather than a user id. On the recently started plone.uservoice.com website this request ranks highly:
Assumptions
This should be optional, as far as possible. In the RegistrationTool the _ALLOWED_MEMBER_ID_PATTERN should probably be set on zope startup and never be changed during runtime, so we should allow '@' signs there always.
Accounts created in a previous Plone version should still be able to login.
Likewise, a root zope user (say admin:admin) without email address should still be able to login as well; like everyone else this user will be presented with a login form where he is asked to enter an email address, which should in this case be 'admin'. The slight confusion this may give is acceptable. Proposal & Implementation
The email address that a user enters in the join form is set both as user name and as login name (and obviously as the email address property). When changing the email address later the user name will stay the same, but the login name will change. So we always keep the email address and the login name in sync. This is how the collective.emaillogin package currently already does it.
I think it is best to make this optional: a boolean in the site_properties, settable through the Plone UI. Based on the value of this setting we can change the behaviour, and some of the UI as well. An obvious example is the login_form where the label of the first field would be changed from 'login name' to 'email address'.
To get a feel for how much needs to be changed we can look at the collective.emaillogin package. It patches the following:
Products.CMFPlone.RegistrationTool.RegistrationTool._ALLOWED_MEMBER_ID_PATTERN Products.CMFPlone.RegistrationTool.RegistrationTool.mailPassword Products.PasswordResetTool.PasswordResetTool.PasswordResetTool._resetPassword Products.PasswordResetTool.PasswordResetTool.PasswordResetTool.getValidUser
It adds two methods to MemberData:
Products.CMFCore.MemberDataTool.MemberData.setLoginName Products.CMFCore.MemberDataTool.MemberData.validateLoginName
(Could be done in CMFPlone.MemberDataTool actually, as I realize now; and validateLoginName is apparently not used, except in some code in a client project.)
And then 10 skin templates and python files (not counting the metadata files).
Framework team: for an initial vote I would say add collective.emaillogin to a Plone 3.2/3.3 buildout (eggs+zcml) and poke holes in it. Note that with this package there is naturally nothing optional about logging in with your email address anymore. For example, if the login name is missing in the login form, this error message is displayed: 'Please enter your email address.'
collective.emaillogin was started by Guido Wesdorp for a client of Zest Software; I improved it lately as we started using it on a website ourselves.
Alternatively, there is the betahaus.emaillogin package, which seems to have the same goal but a different strategy; I have not looked at that. Deliverables
What code and documentation needs to be produced?
- Merge and adapt code from collective.emaillogin.
- We might need a button to set the login name of current users to their email addresses if known.
- Unit/browser tests
- i18n
- Documentation: mostly just mentioning that this is possible.
Risks
Does it make sense to have emaillogins and Open Id enabled at the same time? Or should these be mutually exclusive? They might bite each other.
Can weird things happen in combination with LDAP?
When you have some accounts already and you switch this on (or you switch it off again later) some confusion may arise: existing users may need to fill in their normal login name in the email address field, or their email address in the login name field.
As Alec said: We will also need extensive template changes throughout Plone if we want to provide users with some privacy and avoid spam. Essentially, we would need to ensure that Plone does not ever display the login_name (including the member folder name).
Participants
Who is signed up to do the work? (Real names and usernames, please)
I can drive this: Maurits van Rees (irc: maurits, plone.org: maurits)
Feedback, testing and other assistence is appreciated.
Progress
Is any of the work done already?
collective.emaillogin can be seen as proof of concept.
Change History
comment:2 Changed 7 years ago by alecm
PAS already has distinct concepts of userid and login_name, do we need to add a third? I don't think there are any real technical hurdles in allowing @ in a login_name. I'd suggest we try to use the userid internally to reference users, rather than the login_name as we often do now. That's a fairly large task though.
comment:3 Changed 7 years ago by maurits
- Owner set to maurits
This is also suggested on uservoice.com, where it is currently in the number 1 position with 11 votes: http://plone.uservoice.com/pages/20503-plone-improvement-ideas/suggestions/216744-email-address-login
To get a feel for how much needs to be changed we can look at collective.emaillogin. It patches the following:
Products.CMFPlone.RegistrationTool.RegistrationTool._ALLOWED_MEMBER_ID_PATTERN Products.CMFPlone.RegistrationTool.RegistrationTool.mailPassword Products.CMFCore.MemberDataTool.MemberData.setLoginName Products.CMFCore.MemberDataTool.MemberData.validateLoginName Products.PasswordResetTool.PasswordResetTool.PasswordResetTool._resetPassword Products.PasswordResetTool.PasswordResetTool.PasswordResetTool.getValidUser
And then 10 skin templates and python files (not counting the metadata files).
Framework team: for an initial vote I would say add collective.emaillogin to a Plone 3.2/3.3 buildout (eggs+zcml) and poke holes in it.
collective.emaillogin was started by Guido Wesdorp for a client of Zest Software; I improved it lately as we started using it on a website ourselves. I could drive this plip (help appreciated).
comment:4 Changed 7 years ago by alecm
We will also need extensive template changes throughout Plone if we want to provide users with some privacy and avoid spam. Essentially, we would need to ensure that Plone does not ever display the login_name (including the member folder name).
comment:5 Changed 7 years ago by maurits
Let's flesh this out into proper PLIP form.
Proposer: Maurits van Rees
Seconder: None as yet
Motivation
It's a fairly common request to be able to let users log in using their e-mail address rather than a user id. On the recently started plone.uservoice.com website this request ranks highly:
Assumptions
This should be optional, as far as possible. In the RegistrationTool the _ALLOWED_MEMBER_ID_PATTERN should probably be set on zope startup and never be changed during runtime, so we should allow '@' signs there always.
Accounts created in a previous Plone version should still be able to login.
Likewise, a root zope user (say admin:admin) without email address should still be able to login as well; like everyone else this user will be presented with a login form where he is asked to enter an email address, which should in this case be 'admin'. The slight confusion this may give is acceptable.
Proposal & Implementation
The email address that a user enters in the join form is set both as user name and as login name (and obviously as the email address property). When changing the email address later the user name will stay the same, but the login name will change. So we always keep the email address and the login name in sync. This is how the collective.emaillogin package currently already does it.
I think it is best to make this optional: a boolean in the site_properties, settable through the Plone UI. Based on the value of this setting we can change the behaviour, and some of the UI as well. An obvious example is the login_form where the label of the first field would be changed from 'login name' to 'email address'.
To get a feel for how much needs to be changed we can look at the collective.emaillogin package. It patches the following:
Products.CMFPlone.RegistrationTool.RegistrationTool._ALLOWED_MEMBER_ID_PATTERN Products.CMFPlone.RegistrationTool.RegistrationTool.mailPassword Products.PasswordResetTool.PasswordResetTool.PasswordResetTool._resetPassword Products.PasswordResetTool.PasswordResetTool.PasswordResetTool.getValidUser
It adds two methods to MemberData:
Products.CMFCore.MemberDataTool.MemberData.setLoginName Products.CMFCore.MemberDataTool.MemberData.validateLoginName
(Could be done in CMFPlone.MemberDataTool actually, as I realize now; and validateLoginName is apparently not used, except in some code in a client project.)
And then 10 skin templates and python files (not counting the metadata files).
Framework team: for an initial vote I would say add collective.emaillogin to a Plone 3.2/3.3 buildout (eggs+zcml) and poke holes in it. Note that with this package there is naturally nothing optional about logging in with your email address anymore. For example, if the login name is missing in the login form, this error message is displayed: 'Please enter your email address.'
collective.emaillogin was started by Guido Wesdorp for a client of Zest Software; I improved it lately as we started using it on a website ourselves.
Alternatively, there is the betahaus.emaillogin package, which seems to have the same goal but a different strategy; I have not looked at that.
Deliverables
What code and documentation needs to be produced?
- Merge and adapt code from collective.emaillogin.
- We might need a button to set the login name of current users to their email addresses if known.
- Unit/browser tests
- i18n
- Documentation: mostly just mentioning that this is possible.
Risks
Does it make sense to have emaillogins and Open Id enabled at the same time? Or should these be mutually exclusive? They might bite each other.
Can weird things happen in combination with LDAP?
When you have some accounts already and you switch this on (or you switch it off again later) some confusion may arise: existing users may need to fill in their normal login name in the email address field, or their email address in the login name field.
As Alec said: We will also need extensive template changes throughout Plone if we want to provide users with some privacy and avoid spam. Essentially, we would need to ensure that Plone does not ever display the login_name (including the member folder name).
Participants
Who is signed up to do the work? (Real names and usernames, please)
I can drive this: Maurits van Rees (irc: maurits, plone.org: maurits)
Feedback, testing and other assistence is appreciated.
Progress
Is any of the work done already?
collective.emaillogin can be seen as proof of concept.
comment:6 Changed 7 years ago by alecm
+1
Thanks for a well thought out PLIP. Fortunately, we have a PLIP for hiding login names already #9305, we'll need to figure out how the UI for these interact. This also ties into the customizable profile fields PLIP #9310, since using email as login will mean turning off the login field at the very least.
The betahaus.emaillogin approach seems to allow the current email address to be used as the login even if it has changed. It also allows users to login with either a userid or an email (this seems to be a fairly common, if confusing, practice). These potential advantages are offset by the obvious scalability issues involved with searching for users by email address in the PAS user plugins. Using a cache of email to login mappings would help, but keeping that mapping in sync on profile data changes would be critical. Unfortunately synchronizing such a cache is likely to be near impossible for external data stores which may be editable from outside of Plone.
comment:7 Changed 7 years ago by maurits
@Alec: With the recent changes I did to collective.emaillogin a changed email address can also be used as login name. If you change your email address two times, then you can still login with your initial address (as that is still the userid) and with your current address (as that is the login name) and not anymore with your second address as that is not known in the system anymore. You can also change your email back to the original. If a new user tries to register, we check if the email address is already a login name or a user name.
@David: Mind if I replace your original placeholder text with the full plip as I wrote it?
comment:11 Changed 7 years ago by alecm
@Maurits: That sounds great. Does this updated solution have potential performance problems for sites with large numbers of users due to searching users by email address to perform login? If it caches user->email mapping, does it manage to keep those in sync with profile changes? I'm also still concerned about privacy/spam issues, since we use the login name in a lot of places (someone could harvest email addresses by simply walking the site and appending /Creator to every url, even if we stop showing the login name on every page). We need to be very careful with the implementation, but we really do need this feature.
comment:14 Changed 7 years ago by maurits
Alec: no performance problems. When changing your email address, the login name is changed to that address as well. So no user-email mapping is needed.
comment:15 Changed 7 years ago by erikrose
- Owner maurits deleted
Clearing Owner field of 4.0 PLIPs so we can use it to mean "implementor". (Many of these owners were automatically assigned from choosing a Component that had a default owner.)
comment:17 Changed 7 years ago by rossp
- Owner set to maurits
I believe in this case the owner was set intentionally
comment:18 Changed 7 years ago by rossp
FWT vote +1
comment:19 Changed 7 years ago by MatthewWilkes
As long as when this is disabled it doesn't change the login_name to the email address…
FWT Vote: +1
comment:20 Changed 7 years ago by maurits
@MatthewWilkes: agreed, when this is disabled the current standard behaviour of Plone will be used.
comment:21 Changed 7 years ago by davisagli
FWT vote: +1
comment:22 Changed 7 years ago by raphael
FWT vote: +1
comment:23 Changed 7 years ago by calvinhp
FWT Vote: +1
comment:24 Changed 7 years ago by erikrose
Having spent a lot of time in the PAS and membership code, I'm concerned at adding more branches in there; there are a lot of cleanups that should happen first.
- As alecm says, we need need NEED to stop using loginname to reference users internally; userid is the correct immutable key. I routinely change loginnames when clients move from Plone's built-in auth to our Kerberos auth.
- The OpenID plugin has to do some truly awful hacks (the same ones I do in WebServerAuth) to be able to authenticate a non-enumeratable user; that needs to get fixed in PAS.
- The setting of the last-login time and, IIRC, the firing of some important events are essentially hard-coded into the login_form. These should be moved elsewhere so non-form-based login can be a first-class citizen.
I wonder if email-based login could be better implemented as an add-on once we improve the hook situation in PAS and the rest of the auth code.
FWT vote: -1 for now. I think the idea is good, given that so many people seem to request this, but I want to be sure we implement it in a maintainable way rather than just glomming more branches onto an already hard-to-follow subsystem.
comment:25 Changed 7 years ago by esteele
Approved by FWT vote.
comment:26 Changed 7 years ago by rossp
I emailed Maurits but he never responded.
comment:27 Changed 7 years ago by maurits
- Status changed from new to assigned
Plip ownership accepted by me. I am briefly back from one vacation and entering into the next. :)
comment:29 Changed 7 years ago by maurits
comment:30 Changed 7 years ago by erikrose
comment:31 Changed 7 years ago by davisagli
comment:32 Changed 7 years ago by esteele
Your PLIP has been reviewed by the Framework team. Feel free to discuss any suggested changes either here in the PLIP ticket or on the mailing lists. Final deadline for this PLIP is set for September 30.
comment:33 Changed 6 years ago by maurits
comment:34 Changed 6 years ago by maurits
comment:35 Changed 6 years ago by davisagli
comment:36 Changed 6 years ago by MatthewWilkes
Looks good, FWT vote +1
comment:37 Changed 6 years ago by erikrose
comment:38 Changed 6 years ago by rossp
FWT vote: +1 for merging
comment:39 Changed 6 years ago by dukebody
I'm concerned about the confusion that switching this feature on and off in existing sites could create. As stated in the PLIP readme:
""" Enabling this on a website that already has users may be confusing for those users. When logging in they will be asked for their email address, but these existing users should actually still login with the login name they have chosen. """
Also: """
- If you change your email address, you can no longer login with your original email address, though that is still your user id. A user created before use_email_as_login was switched on can only login with his original login name until the first time that he saves his personalize_form. After that he needs his current email address. We could allow the user id to be used for login as well. I thought I had that working with the collective.emaillogin package, but apparently not. It can be done if we want this. It would need a change in PluggableAuthService.py in the _verifyUser method; basically doing a second pass over that function with the passed login name used as user_id instead.
"""
User id and login name are different things AFAIK. According to the README, the migration back to plain login names uses user ids as login names, mixing them (althought I have no idea about what could be a use-case where one needs login names different from user ids).
Wouldn't it be simpler to create a PAS authentication plugin which searches the user database for a user with the entered email address and try to authenticate it? If there are serious perfomance problems in sites with many users, we could create a catalog of (user id - email) pairs. Also, this approach would allow both email and username login simultaneuslly (the email login PAS plugin just has to fail).
My two cents. :)
comment:40 Changed 6 years ago by esteele
This PLIP has been accepted for merging into Plone 4.0
The final vote was: Alec Mitchell +1 David Glick +1 Erik Rose +1 Laurence Rowe +1 Matthew Wilkes +1 Ross Patterson +1
Please merge your branches into the Plone 4.0 head by end-of-day Friday Oct 16. If you need assistance with merging, please contact me.
We'll be assigning a documentation ticket to this PLIP shortly. Please assist the docs team in documenting the changes and new features that this PLIP introduces.
comment:41 Changed 6 years ago by maurits
comment:42 Changed 6 years ago by maurits
comment:43 Changed 6 years ago by maurits
(In [30320]) Added @@migrate-to-emaillogin browser view so admins can update the login names of existing users. It can check for duplicate emails and can update the login name of all users to their email addresses or back to their user ids. Added use_email_as_login property to security control panel. Refs #9214
comment:44 Changed 6 years ago by maurits
comment:45 Changed 6 years ago by maurits
- Status changed from assigned to closed
- Resolution set to fixed
Okay, plip 9214 has been merged!
comment:46 Changed 6 years ago by esteele
Please assist the doc team in creating/updating documentation relating to this PLIP. See #9621.
comment:47 Changed 6 years ago by maurits
(In [30720]) Integrated the 'email as login' plip (#9214). Made the email field and widget ascii-only, otherwise you get validation errors or unicode errors when trying to log in. Always show the email field. Made the code more robust against input errors, at least for the username and email fields. Fixes #9643, refs #9310 and refs#9214.
comment:48 follow-up: ↓ 49 Changed 6 years ago by daftdog
When activating email as login and member folder creation, the member folder's ID sort of reveals the email address. A user with the email-address test@… will get a member folder with id test-40test.org. To me that is too close to the real address to deter spammers. IMHO it would make much more sense to use the email address solely for the login, but have member.getId() return the ID that was set during registration.
comment:49 in reply to: ↑ 48 ; follow-up: ↓ 50 Changed 6 years ago by maurits
Replying to daftdog:
When activating email as login and member folder creation, the member folder's ID sort of reveals the email address. A user with the email-address test@… will get a member folder with id test-40test.org. To me that is too close to the real address to deter spammers. IMHO it would make much more sense to use the email address solely for the login, but have member.getId() return the ID that was set during registration.
This is already happening, but the email address is used as both login name and user id (returned by getId()) so you don't notice a difference.
comment:50 in reply to: ↑ 49 Changed 6 years ago by daftdog
- Cc daftdog added
Replying to maurits:
This is already happening, but the email address is used as both login name and user id (returned by getId()) so you don't notice a difference.
I debugged into the member folder creation code, and it determines the member folder's id by checking getId(), which returns the email address. The id/url of the member folder is thereby the email ad (with the @ encoded as -40). We will have public member folders in a project I'm working on, and I really think showing the email ad in the URL is a bad idea.
I'm pretty sure we need some sort of mapping facility in any case, to properly support things like OpenID. We can't use the email address as a user ID, but we can generate one, so that "user@…" becomes user ID "user" (or user2, user3, etc if it's taken). Then there's a simple mapping from the email address to the ID, so we can change the email without renaming the user.
Related, a useful overview of the latest changes to OpenID adoption and UI: http://www.25hoursaday.com/weblog/2009/05/22/OpenIDsTippingPoint.aspx