Database error when new users try to log in

Created on 17 October 2024, 2 months ago

Problem/Motivation

Whenever new users try to log in, the get a database error that start like this:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be null: INSERT INTO "users_field_data"

Our only workaround is to manually add a database row to the "authmap" Drupal table and to manually create a Drupal user at /admin/people/create. After doing these things, the user is able to log in.

Steps to reproduce

I assume this is a problem with our particular configuration/site/backend, because obviously there would be many other people reporting this if not. That's why I classified this issue as a support request. However I don't know how to recreate it easily. I am hoping that this is something the experts on this module may recognize.

FWIW, here are some relevant configuration settings we are using:

Enable custom matching: false
Enable matching on name: false
Enable matching on email: true
Roles allowed for linking: none selected
Create users from SAML data: true
Synchronize user name every login: false
Synchronize email address on every login: false
User name attribute: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
User email attribute: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress

Thank for any guidance!

πŸ’¬ Support request
Status

Active

Version

3.9

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States brockfanning

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

Comments & Activities

  • Issue created by @brockfanning
  • πŸ‡ΊπŸ‡ΈUnited States brockfanning
  • πŸ‡ΊπŸ‡ΈUnited States brockfanning
  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU

    I would like to have the module give a more descriptive error than this, in every case. But from reading the code, I don't see how this happens.

    Since the code is a maze, here's a simplified call tree:

    1) SamlService::acs() calls ExternalAuth::register().

    $unique_id is from the "Unique ID attribute". I don't know what this is in your case, but it is always nonempty at this point, even if the 'name' (from the SAML attribute) would not be.

    2) ExternalAuth::register() does its thing and calls $account->save(). samlauth_user_presave() calls UserSyncEventSubscriber::onUserSync() just before the user is actually saved.

    At this point, $account should have a nonempty name (even if it is bogus - it might contain the unique ID in theory), and it should still be isNew().

    At the end of this function, the name and the email should be overwritten with the value from your user name / email attribute. (getAttributeByConfig() -> setUsername() and setEmail().)

    From just reading the code, I cannot see a path that has emptied out the name and not thrown an error, at the end of this function. This is where to debug / log to watchdog / whatever.

    If the username is still nonempty at the end of UserSyncEventSubscriber::onUserSync(), it's out of our hands. You have e.g. another hook_user/entity_presave that is messing things up.

    (Linking other issue that might have nothing to do with it, just for a personal reminder to re-check this when I get to doing that one.)

  • πŸ‡ΊπŸ‡ΈUnited States brockfanning

    Thank you for the quick response @roderik! That's helpful. We did do a little debugging at this point in the code:

    https://git.drupalcode.org/project/samlauth/-/blob/8.x-3.x/src/SamlServi...

    We confirmed that $account_data['name'] was indeed null/empty at that point.

    So, this points to some hook_user or entity_presave somewhere else in our custom or contrib code, is that right?

  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU

    No, this points to

    1) your "User name attribute" configuration being incorrect (or your SAML data disappearing, but I don't think so). Because $this->getAttributeByConfig('user_name_attribute') should be getting the value from the attribute named "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", but apparently that does not exist or is empty.

    (If needed, you can turn on some debugging in configuration - User - SAML authentication - SAML , to get your full IDP response including the attriubutes logged to watchdog.)

    2) UserSyncEventSubscriber::onUserSync() not doing its job of giving you a proper error message.

    (From reading the code, I was expecting the email to be empty and this being turned into an exception - because you're using the same attribute for name and email. I'll doublecheck this sometime when I address the linked issue - I should really make automated tests for this code.)

  • πŸ‡³πŸ‡±Netherlands roderik Amsterdam,NL / Budapest,HU

    @brockfanning I am mixing things up. For completeness: in my reasoning, things are going on:

    1) I was expecting the account name not to be empty at the start of UserSyncEventSubscriber::onUserSync() , but filled with the $unique_id. So I still don't know where your database error about a NULL name is coming from.

    Maybe the cause of this is some other hook, or maybe I am just not reading ExternalAuth code right.

    But that's not of direct interest to you, at first.

    2) The first interesting thing for you is that $account_data['name'] is empty at that earlier point, and that warrants checking, per my previous comment.

Production build 0.71.5 2024