Steps to reproduce

  • Go to user/register and register an account named 'example'.
  • Go back to user/register and register an account named 'example'.

Expected outcome

Drupal displays an error message, which could be "that user name is already in use".

Actual outcome

[Sun Jun 07 14:08:33.269535 2015] [:error] [pid 27883] [client ::1:60767] Uncaught PHP Exception Drupal\\Core\\Entity\\EntityStorageException: "SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'example-en' for key 'user__name': INSERT INTO {users_field_data} (uid, langcode, preferred_langcode, preferred_admin_langcode, name, pass, mail, timezone, status, created, changed, access, login, init, default_langcode) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11, :db_insert_placeholder_12, :db_insert_placeholder_13, :db_insert_placeholder_14); Array\n(\n    [:db_insert_placeholder_0] => 4\n    [:db_insert_placeholder_1] => en\n    [:db_insert_placeholder_2] => en\n    [:db_insert_placeholder_3] => en\n    [:db_insert_placeholder_4] => example\n    [:db_insert_placeholder_5] => $S$foo\n    [:db_insert_placeholder_6] => example@example.com\n    [:db_insert_placeholder_7] => America/New_York\n    [:db_insert_placeholder_8] => 0\n    [:db_insert_placeholder_9] => 1433700487\n    [:db_insert_placeholder_10] => 1433700487\n    [:db_insert_placeholder_11] => 0\n    [:db_insert_placeholder_12] => 0\n    [:db_insert_placeholder_13] => example@example.com\n    [:db_insert_placeholder_14] => 1\n)\n" at /Library/WebServer/Documents/drupal8x/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php line 930, referer: http://localhost/drupal8x/user/register

Proposed resolution

Handle the exception gracefully.

Remaining tasks

User interface changes

API changes

Beta phase evaluation

Reference: https://www.drupal.org/core/beta-changes
Issue category Bug because a php error is thrown when anonymous users try to register with a username or email address that is already taken. It is caused by an access restriction for anonymous users.
Issue priority Major because there is a PHP error which is only triggered under rare circumstances or which affects only a small percentage of all users.
Prioritized changes The main goal of this issue is fixing a bug which causes a PHP error.
Disruption None.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cilefen’s picture

Title: Unhandled exception when trying to add a duplicate user » Unhandled exception when trying to register a duplicate user
cilefen’s picture

Priority: Normal » Major

According to priority levels of issues, this is "a PHP error which is only triggered under rare circumstances or which affects only a small percentage of all users", so it is major.

dawehner’s picture

Oh, what certainly should happen is some form of validation, which certainly exists, but somehow doesn't work, see core/modules/user/src/Entity/User.php:463

willzyx’s picture

larowlan’s picture

Damn

dawehner’s picture

Working on test coverage ...

dawehner’s picture

Status: Active » Needs review
FileSize
3.48 KB

There we go.

larowlan’s picture

Test looks good, you've left the test > ptest changes in a few places

dawehner’s picture

wrong comment

dawehner’s picture

FileSize
2.55 KB
3.43 KB

So the actual problem is that the anonymous user is not allowed to edit the username

The last submitted patch, 7: 2502021-7.patch, failed testing.

larowlan’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/user/src/UserAccessControlHandler.php
    @@ -81,9 +81,13 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_
    +        // Anonymous users should be able to change their usernamae
    

    %s/usernamae/username - and needs a trailing .

  2. +++ b/core/modules/user/src/UserAccessControlHandler.php
    @@ -81,9 +81,13 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_
    +        if ($account->isAnonymous()) {
    +          return AccessResult::allowed();
    +        }
    

    Is this hunk still needed, shouldn't the first hunk cover the issue? Surely anonymous users shouldn't have access to all operations on the name field?

willzyx’s picture

Status: Needs work » Needs review
FileSize
2.35 KB
981 bytes

as for #12

dawehner’s picture

+++ b/core/modules/user/src/UserAccessControlHandler.php
@@ -81,13 +81,10 @@
-        if ($account->isAnonymous()) {
-          return AccessResult::allowed();
-        }

Right, that was the first way how I tried to solve it ...

EvanSchisler’s picture

Status: Needs review » Needs work

Did some manual testing of patch #13 and it still is throwing the same exception for me. Ran git apply, purged db and re-installed. Followed the steps to re-create exactly as posted.

willzyx’s picture

FileSize
112.16 KB

@EvanSchisler This is what I get running drupal HEAD version and apply patch from #13



cilefen’s picture

Status: Needs work » Needs review

@willzyx I see the same as you.

EvanSchisler’s picture

Sorry guys! I made a mistake and the patch did not apply properly to the UserAccessControlHandler.php file.
I am fairly new to patching.
Re-patched and tested and every showing up the same as @willzyx.

Anonymous’s picture

Issue summary: View changes

Added a beta eval to the summary.

This looks good! Only a minor nitpic:

+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -193,6 +194,24 @@ function testRegistrationDefaultValues() {
+    $account = $this->drupalCreateUser([]);

The first parameter defaults to an empty array, so explicitly setting it is not needed?

cilefen’s picture

Status: Needs review » Needs work
+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -193,6 +194,24 @@ function testRegistrationDefaultValues() {
+   * Ensures that you cannot register with the same name / mail twice.

This function description is unclear. Is it testing the name, the mail (or email), or both?

  1. +++ b/core/modules/user/src/Tests/UserRegistrationTest.php
    @@ -193,6 +194,24 @@ function testRegistrationDefaultValues() {
    +    // Existing username.
    

    This would be better as a sentence or remove it. It is clear from the error message what the code is doing.

  2. +++ b/core/modules/user/src/Tests/UserRegistrationTest.php
    @@ -193,6 +194,24 @@ function testRegistrationDefaultValues() {
    +    // Existing mail address.
    

    The same applies with this.

DuaelFr’s picture

Status: Needs work » Needs review
FileSize
2.34 KB
1.37 KB

I just ran into that issue so I'm glad someone already noticed it.
Here is the updated patch.

Status: Needs review » Needs work

The last submitted patch, 21: interdiff.2502021.13.21.patch, failed testing.

The last submitted patch, 21: registration_exception-2502021-21.patch, failed testing.

The last submitted patch, 21: registration_exception-2502021-21.patch, failed testing.

willzyx’s picture

Status: Needs work » Needs review
Anonymous’s picture

Status: Needs review » Reviewed & tested by the community

Manually tested and confirmed to work.

Steps to reproduce.

go to user/register

create user XXX, with email YYY
create user XXX, with email CCC

with patch this will bring up a situation shown in screenshot at comment #16, without patch it will put you into error page with message "The website encountered an unexpected error. Please try again later."

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Needs a reroll.

The fix is pretty oblique - why is the anonymous user name name changing here?

willzyx’s picture

Status: Needs work » Needs review
FileSize
2.43 KB

rerolled

// Anonymous users should be able to change their username.

Sure, the comment is misleading.. should be something like

// Anonymous users should be able to change their username during the registration process, otherwise the username constraints are not checked.

cilefen’s picture

@alexpott I agree. I don't understand how this code fixes it, but evidently it does.

Anonymous’s picture

Status: Needs review » Needs work

Let's make that comment bit more descriptive

Anonymous’s picture

Status: Needs work » Needs review
FileSize
2.53 KB

added the comment that was suggested in #30

dawehner’s picture

I'm not really convinced by the solution. Why does the \Drupal\user\Plugin\Validation\Constraint\UserNameUnique not trigger here, it really should!

dawehner’s picture

Oh I know, because it is only executed on access, nevermind.

lauriii’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/user/src/Tests/UserRegistrationTest.php
    @@ -265,6 +266,23 @@ function testRegistrationDefaultValues() {
    +   * Tests registration errors when trying to register with an existing user
    

    Function description cannot be multiline

  2. +++ b/core/modules/user/src/Tests/UserRegistrationTest.php
    @@ -265,6 +266,23 @@ function testRegistrationDefaultValues() {
    +    $this->drupalPostForm('user/register', ['mail' => 'test@example.com', 'name' => $account->getUsername()], t('Create new account'));
    ...
    +    $this->drupalPostForm('user/register', ['mail' => $account->getEmail(), 'name' => $this->randomString()], t('Create new account'));
    

    These would be cleaner if they would be put on multiple lines.

  3. +++ b/core/modules/user/src/Tests/UserRegistrationTest.php
    @@ -265,6 +266,23 @@ function testRegistrationDefaultValues() {
    +    $this->assertRaw(Safemarkup::format('The username %value is already taken.', ['%value' => $account->getUsername()]));
    ...
    +    $this->assertRaw(Safemarkup::format('The email address %value is already taken.', ['%value' => $account->getEmail()]));
    

    s/Safemarkup/SafeMarkup

  4. +++ b/core/modules/user/src/UserAccessControlHandler.php
    @@ -81,7 +81,9 @@ protected function checkFieldAccess($operation, FieldDefinitionInterface $field_
    +        // Anonymous users should be able to change their username during the registration process,
    

    This is over 80 characters

Anonymous’s picture

Issue tags: +Novice

tagging with novice as there's a clear what is left to do

Status: Needs work » Needs review
Saphyel’s picture

FileSize
2.87 KB
2.59 KB

Updated with all lauriii's changes

Status: Needs review » Needs work

The last submitted patch, 39: 2502021-39-registration_update.patch, failed testing.

Saphyel’s picture

Status: Needs work » Needs review
FileSize
2.55 KB
2.55 KB
Anonymous’s picture

Status: Needs review » Needs work
+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -265,6 +266,36 @@ function testRegistrationDefaultValues() {
+    $this->assertRaw(Safemarkup::format(
...
+    $this->assertRaw(Safemarkup::format(

Safe_M_arkup, uppercase M

+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -265,6 +266,36 @@ function testRegistrationDefaultValues() {
+   * Tests registration errors when register an existing username or email.

"Tests registration errors when register an existing username or email." => "Tests registration errors when trying to use an existing username or email."

lauriii’s picture

+++ b/core/modules/user/src/Tests/UserRegistrationTest.php
@@ -265,6 +266,36 @@ function testRegistrationDefaultValues() {
+      ['mail' => 'test@example.com', 'name' => $account->getUsername()],
...
+      ['mail' => $account->getEmail(), 'name' => $this->randomString()],

Lets create variable for these like $values = ['mail' => 'test@exmaple.com'] etc. Then we can have these on a single line.

b0unty: Whats the difference between the two strings on #42.2?

Anonymous’s picture

Lol copy paste failed. fixd.

willzyx’s picture

Status: Needs work » Needs review
FileSize
2.84 KB
2.69 KB
lauriii’s picture

Status: Needs review » Reviewed & tested by the community

Looks a lot better.

DuaelFr’s picture

+1 for RTBC
Thank you all for your work on this issue !

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

This issue addresses a major bug and is allowed per https://www.drupal.org/core/beta-changes. Committed a66929c and pushed to 8.0.x. Thanks!

  • alexpott committed a66929c on 8.0.x
    Issue #2502021 by willzyx, Saphyel, dawehner, DuaelFr, b0unty, cilefen,...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.