https://www.drupal.org/node/2919733 patch has unintended consequences on usernames. Previous to this release, a user like thisIsMyEmail@gmail.com would create a username like:
thisIsMyEmail
After this release, the username is initially the above, but after email validation becomes something like:
email_registration_pptmXg1MkW
This is due to the hook-name change in the related issue.
This results in some conflicting / irrelevant logic:
- The following block of logic in email_registration_user_insert() is a little moot as the user name is overwritten once the account is validated
if (empty($names)) { // Strip off everything after the @ sign. $new_name = preg_replace('/@.*$/', '', $account->getEmail()); // Clean up the username. $new_name = email_registration_cleanup_username($new_name); } - The user name will keep changing every time the user form is saved because of this bit of code in the hook:
$form['account']['name']['#value'] = 'email_registration_' . user_password();This can make it very confusing for admins as user's usernames will keep changing.
- Most importantly hook_email_registration_name() is also moot as the username keeps getting reset to something like email_registration_pptmXg1MkW after registration.
Comments
Comment #2
nickgee commentedComment #3
nickgee commentedJust commenting to flag that I've added #3 above, which highlights that hook_email_registration_name() is irrelevant with the changes in rc6.
Comment #4
gregglesSorry to hear about this bug. Thanks for identifying where it was introduced. I've referenced this issue from there and also added this as a release blocker on #3021912: Plan for creating email registration 8.x-1.0 final stable.
One thought:
> This can make it very confusing for admins as user's usernames will keep changing.
My sense is that the best way to use this module is to just consider emails, and not usernames. There's also the idea of using a "real name" profile field that is shown to admins and hiding the username.
Comment #5
nickgee commented@greggles, I agree that with this module we shouldn't really be using usernames, except with this one caveat:
Using user emails, specifically $user->mail (i believe) can be problematic for certain cases because Drupal requires permissions to see other user's email addresses. Ex. views (entity reference source display).
But that is a separate issue. (Regardless, I think having a stable username is best.)
Thanks for the quick reply. I've reverted my module to rc5 but I'm happy to test patches! :)
Comment #6
gregglesTotally makes sense, I just meant for admins it's ideal to use emails (if they are the kind of admin that sees emails, which I guess I'm assuming but might not be the case).
Comment #7
lukas.fischer commentedI just want to emphasize that this is critical. I was using email_registration together with masquarade. Finding the correct user with masquared
is impossible with "email_registration_***".
Comment #8
alduya commentedThis newly introduced behaviour makes the Allow log in with email address or username functionality completely useless.
It will also require every site using this module to change the /admin/people overview and have a solution for some of the emails that are sent from the website (those using the [user:display-name] token).
Comment #9
andreynacarrasco commentedHi @greggles (and everyone), for now I resolved the issue changing the function email_registration_form_user_form_alter like rc5 version (until a new version it's release):
In email_registration.module file:
1.- The function name email_registration_form_user_form_alter was modified to email_registration_form_user_register_form_alter.
2.- Then added function email_registration_form_user_form_alter again with the code:
I didn't analize all the funtionality involve in this reverse to rc5 version, so please @greggles tell us if it's ok to make this temporaly change, or if it's possible that conflicts occur (I did several tests and for now everything works correctly, but I may be ignoring something).
Thanks in advanced.
---Spanish
Hola @greggles (y a todos), por ahora resolví el error cambiando la función email_registration_form_user_form_alter tal como estaba en la versión rc5 (hasta que se publique una nueva versión):
En el archivo email_registration.module:
1.- El nombre de la función email_registration_form_user_form_alter fue modificado a email_registration_form_user_register_form_alter.
2.- Luego se agregó nuevamente la función email_registration_form_user_form_alter con el código:
No analicé toda la funcionalidad involucrada en éste reverso a la versión rc5, así que, por favor @greggles, indicar si está bien hacer éste cambio temporal, o si es posible que ocurran conflictos (hice varias pruebas y por ahora todo funciona correctamente, pero puedo estar obviando algo).
Gracias de antemano.
Comment #10
mattjones86This is just caused me some headaches on a few Drupal sites we've included this module on.
Put @andreyna 's fix into a patch.
Comment #11
gregglesI believe that patch in #10 basically just reverts the changes in #2919733: Alter AccountForms instead of just registration form when using this module. so I think that's not an ideal solution. Perhaps since this causes a lot of problems for people it's worth committing a revert of that change and then reopening that issue.
Comment #12
pradosh15 commentedBecause it does not check the default value for name field exist or not. And assigning "email_registration_'. user_password()"
value in email_registration_form_user_form_alter username is changing on save. And as password is encrypted it is getting strange value e.g. email_registration_Aghs1dsh. This patch will fix that issue.
Comment #13
pieterdcThe first part of the patch in #10 reverts https://cgit.drupalcode.org/email_registration/commit/?id=23596fe The second part of the patch was not in #2919733: Alter AccountForms instead of just registration form when using this module..
Created a patch which only reverts the code from the issue @greggles mentioned in his previous comment.
Comment #14
greggles#12 looks like a great solution! Can folks please test that?
Comment #15
henk commented#12 will probably work, but to check that default user name value will be saved, fix can be improved to:
Value input in form doesn't have default_value parameter so will be not used: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21...
Comment #17
andypostbtw User in d8 has some set of entity forms - registration & default http://cgit.drupalcode.org/drupal/tree/core/modules/user/src/Entity/User...
I bet on keep 2 form hooks separate, so like #10 + #15
Comment #18
andypostsurely it needs test coverage
Comment #19
henk commentedI merge #10 + #15, do not add 'Display name' label for value type doesn't make sense. Should pass tests now.
Comment #20
henk commentedComment #21
darrenwh commentedThis may come in handy to fix accounts that have been changed:
Comment #22
darrenwh commentedRTBC . Works fine
Comment #23
knyshuk.vova commentedThe patch looks good and applies successfully. +1 for RTBC.
Comment #24
ptmkenny commentedAs per comment #18, this needs tests to make sure it doesn't happen again in a future release.
Comment #25
opdaviesComment #26
Senthil Kumar Kumaran commentedWhen will the fix be integrated to the module?
This is partly a security concern as the encrypted password is visible in the pages. Kindly apply the fix to the module with an update as early as possible.
Thank you.
Comment #27
henk commented@Senthil Kumar Kumaran it is generated a random alphanumeric password so security is not a problem, function name is not clear but you can read it here https://api.drupal.org/api/drupal/core%21modules%21user%21user.module/fu...
@ptmkenny what kind of tests you propose? Probably we need some functional test here base on BrowserTestBase?
Comment #28
Senthil Kumar Kumaran commented@henk Thank you for the response. However, i'm still waiting for update to get the fix applied in module.
Comment #29
opdaviesI guess as per #18, it's waiting for tests to be added to ensure that the issue is indeed fixed and also can't be re-introduced in a future release as a regression.
The most recent patch in #19 includes no tests for this change.
Comment #30
henk commentedThis problem appear when user was edited and saved, e.g. activated. Current test have only "Test email_registration_unique_username()." register user case. Not for editing user. I will try to update tests and add scenario for user edition, should fix problem.
Comment #31
andreynacarrasco commentedPatch #19 works fine. Thanks @henk
Comment #32
chris pergantis commentedI am believing that one consideration is not in the mix here. Perhaps I am missing something in this message thread but I am adding one caveat to this issue. To most users of a website their username is something that gives them an identity on the the site. It goes next to their content their comments and may be how the other users at the site address them in their personal contact forms. The module needs a different generation of a user name and an option to allow a user (based on the original permissions of core) to change their user name. To a user their username is not a generated blob of letters.
Comment #33
chris pergantis commentedWith patch #19 and then adding the patch located here https://www.drupal.org/project/email_registration/issues/3034828 we have a working email_registration module. Thanks.
Comment #34
ptmkenny commented@Chris Pergantis Your comment in #32 is not really related to the issue at hand; please open a new issue if you want to start a discussion on a different topic.
To give users the ability to have a name to represent themselves on the site, you can use this module in combination with the Real Name module.
Comment #35
jeroentPatch attached, contains a test to check if the username stays the same when editing the user.
Comment #36
jeroentComment #38
jeroentUnused use statement. I guess this can be fixed on commit.
Comment #39
jeroentComment #40
Waldoswndrwrld commentedTested & works as expected.
Comment #41
klausiwrong comment, this is hook_form_FORM_ID_alter() as it was before #2919733: Alter AccountForms instead of just registration form when using this module., right?
Why do we have 2 form alters now? Does this fix work with the changes in email_registration_form_user_form_alter() only?
we should have a comment here that this form alter applies to the user registration form AND the user edit form. That is why we have to check for existing user names in #default_value.
unused use statement
never use random data in tests as this can lead to random test fails. Better hard-code a fixed test user name here.
never use t() in tests when you are only testing the English version of the site anyway.
I know, the other test code probably violates this as well but all new test code should be written correctly.
Comment #42
weseze commentedPatch in #10 works for me, patch in #35 does not. Using form_mode_manager and account_field_split. (which complicates things ;))
Please also consider the the $form['account']['name'] might not even be present if it was disabled. We are doing this all the time using different form modes with form_mode_manager module.
And please also consider that a module like account_field_split renders the username field in $form['name'] instead of $form['account']['name'].
So before making changes to the username in the form array we should always check if it exists first.
Comment #43
gclicon commentedThe patch still needs some work. Setting the #value to 'email_registration_' . user_password() or to the #default_value will will hijack the username field and not allow any other modules to update the username.
For my use case, admin users need to be able to set the user name to a specific username for our REST endpoint users. In my custom module I have a form alter where I check that the admin has permission to administer users and then set the field back to type textfield. On save, because we're copying the #default_value to the #value field, the new value does not get saved.
Simply checking if #default_value is empty and then setting the 'email_registration_' . user_password() will work better.
Comment #44
jeroentMade changes as suggested by Klausi in #41.
Comment #45
jeroentIn hook_form_alter, the type of the field is changed to "value". The only valid way to set a value for type value is using '#value' :
Comment #46
klausiThanks, looks good!
Comment #47
brandonratz commentedPatch #44 fixes the issue for me when saving a user form. However, if the user had already been saved the botched username persists. This is likely expected behavior as the module shouldn't update the username on form submission. But I cannot be certain? A fix might be the aforementioned #3.
Comment #48
jeroent@brandonratz, have you tried the suggestion in #21?
Comment #49
henk commented@JeroenT Thanks! test do not check account edition and after edit problem appears not after login (in my case). So bug is not covered by the tests still. Following steps:
Comment #50
stefanos.petrakisSome thoughts on this fun issue:
#42 touches a topic that hasn't been addressed so far.
#49 Claims that the new tests are not specific to the editing of an account
Additionally, and after reading through this issue as well as the source of this problem (#2919733: Alter AccountForms instead of just registration form when using this module., I found another way to tackle this.
Simply put: The form_alter logic should only kick in if the form has to do with a registration, i.e. new user creation.
I am attaching updates to #44 where the tests are more specific (following #49) and the form_alter uses an alternative condition before applying changes. Also checking if the 'name' element is even present (see #42)
P.S.: Point 4 from #41 hasn't been addressed yet, calling
createUser()basically callsrandomMachineName()under the hood. In this case there is nothing wrong with this though, since the generated machine name is never going to mess with the logic we are testing.Comment #52
stefanos.petrakisTaking this back as it didn't fix the problem, the better implementation would be like this:
However I think I just fully realized what @henk meant at #49, the tests were green, even though the code was failing. Will be looking at the tests soon.
Comment #54
stefanos.petrakisTests are doing the job, "Needs review" is correct.
Comment #55
klausiThe problem with the patch from #52 is that it now always shows the user name form field when editing a user.
So you are introducing a behavior change with that. Previously the user name form field was hidden, not editable by an admin or the user. With your patch the user name field can now be edited. Is that desired behavior? Looks like we have no test coverage for that, should probably be decided in another issue.
I did not fully understand comment #49. Should we just add a logout and then login check after editing in the test?
So let's expand the test and then go back to the approach in #44 to avoid the form field behavior change.
Comment #56
jeroent#49 that's exactly what I tried to test:
Comment #57
stefanos.petrakis#55: I don't know why this is introducing a behaviour change, maybe I am missing sth. The only change #52 introduces is the conditional wrapping to make sure the form alterations apply only to forms that create new user objects (i.e. registrations) and don't edit existing ones. This is quite close to the state of things before the change from
user_register_formtouser_formwas introduced that caused the current regression. My intention is to revert that change in a way that still facilitates the request from #2919733: Alter AccountForms instead of just registration form when using this module.#49: I would also like to know that, I assumed that a test failure when calling
drupalLogin()is not a specific as checking if the user name was modified which is what I tried to check in my modified version of the tests.Thanks for the feedbacks in any case, much appreciated!
Comment #58
jeroent#55: The check if the user is already created or not is added. If you are on a user edit page, the user is already created and the field type of name is not changed to "value". So on that form, the username will be visible. This is a change because in previous versions of the email_registration module you were not allowed to change the username.
#49: the
drupalLogin()method uses the username and password to log in. When the username is changed, the user will nog longer be able to log in using the username he expects and this will throw an error. So both tests will work.Comment #59
stefanos.petrakis#58: Gotcha, thanks! Then, if I may insist some, the changeset is even smaller, i.e.:
Comment #60
jeroent@stefanos.petrakis,
That will probably work, but imo the check if the user is new or check if a name is already set, will lead to the same behaviour.
Comment #61
stefanos.petrakisFair enough. So, it comes down to these two versions:
(from #44)
or, (from #59):
The two versions are very similar and both solve the problem.
I would mildly argue that the code I propose is easier to understand because it makes explicit the assumption that this is a new user entity with an uninitialized #value for name.
I also find that not performing value settings or other alterations when not dealing with a registration is more consistent with the responsibility zone of the module.
Up to the reviewers, I am fine with both options since they solve the problem. :-)
As far as the tests are concerned, maybe we could merge the extra assertion I added, roughly like this:
Changing the "Version" for this issue as it should be against dev I believe.
N.B.: I think the concern expressed in #42 still deserves some consideration, for the time being, I removed it from the snippet in this comment for clarity.
Comment #62
jeroent@stefanos.petrakis,
Can you make a patch of those changes?
Comment #63
stefanos.petrakisSure, here goes.
Comment #64
joachim commentedLooks good to me.-
Just one point:
Why do we need to log out and back in again after we've made the assertion?
Comment #65
maxplus commentedThanks for the fix, I will test it and give feedback here!
Comment #67
gregglesNow committed. Thanks, everyone for your work on this. I'll likely make a new release shortly to be sure this gets included. Please comment on #3021912: Plan for creating email registration 8.x-1.0 final stable with anything else you'd like to see fixed soon.
Comment #68
gregglesAnd for anyone who needs to cleanup, from @darrenwh in comment #21:
Comment #69
joachim commentedThanks for the update code @darrenwh! My version didn't check for uniqueness and so crashed my server :(
However, the code in #68 doesn't scale for sites with large numbers of users.
Here's my version that runs a batch, with @darrenwh's code for setting the user name added in:
Comment #71
Senthil Kumar Kumaran commentedWhen will the fix be updated in the module?
Comment #72
greggles8.x-1.0-rc7 was released in May https://www.drupal.org/project/email_registration/releases/8.x-1.0-rc7 with this fix in it. Did you upgrade to that? Do you still experience a bug? If so, please open a new issue with the details of that bug.
Comment #73
Senthil Kumar Kumaran commented@greggles,
Thanks for the update. I'm using the latest version https://www.drupal.org/project/email_registration/releases/8.x-1.0-rc7
However, the issue is still not fixed. I had seen the .install file and couldn't find any code related to this.
Updating the DB with patch provided in this issue will resolve my problem. But i want a fix from the module update that will automatically fix and i can make sure my DB is safe.
Please help as this is a long pending issue. Thank you in advance.
Comment #74
gregglesDo you mean the code from comment #69?
Patches welcome. I think ideally it would be an action that could be used with views bulk operations as it seems somewhat generally useful.
Comment #75
andypostFiled follow-up #3081817: Add action to regenerate username /cc @greggles