User role cleared after log in

Created on 6 January 2025, 15 days ago

Problem/Motivation

After recently upgraded from 1.x to 3.0, our site seems to remove a user's custom Drupal roles after they log in with the OpenID Connect button.

Steps to reproduce

- Upgrade the module from 1.x to 3.0-alpha
- Log in using the OIDC button
- Notice user's custom roles removed. Only "Authenticated" role remain.

We are running Drupal 10.3.10 on PHP 8.3.14.
Before that, the website runs on 10.3.1 on PHP 8.1.

🐛 Bug report
Status

Active

Version

3.0

Component

Code

Created by

🇯🇵Japan hktang

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

Merge Requests

Comments & Activities

  • Issue created by @hktang
  • 🇺🇸United States pfrilling Minster, OH

    This sounds like a similar issue as #3487116, which should have corrected this.

    - What OpenID Client are you using?
    - Can you provide the plugin's configuration before and after the upgrade (obfuscating the sensitive parts)?

  • 🇺🇸United States dcam

    Did you run the database updates after updating to alpha5?

  • 🇮🇳India gokul.jayan

    I encountered the same problem, and re-saving the OpenID Connect settings resolved it for me.

  • 🇯🇵Japan hktang

    @pfrilling
    Below is the config in question. It seems to stay the same after upgrading from alpha3 to alpha4.

    @dcam
    I did run drush deploy after upgrading so I assume database update was successful.

    @gokul.jayan
    I tried creating a new Google profile with the same configuration. But it still wipes away my user roles after switching to that profile (on alpha4).

    uuid: 0aax...cae
    langcode: en
    status: true
    dependencies: {  }
    id: webmail
    label: 'Webmail'
    plugin: google
    settings:
      client_id: 5032...o1.apps.googleusercontent.com
      client_secret: GOC....ZFd
      iss_allowed_domains: "xxx.or.jp\r\nddev.site\r\npantheonsite.io"
    
  • 🇯🇵Japan hktang

    Perhaps this is the culprit? If we don't have any mappings, we should skip role syncing, right?

       $role_mappings = $this->configFactory->get('openid_connect.settings')->get('role_mappings') ?? [];
       $user_groups = $userinfo['groups'] ?? [];
       foreach ($role_mappings as $role => $mappings) {
         if (empty(array_intersect($mappings, $user_groups))) {
           // User doesn't have a mapped role. Remove it from their account.
           $account->removeRole($role);
         }
         else {
           // User has a mapped role. Add it to their account.
           $account->addRole($role);
    
  • 🇺🇸United States dcam

    alpha5 has the fix for this issue.

  • 🇯🇵Japan hktang

    Hi @dcam, I tried upgrading from alpha4 to alpha5 and still have the same issue.

  • 🇮🇳India gokul.jayan

    Update to alpha5, and there are configuration changes for the module settings that needs to be exported. After the export the configuration looks something like this.

    _core:
      default_config_hash: NFnOZU6VCOfURCAR4-O3V7eMHTx2LNqnCmDKRSNjjns
    always_save_userinfo: true
    connect_existing_users: true
    override_registration_settings: false
    end_session_enabled: true
    user_login_display: above
    redirect_login: /user
    redirect_logout: /
    userinfo_mappings: {  }
    role_mappings: {  }
     
  • 🇮🇳India gokul.jayan

    gokul.jayan changed the visibility of the branch 3497559-user-role-cleared to hidden.

  • 🇺🇸United States dcam

    I did run drush deploy after upgrading so I assume database update was successful.

    I'd need to know more about your deployment workflow. Did you update the module on a dev environment, update the database (without using drush deploy), export the configuration, commit the configuration, push your changes to production, install the update, and then run drush deploy?

  • 🇯🇵Japan hktang

    Hi @dcam:

    I was performing a minor Drupal upgrade alongside other module upgrades .

    1. On dev environment, composer require the latest 3.0.0-alpha version of OIDC. (from alpha3 to alpha4 at the time of upgrading).
    2. Push changes to dev/test/live, without any changes made to OIDC settings. I cannot remember if I did a config export.. but both the module setting and the google plugin setting remained the same, i.e. as copied above.
    3. Drush cr and drush deploy was run when deployed, so any database update should have run already.

    Hope this helps!

  • 🇯🇵Japan hktang

    Hi @gokul.jayan,

    I don't know why but my role mapping has empty items with my Drupal site roles. (see #7).
    I added a quick fix but hopefully that doesn't break other functionalities.

  • 🇯🇵Japan hktang

    hktang changed the visibility of the branch 3497559-user-role-cleared to active.

  • 🇯🇵Japan hktang

    hktang changed the visibility of the branch 3497559-user-role-cleared to hidden.

  • Pipeline finished with Failed
    14 days ago
    Total: 248s
    #388038
  • 🇺🇸United States dcam

    I asked about the workflow because drush deploy runs database updates and then imports your configuration. If a person did that on an environment without following a strict procedure for configuration management, then their database would be updated and then immediately overwritten with the old configuration. That would result in no changes being apparent.

    In any case, if the database updates were run but your configuration remains in a broken state, then it's probably going to need to be manually repaired at this point. @gokul.jayan gave the solution. The role_mappings key needs to be reduced to an empty array, role_mappings: { }. Personally, I would just edit the config file to do it and then import the configuration.

  • 🇮🇳India gokul.jayan

    Hi @hktang
    I also encountered the same problem with alpha5. In my case, when I resaved the module settings, there were changes to the role mappings—specifically, the removal of all role mappings and their replacement with only the role_mapping key containing an empty array. I believe resaving the module settings should resolve the issue.

  • 🇺🇸United States dcam

    Yeah. That should work too.

  • 🇯🇵Japan hktang

    Hi @dcam and @gokul.jayan, thank you for your feedback!

    I tried renaming the database upgrade script and quickly rerun it as 30003.

    Then I did a config export just to make sure the role_mappings is emptied.

    Still, it seems the upgrade script didn't empty the role_mappings config item as expected. My config stays the same as #7.

    Here's the log for drush deploy and drush cex -y.

    ddev drush deploy
     [notice] Database updates start.
     ---------------- ----------- --------------- ------------------------------------------------------------ 
      Module           Update ID   Type            Description                                                 
     ---------------- ----------- --------------- ------------------------------------------------------------ 
      openid_connect   30003       hook_update_n   30003 - Clean-up role_mappings in openid_connect.settings.  
     ---------------- ----------- --------------- ------------------------------------------------------------ 
    
    
     Do you wish to run the specified pending updates? (yes/no) [yes]:
     > >  [notice] Module twig_xdebug has an entry in the system.schema key/value storage, but is not installed. <a href="https://www.drupal.org/node/3137656">More information about this error</a>.
    >  [notice] Module workflow_buttons has an entry in the system.schema key/value storage, but is missing from your site. <a href="https://www.drupal.org/node/3137656">More information about this error</a>.
    > >  [notice] Update started: openid_connect_update_30003
    > >  [notice] Update completed: openid_connect_update_30003
    >  [success] Finished performing updates.
     [success] Config import start.
    +------------+-------------------------+-----------+
    | Collection | Config                  | Operation |
    +------------+-------------------------+-----------+
    |            | openid_connect.settings | Update    |
    +------------+-------------------------+-----------+
    
     Import the listed configuration changes? (yes/no) [yes]:
     > >  [notice] Synchronized configuration: update openid_connect.settings.
    >  [notice] Finalizing configuration synchronization.
    >  [success] The configuration was imported successfully.
     [success] Cache rebuild start.
    >  [success] Cache rebuild complete.
     [success] Deploy hook start.
    >  [success] No pending deploy hooks.
    ❯ ddev drush cr
     [success] Cache rebuild complete.
    ❯ ddev drush cex
     [notice] The active configuration is identical to the configuration in the export directory (/var/www/html/config/sync).
    /var/www/html/config/sync
  • 🇯🇵Japan hktang

    Also, I agree with you that we should follow deployment best practices.

    Manually updating the config yaml file might have the risk of it being overwritten by other processes. Wouldn't it be better if we just have a simple check and skip the dangerous role removal, as suggested in the merge request?

  • 🇯🇵Japan hktang

    Hi guys, I also confirm the update script runs correctly but drush still thinks there's no difference.

    This is the config right after running the update script.

    Array
     (
         [_core] => Array
             (
                 [default_config_hash] => NFnOZU...SNjjns
             )
     
         [always_save_userinfo] => 1
         [connect_existing_users] => 1
         [override_registration_settings] => 
         [end_session_enabled] => 1
         [user_login_display] => above
         [redirect_login] => /user
         [redirect_logout] => /
         [userinfo_mappings] => Array
             (
             )
     
         [role_mappings] => Array
             (
             )
     
     )
    

    But my config, after running drush cex, is still the same as #7. i.e. different content, but considered same by Drush.

  • 🇮🇳India gokul.jayan

    Hi @hktang
    During the Drush deployment process, changes were made to the openid_connect.settings, and the new changes were overridden. Try resaving the module settings and then run drush cex.

  • 🇯🇵Japan hktang

    Hi there, I finally confirmed what happened. It's caused by my deployment script which uses "drush deploy".

    According to documentation, drush deploy imports existing config immediately after running database update. It's a combination of:

    drush updatedb --no-cache-clear
    drush cache:rebuild
    drush config:import
    drush cache:rebuild
    drush deploy:hook

    This sequence of actions effectively ignores the $config-save() action made by the update script added via https://www.drupal.org/node/3487116 . When I do `drush cex` after deployment, I am actually exporting the old configuration instead of the new one.

    I wonder if drush deploy is the standard deploy action?

Production build 0.71.5 2024