UserAuth BC layer is not working for modules that use it to provide email based logins

Created on 2 May 2024, almost 2 years ago
Updated 25 June 2024, over 1 year ago

Problem/Motivation

In Drupal 10.2, you could allow e-mail authentication simply by overriding the UserAuth service because it was also responsible to look up the user belonging to that identifier.

📌 Optimize user logins by avoiding duplicate entity queries Needs work changed this. And while it was reverted and improved, there are still two issues with the BC layer, both breaking modules like https://drupal.org/project/mail_login (has no tests unfortunately).

Note: email_registration is currently not affected by the regression directly, it only just recently added a UserAuth service in 2.x and even that is double-layered also by a custom UserAuthenticationController (that was added in a different issue at the same time) *and* form alters that were used historically for this.

There are two problems with the implementation in 10.3.

a) In 10.2, while flood control did only run if the login form and the controller, it afterwards still did the authenticate() calls, allowing other modules to identify a user where core failed to do so. In 10.3, there is BC for the old API method, but it is only called if core was able to identify the user previously based on the username.

b) The BC layer checks that the UserAuth service implements the new interface. However, both email_registration and my own custom code subclassed the UserAuth class, so automatically and unknowingly also implementing the new interface.

Steps to reproduce

Install mail_login, try to log in via e-mail.

Proposed resolution

To fix the two issues, I'd propose:

a) Move the authenticate() BC call out of the if ($account) condition, which I guess should be combined with the interface check.

b) Deprecate the old UserAuth class completely, introduce a new UserAuthentication class that core uses by default. This still needs to implement both interfaces to be backward compatible to old code that still calls ->authenticate(). But classes that subclass UserAuth will not automatically implement the new interface. This has the added benefit that we can fully deprecate the old class, which helps to alert modules using it as a parent class about its deprecation.

Note: The longterm fix for a module like mail_login is to implement the new service and only override lookupAccount() (and authenticate() for BC for other modules). I did that in my custom implementation and it works great, plus it then fully integrates with flood control protection, requiring no extra code for that and also allows those modules to properly benefit from the core performance improvements.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Fixed

Version

10.3

Component
User system 

Last updated 5 months ago

Created by

🇨🇭Switzerland berdir Switzerland

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024