Roles being stripped from users when saved if user has no access to roles field

Created on 9 June 2022, almost 3 years ago
Updated 8 November 2023, over 1 year ago

Problem/Motivation

When a user who has access to edit roles with role delegation edits a user on a form, where the roles field is disabled (not displayed), then on save it will strip all the roles from the user account.

Note this issue has a different root problem than https://www.drupal.org/project/role_delegation/issues/3263782 πŸ› Roles being stripped from users when saved Closed: duplicate .

Steps to reproduce

1. Create a role where you allow to assign roles with the role delegation module.
2. Create/assign the previously created role to a user.
3. Remove from the default display form mode the "User name and password" field which should remove the user, password and role fields from the user edit form OR in hook field access give access false to the ['account']['roles'] field.
4. Login with the user from point 2. Edit your own profile and save it.
5. Now you are only a simple user, without any roles. (except authenticated)

Proposed resolution

As looking at the code there are many different ways to handle this. Either by allowing the roles_change to be configured on the display form mode so the admin can disable it from that place, or automatically handle when the original role field is not accessible, either by setting the correct default value after form submits or somewhere else to skip the saving process.

Remaining tasks

-
- test
- review
- commit

User interface changes

None

API changes

None

Data model changes

None

πŸ› Bug report
Status

Needs review

Version

1.0

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium golddragon007

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

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡§πŸ‡ͺBelgium keszthelyi Brussels

    Patch from MR at commit 7cdc8c1d

  • πŸ‡¨πŸ‡¦Canada Liam Morland Ontario, CA πŸ‡¨πŸ‡¦

    Liam Morland β†’ made their first commit to this issue’s fork.

  • Pipeline finished with Failed
    over 1 year ago
    Total: 155s
    #65917
  • Status changed to RTBC over 1 year ago
  • πŸ‡¨πŸ‡¦Canada Liam Morland Ontario, CA πŸ‡¨πŸ‡¦

    Updated the merge request.

    Patch works for me.

  • πŸ‡¬πŸ‡§United Kingdom scott_euser

    Confirming RTBC here.

    To note there were also efforts in πŸ› Roles being stripped from users when saved Closed: duplicate but closed it as a duplicate as this one seems to jump in earlier in where things go wrong compared to in the final presave, but maintainers may find it useful to know there are also 11 followers there,

  • πŸ‡¬πŸ‡§United Kingdom scott_euser

    Hiding patch

  • First commit to issue fork.
  • Status changed to Needs work 7 months ago
  • πŸ‡§πŸ‡ͺBelgium JeroenT πŸ‡§πŸ‡ͺ

    Tests are failing.

  • First commit to issue fork.
  • πŸ‡¦πŸ‡ΊAustralia acbramley

    I was able to reproduce via the steps in the IS and got some test coverage going for this bug. Obviously the fix still isn't working (since it's breaking existing tests) but this'll give us something to test against (TDD :))

  • @acbramley i might be misunderstanding but the following section of code in the .module file:

    <?php
    function role_delegation_user_form_builder(string $entity_type, UserInterface $user, array &$form, FormStateInterface $form_state) {
      // If the user has no access to the "role_change" or "role" field, then the
      // form will submit an empty array for the field, which will make later
      // processing think it was intentional. Set it to the empty field value to
      // correct this.
      if (!isset($form['role_change']['#access'], $form['account']['roles']['#access']) || !$form['role_change']['#access']  ||  !$form['account']['roles']['#access']) {
        $user->set('role_change', DelegatableRoles::$emptyFieldValue);
      }
    }
    ?>

    If i am reading the text right it says that the user needs access to either the role_change field or the account roles field. However with the above code you would need access to both field for it to not submit an empty value. I believe the code should be:

    <?php
    function role_delegation_user_form_builder(string $entity_type, UserInterface $user, array &$form, FormStateInterface $form_state) {
      // If the user has no access to the "role_change" or "role" field, then the
      // form will submit an empty array for the field, which will make later
      // processing think it was intentional. Set it to the empty field value to
      // correct this.
      if (!isset($form['role_change']['#access'], $form['account']['roles']['#access']) || (!$form['role_change']['#access'] && !$form['account']['roles']['#access'])) {
        $user->set('role_change', DelegatableRoles::$emptyFieldValue);
      }
    }
    ?>
Production build 0.71.5 2024