Problem/Motivation
I ran into some issues with the version 8.x-4.x in context with the "Drupal Account Provisioning Events" settings.
Situation:
- Drupal 9.0.9
- drupal/ldap dev-4.x
- No checkbox selected at "Drupal Account Provisioning Events"
- LDAP Query configured. Test of query works successfully
- If I run the ldap_user_cron() then the users are updated correctly
Issue 1
At "Drupal Account Provisioning Events" I check "Create or Sync to Drupal user on successful authentication with LDAP credentials" and run the cron again. I get the error Integrity constraint violation: 1062 Duplicate entry 'XXXXXX' for key 'user__name'
This occurrs, because GroupUserUpdateProcessor::runQuery() calls the method drupalUserLogsIn(), which then calls syncToDrupalAccount(), because of this Drupal account provisioning setting.
Issue 2
I get the same "duplicate entry" error, if I check the other checkbox "Create or Sync to Drupal user anytime a Drupal user account is created or updated."
In this case, saving the user causes the ldap_user_user_presave() hook to be called. Which calls drupalUserUpdate() and this again leads into calling syncToDrupalAccount(). Therefore, we run into the same issue.
In this case it also effects the user handling in other places. For instance, I can reproduce the error with this:
$users = $this->entityTypeManager->getStorage('user')->loadMultiple([10, 11]);
foreach ($users as $user) {
$user->save();
}
If I check the logs afterwards, the error occurs while saving the second user.
Example:
- User 10, username "foo"
- User 11, username "bar"
User 10 updated successfully. While saving user 11, the error appears with the username of user 10, but with uid of user 11.
Duplicate entry 'foo' for key 'user__name' ...... [uid_placeholder] => 11
Comments
Comment #2
marco-sI can also reproduce it with the hogwarts demo.
hpotter (uid 6)
hgranger (uid 7)
Integrity constraint violation: 1062 Duplicate entry 'hpotter-en' for key 'user__name': INSERT INTO {users_field_data} (uid, langcode, .... Array ( [:db_insert_placeholder_0] => 7 [:db_insert_placeholder_1] => enI stepped a little deeper into the process and found out that via
doSave()inSqlContentEntityStorage::mapToStorageRecord()the user entity of the second user (hgranger) has the correct values, but$entity->get('name')->valuereturns the wrong value (hpotter instead of hgranger). Could also be a Drupal related issue? I will analyse this in more detail soon if possible.Comment #3
grahlI believe I've fixed this in another issue, unfortunately the DrupalUserProcessor wasn't being reset in the cron runs.
Please let me know if you can still reproduce this on latest dev.
Comment #4
fred r commentedThank you @grahl.
The last dev version fix that bug for me.
Before update : each cron give this error :
Integrity constraint violation: 1062 Duplicate entryAfter update :
i've deteled all users.
Run cron --> all users created
Run cron --> no error
Comment #6
marco-sI agree. The latest dev version has solved most of the issues.
Unfortunately, I can still reproduce issue 2, if I have "Create or Sync to Drupal user anytime a Drupal user account is created or updated" selected and save multiple users in a row somewhere in the code.
This breaks user updates in other modules.
Comment #7
marco-sThe reason for the issue is the assignment of the user's name in
DrupalUserProcessor::setLdapBaseFields().Comment #8
grahl@Marco you're probably running into the same issue as here: #3196170: Unexpected behavior in ldap_user_user_presave on processing multiple users per request
Comment #9
marco-s@Hendrik, thank you for the link.
Drupal::service('ldap.drupal_user_processor')->reset()indeed solves that issue! :)