Disallow the programmatic assignment of insider/outsider roles to members

Created on 11 October 2024, 4 months ago

Problem/Motivation

Assigning outsider/insider roles to a member is not possible via the UI, but we do not prevent it via code. This can lead to unstable websites where our access policies choke on the unexpected presence of these roles.

We fixed one part of the ordeal here: 🐛 An already assigned individual role can be made out/insider, leading to a crash in the permission calculation Needs review
This issue is about fixing the other part.

Steps to reproduce

Assign an outsider role via code, see your site crash.

Proposed resolution

Do not allow the above.

📌 Task
Status

Active

Version

3.3

Component

Code

Created by

🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

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

Merge Requests

Comments & Activities

  • Issue created by @kristiaanvandeneynde
  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

    Need to update the footer of this CR once this is fixed: https://www.drupal.org/node/3480111

  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

    I'm hoping tests will go green now. Need to add a CR about memberships now validating role scope. The fact that the other two checks got moved to the same constraint doesn't need a CR because we were already throwing an exception from those checks.

  • Pipeline finished with Skipped
    3 months ago
    #313388
  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium
  • Automatically closed - issue fixed for 2 weeks with no activity.

  • 🇦🇹Austria mvonfrie

    I stumbled upon this issue when executing a migration from a Drupal 7 site with organic groups which I implemented several months ago and the new site is almost ready for production now. I changed my plugin to filter out all non-individual roles from the mapping and that works. But I observe a strange behavior related to this and would like to ask if that is intended or not.

    The Drupal 7 site has an og level "Author" role, which now is a global "Author" role with outsider and insider mappings for the group type. Users, organic groups and almost all contents get migrated from Drupal 7, except migrating the og-level roles to corresponding global roles. The admins have to do this manually. After running the migration I have the following in Drupal 10:

    • User A created
    • Group B created, Insider "Author" role bound to the global "Author" role is defined.
    • Membership of user A in group B created

    Now when I assign the global "Author" role to user A, I nowhere see that it also got the "Author (insider)" role in group B implicitely assigned. Neither in the group members view, nor as read-only information in the group membership edit form. How can I check whether the outsider/insider scoped group roles actually are assigned?

  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

    How can I check whether the outsider/insider scoped group roles actually are assigned?

    They aren't assigned, their permissions are by virtue of an access policy: SynchronizedGroupPermissionCalculator

  • 🇦🇹Austria mvonfrie

    Thanks, that seems to work. At least when debugging the SynchronizedGroupPermissionCalculator the calculated permissions look correct.

    But still, the information about the implicit (outsider, insider, inherited) roles is missing. I will create a follow-up issue as feature request.

  • 🇳🇱Netherlands kingdutch

    There's a slight "API change" this causes that may trip some people up (which I don't think is worth fixing, but I want to share it because it may save people some debugging time).

    In previous versions of group it was 'valid' to call $group->addMember($user, ['group_roles' => '']) where group_roles was an empty string. Because of how Drupal treated fields this would just be seen as an empty value and otherwise ignored in code.

    Now that the validation exists, the group module will try to load a route with an empty ID which can never exist, thus throwing a validation error. This means that you code should check that you're actually assigning a role and that you didn't receive empty user input. If you're not assigning a role you should unset the group_roles entry of the membership data.

    (This scenario occurred for us in test code where scaffold data was being parsed from markdown tables into arrays. Empty fields in this system are interpreted as empty strings.)

  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

    Good catch, but I agree that this is not worth fixing. I'm sure if you pass it an empty array, the code will work fine. So it's really down to the question: Why are you passing a string where an array is expected? :)

Production build 0.71.5 2024