Grants form deletes other modules' grants

Created on 1 September 2023, over 1 year ago

Problem/Motivation

Submitting the Grants form deletes all permissions that come from other modules (or from Drupal core), replacing them with only the ones from this module.

Steps to reproduce

Suppose a published node has the following entries in the core node_access table of the database, where "nonprofit" is the node type and 117 is the user ID of the node author:

MariaDB [main]> select * from node_access where nid=1150;
+------+----------+----------+-----+----------------------------+------------+--------------+--------------+
| nid  | langcode | fallback | gid | realm                      | grant_view | grant_update | grant_delete |
+------+----------+----------+-----+----------------------------+------------+--------------+--------------+
| 1150 | en       |        1 |   0 | edit any nonprofit content |          0 |            1 |            0 |
| 1150 | en       |        1 | 117 | edit own nonprofit content |          0 |            1 |            0 |
+------+----------+----------+-----+----------------------------+------------+--------------+--------------+
2 rows in set (0.001 sec)

After using the Grants form to give user 23 editing permission, the nodeaccess table (i.e. for this module) looks like this, as it should:

MariaDB [main]> select * from nodeaccess where nid=1150;
+------+-----+----------------+------------+--------------+--------------+
| nid  | gid | realm          | grant_view | grant_update | grant_delete |
+------+-----+----------------+------------+--------------+--------------+
| 1150 |  23 | nodeaccess_uid |          1 |            1 |            0 |
+------+-----+----------------+------------+--------------+--------------+
1 row in set (0.001 sec)

but the node_access table (core) now looks like this:

MariaDB [main]> select * from node_access where nid=1150;
+------+----------+----------+-----+----------------+------------+--------------+--------------+
| nid  | langcode | fallback | gid | realm          | grant_view | grant_update | grant_delete |
+------+----------+----------+-----+----------------+------------+--------------+--------------+
| 1150 | en       |        1 |  23 | nodeaccess_uid |          0 |            1 |            0 |
+------+----------+----------+-----+----------------+------------+--------------+--------------+
1 rows in set (0.003 sec)

when it should look like this:

MariaDB [main]> select * from node_access where nid=1150;
+------+----------+----------+-----+----------------------------+------------+--------------+--------------+
| nid  | langcode | fallback | gid | realm                      | grant_view | grant_update | grant_delete |
+------+----------+----------+-----+----------------------------+------------+--------------+--------------+
| 1150 | en       |        1 |   0 | edit any nonprofit content |          0 |            1 |            0 |
| 1150 | en       |        1 | 117 | edit own nonprofit content |          0 |            1 |            0 |
| 1150 | en       |        1 |  23 | nodeaccess_uid             |          0 |            1 |            0 |
+------+----------+----------+-----+----------------------------+------------+--------------+--------------+
3 rows in set (0.003 sec)

Proposed resolution

In line 423 of GrantsForm, the line

    \Drupal::entityTypeManager()->getAccessControlHandler('node')->acquireGrants($node);

is called without capturing the returned value. The subsequent line therefore does not have the acquired grants and cannot retain them. Do this instead:

    $drupal_grants = \Drupal::entityTypeManager()->getAccessControlHandler('node')->acquireGrants($node);
    \Drupal::service('node.grant_storage')->write($node, $drupal_grants);

Remaining tasks

Make a fork.

πŸ› Bug report
Status

Needs review

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States BenStallings

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

Comments & Activities

Production build 0.71.5 2024