Problem/Motivation
Since 9.5.4 (and i think #3039499: Role permissions not sorted in config export), when i save the admin/people/permissions form (while adding or removing a permission) and export configuration, i see key index on permission export.
To take the example of the related issue, here is now the result :
diff --git a/config-sync/user.role.toggle_all.yml b/config-sync/user.role.toggle_all.yml
index 0ce46a0..35ac270 100644
--- a/config-sync/user.role.toggle_all.yml
+++ b/config-sync/user.role.toggle_all.yml
@@ -7,11 +7,10 @@ label: 'Toggle all'
weight: -2
is_admin: null
permissions:
- - 'abstractpermissions:role_toggle:toggle_all'
- - 'access administration pages'
- - 'access toolbar'
- - 'role_toggle:administrator'
- - 'role_toggle:debugger'
- - 'role_toggle:design_manager'
- - 'role_toggle:site_manager'
- - 'role_toggle:translation_manager'
+ 0: 'abstractpermissions:role_toggle:toggle_all'
+ 1: 'access administration pages'
+ 2: 'access toolbar'
+ 3: 'role_toggle:debugger'
+ 4: 'role_toggle:design_manager'
+ 5: 'role_toggle:site_manager'
+ 6: 'role_toggle:translation_manager'
Index should not appear in the export, only permissions, sorted by their name.
Steps to reproduce
- Submit changes in role permissions.
- Export the configuration
- Permissions in configuration file show index
See #13
Comments
Comment #2
goz commentedComment #3
goz commentedSetting back the following code solve the issue :
\Drupal\user\Entity\Role::preSave:
Still needs to see why it has been removed. Seems something doesn't work as expected after #3039499: Role permissions not sorted in config export changes.
Comment #4
goz commentedFound this similar issue for 10.x to
#3341431: user_update_10000 causes exported permissions to be numerically keyed
Comment #5
goz commentedMove it to critical since it will regenerate all permissions roles files of existing projects, and will need a rollback.
Comment #6
goz commentedAfter updating another project from 9.5.3 to 9.5.4, i don't reproduce the issue.
Really strange
Comment #7
goz commentedForget about this, i restart from previous dump, run the update again and cannot reproduce
Comment #8
goz commentedI finally reproduce again.
This will occurs only if you remove a permission from a role (and then export configuration with drush).
Comment #9
goz commentedMay be there is a better solution, but set the code from Role::preSave back solve it right now.
Let see later why schema update from #3039499: Role permissions not sorted in config export does not solve this as expected.
Comment #10
smustgrave commentedTried replicating and was not able to.
Exported permissions
Removed a permission from a role
Exported again.
not seeing any issues.
Think this can be lowered to Normal.
As a bug will also need a test case to show the isuse.
Comment #11
larowlanI don't think this meets the requirements for a critical, can you elaborate on why you feel it is, it doesn't seem to cause data loss
Comment #12
acbramley commentedThe IS states"revoke a permission". Does that mean via the action? I can see how that may lead to unsorted permissions depending on how that action plugin works. I would be surprised if it did though since saving a Role entity should trigger the sort that was added in https://www.drupal.org/project/drupal/issues/3039499
Comment #13
goz commentedI reproduce in both contexts : after updating from 9.5.3 to 9.5.4, and after installation to 9.5.4 with existing config.
Steps to reproduce :
- Have an installed drupal at 9.5.3
- Be sure configuration is up to date :
drush cex -y- Update to 9.5.4 :
Permissions in user.role.authenticated.yml is :
- I commit this in git to see differences when i'll remove the permission and export again.
- Remove 'edit own comments' from /admin/people/permissions
- Export config :
drush cex -y- git diff on user.role.authenticated.yml is now :
Comment #14
acbramley commented@GoZ a normal upgrade path would have a cache clear in there. Did you clear cache before or after the
drush updb? Because without that, the schema change from #3039499: Role permissions not sorted in config export would not be in effect.Comment #15
acbramley commentedConfirmed steps in #13 trigger the issue even with a cache clear.
Even worse - after adding a new permission it's tacked on to the end, i.e there's no sorting at all.
I've tracked this down to the fact that
user_role_grant_permissionsanduser_role_revoke_permissionscalltrustData.Setting trustedData = TRUE skips casting in validation
Config::castValue is where sorting is applied.
UserPermissionsForm::submitForm calls user_role_change_permissions which uses the 2 functions mentioned above.
This can be reproduced on 10.1.x, no need to upgrade or anything just simply save the permissions form.
Comment #17
acbramley commentedPushed a fix to the MR, keen to see what fails before working on dedicated tests. Hiding the patch as well.
Comment #18
acbramley commentedI couldn't find any existing tests for the permissions form so I've added a new class (searched all tests for admin/people/permissions or user.admin_permissions).
This test is very simple and correctly fails when reverting either of the changes in the first commit:
Add fail:
Remove fail:
Comment #19
acbramley commentedChecked core for usages of
user_role_change_permissions,user_role_grant_permissions, anduser_role_revoke_permissionsand almost all usages are in tests, except this permissions form and inFilterFormat::postSave. I can't find any test coverage for the FilterFormat permissions.Comment #20
acbramley commentedComment #21
larowlanPatch looks simple enough, and has a test.
The ::trustData call was added in #2432791: Skip Config::save schema validation of config data for trusted data in comment 57 it seems.
Will ping @alexpott about this given he worked on both that patch and the sorting one.
Comment #23
alexpottI've tweaked the fix to do a partial revert of #3039499: Role permissions not sorted in config export so that the behaviour from before that is maintained. This ensures that the actions also still work as before. I think this is analogous to the existing code for dependencies in ConfigEntityBase...
Comment #24
alexpottIf you update from 10.0.0 to this MR you'll see
Comment #25
alexpottMy changes are now too extensive to leave at RTBC...
Comment #26
bircherThis looks good!
Checking for
$this->hasTrustedData()and doing the sorting here is ok. But long term we should make sure to avoid the trusting of data except in the install phase. And there we could do a sorting/casting after the installation. But this would need lots of other work with sorting etc and is clearly out of scope here.So I RTBC this again.
Comment #27
alexpottI've opened an issue to deprecate the trusted data concept - see #3347842: Deprecate the trusted data concept in configuration
Comment #28
alexpottThis will need to be backported to 9.5.x
Comment #29
catchI asked @alexpott about a follow-up to deprecate user_role_grant_permissions(), turns out we have a ten year old issue #2025089: Deprecate user_role_grant_permissions() and user_role_revoke_permissions() already.
Committed/pushed to 10.1.x and cherry-picked to 10.0.x. This needs a re-roll for 9.5.x
Comment #32
catchDiff applies to 9.5.x even though the cherry-pick doesn't, so committed/pushed there too.
Comment #34
acbramley commentedThanks for the quick turn around! @alexpott just curious why we went with that solution rather than removing the trustData call?
Comment #35
alexpott@acbramley because it is not just these methods. Anywhere that called trustData() on a role would no longer be sorted. I broke that with #3039499: Role permissions not sorted in config export when I shouldn't have.
Comment #36
goz commentedThanks all, that was fast !