Problem/Motivation

Wherever possible, Drupal 8 code should deprecate instead of removing old code, behaviors, etc.

Permission machine names are stored in user role configurations, but they are also used in code for many things like access checks. This means that if core updates the machine name of a permission, even if it provides an upgrade path, contributed module code that checks against the core permissions might start to deny access that should be allowed.

Marked major because it affects how thoroughly we can implement our backwards compatibility policy.

Proposed resolution

Provide a mechanism to deprecate permissions in the permission definition.

Remaining tasks

  • Needs review.
  • Followup to explore how to raise warnings when a deprecated permission is used.

User interface changes

If no deprecated permissions are used, there is no UI change: unused deprecated permissions are simply not presented to the user.

If a deprecated permission is in use, the user will see a short message under the permission. The permission can be revoked from roles that have it through the UI, but not granted to additional roles (unchecked checkboxes for it will be disabled).

Displays permission form with new warning for deprecated permission.

A message will also be provided on the status report.

Shows the warning about deprecated permissions in the status report.

API changes

A deprecated key is added to the permission definition API.

Data model changes

Issue fork drupal-2924785

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

xjm created an issue. See original summary.

xjm’s picture

Status: Active » Needs review
Issue tags: +Needs tests
StatusFileSize
new2.51 KB

I'm thinking something like the attached.

I started to look at adding unit tests in core/modules/user/tests/src/Unit/PermissionHandlerTest.php, but then backed away slowly because that test does very un-unit-testlike things (file_put_contents() of test permissions, etc...)

xjm’s picture

Status: Needs review » Needs work

For tests.

dawehner’s picture

  1. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -123,7 +123,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    -    $permissions = $this->permissionHandler->getPermissions();
    +    $permissions = $this->permissionHandler->getUndeprecatedPermissions();
    

    Couldn't this cause security issues by people not seeing that a certain role has a certain permission. Maybe we should show it, but not make it possible to grant a role the permission?

  2. +++ b/core/modules/user/src/PermissionHandler.php
    @@ -110,6 +110,18 @@ public function getPermissions() {
    +      if (!empty($permission['deprecated'])) {
    +        return FALSE;
    +      }
    +      return TRUE;
    

    🙃 These 4 lines could be collapsed to return empty($permission['deprecated'])

xjm’s picture

Couldn't this cause security issues by people not seeing that a certain role has a certain permission. Maybe we should show it, but not make it possible to grant a role the permission?

Ah yes. That's partly why I added the text about update hooks, but it's better to harden it against that. So we could show the checkbox if any role has the permission, disable the checkbox for any roles that don't have the permission, and display a message in the same place we add the restricted access message: "This permission should no longer be used".

🙃 These 4 lines could be collapsed to return empty($permission['deprecated'])

derp yes. Booleans for our booleans!

xjm’s picture

Status: Needs work » Needs review
StatusFileSize
new6.56 KB

Attached does that. It includes a test fixture, but still no actual test.

sam152’s picture

Based on #1977498: Add version tracking for configuration schema and data, permissions can't be renamed, even with an upgrade path right? Any exported role that contained such a permission in a module or elsewhere would be invalid.

I wonder if a follow-up for this could be a "replaced_by" key on deprecated permissions, so contrib modules which check the legacy permission could have the access check replaced by a lookup on the new permission automagically.

dawehner’s picture

Currently the runtime permission system is fully decoupled from hook_permissions, for example because of performance reasons. Maybe one thing we could do to keep this constraint alive is to update permissions automatically on role save.

phenaproxima’s picture

Status: Needs review » Needs work
Issue tags: +Needs change record

Patch looks good to me -- nice idea! Sending back to NW for tests, though :)

xjm’s picture

Regarding updating permissions on save, this is something we try to avoid because it adds noise to config diffs.

We don't really guarantee that config exports will always work. We've had lots of upgrade paths that re-save config, generally accompanied by change records if key names/structure/etc. are changing. All those upgrades probably made old exports invalid.

I'm not sure about a replaced_by key or whatever, because permissions will not always have a 1:1 replacement. E.g. in #2862422: Add per-media type creation permissions for media one permission is replaced by many permissions.

I was thinking that it would be up to the provider to maintain BC for the deprecated permission (and to add a @trigger_error() for the deprecated permission in the relevant code paths) since only the module knows how the permission should be used. That's why the patch just hides them from the permissions UI.

xjm’s picture

Status: Needs work » Needs review
StatusFileSize
new6.99 KB
new12.21 KB

Now with a test. This is also adding a test class that can eventually also test things from the very-un-unit-testlike PermissionHandlerTest.

xjm’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/user/tests/src/Functional/PermissionsPageTest.php
    @@ -0,0 +1,127 @@
    +class PermissionsPageTest extends BrowserTestBase {
    

    PermissionFormTest would probably be a better name.

  2. +++ b/core/modules/user/tests/src/Functional/PermissionsPageTest.php
    @@ -0,0 +1,127 @@
    +   * Tests the display of deprecated and admin permissions.
    ...
    +  public function testSpecialPermissions() {
    

    I initially was going to add admin permissions here but decided it was out of scope, so the method name and docs need to be fixed accordingly.

  3. +++ b/core/modules/user/tests/src/Functional/PermissionsPageTest.php
    @@ -0,0 +1,127 @@
    +   * @see
    

    This is like "If Nietzsche wrote a unit test."

xjm’s picture

+++ b/core/modules/user/src/PermissionHandlerInterface.php
@@ -35,6 +35,9 @@
+   *   - deprecated: (optional) Whether the permission is deprecated. Be sure
+   *     to also provide an ugprade path revoking the deprecated permission and
+   *     (if applicable) granting the new permission.

I guess we should also add here something like "The implementation is responsible for retaining backwards compatibility for the permission and for informing the developer of the deprecation."

xjm’s picture

+++ b/core/modules/user/tests/src/Functional/PermissionsPageTest.php
@@ -0,0 +1,127 @@
+    $admin_perm_role2_checkbox = $this->cssSelect('#edit-' . $role2->id() . '-deprecated-admin-permission');
...
+  protected function selector($name) {
+    return 'tr[data-drupal-selector="edit-permissions-' . str_replace(" ", "-", $name) . '"]';
+  }

I could add another protected method for the checkbox selectors.

xjm’s picture

Assigned: Unassigned » xjm

Will post fixes tomorrow.

xjm’s picture

Assigned: xjm » Unassigned
Status: Needs work » Needs review
StatusFileSize
new13.14 KB
new9.75 KB

Updated test and docs.

xjm’s picture

StatusFileSize
new13.33 KB
new1.78 KB

Just a couple test docs fixes etc.

xjm’s picture

StatusFileSize
new13.41 KB
new1.86 KB

Duh.

xjm’s picture

I drafted a change record in https://www.drupal.org/node/2926020.

I originally had this bit:

Add a deprecation warning in the code that handles the permissions:

      case 'update':
        if ($account->hasPermission('update any media')) {
          @trigger_error("The 'update any media' permission is deprecated as of Drupal 8.5.x and will be removed before 9.0.0. Use the bundle-specific 'update any \$type media' permissions instead.");
          return AccessResult::allowed()->cachePerPermissions();
        }

But that made me think the @trigger_error() there is not actually helpful. If someone is checking the permission in their own access handler, then they're not going to necessarily exercise code paths in the core access control handler. And if they are exercising the code paths in the core access control handler then they probably also got the upgrade path.

But to add the warning in hasPermission() or such that would couple roles to the implementation of permission definitions, and run into the problem @dawhener alludes to in #9.

It's sort of similar to the question of how we'd add warnings to deprecations for constants. So I think we should simply adopt a deprecation standard for permissions, allow the UI to support it, and maybe add a followup for how we might raise warnings about it.

xjm’s picture

Issue summary: View changes

 

xjm’s picture

Hmm, that also made me wonder about the upgrade path in #2862422: Add per-media type creation permissions for media which revokes the old permissions. If someone's custom access control handler was checking those permission names, following the upgrade path, it would always return 'access denied' and would be functionally the same for that code as if the permission had been removed entirely.

dawehner’s picture

  1. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -124,13 +124,29 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +          if (in_array($permission_name, $role_permission)) {
    
    @@ -183,10 +201,18 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +          if (in_array($perm, $role_permissions[$rid])) {
    

    let's use strict=TRUE , as otherwise we run into https://3v4l.org/7qgqe potentially.

  2. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -183,10 +201,18 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +            $form['permissions'][$perm][$rid]['#default_value'] = 0;
    +            if (!empty($permissions[$perm]['deprecated'])) {
    +              $form['permissions'][$perm][$rid]['#disabled'] = TRUE;
    +            }
    

    Nice!

  3. +++ b/core/modules/user/tests/modules/user_permission_form_test/user_permission_form_test.permissions.yml
    @@ -0,0 +1,15 @@
    +  title: 'A normal permission'
    ...
    +  title: 'Deprecated permission 1'
    +  deprecated: true
    +deprecated permission 2:
    +  title: 'Deprecated permission 2'
    +  deprecated: true
    
    +++ b/core/modules/user/tests/src/Functional/PermissionFormTest.php
    @@ -0,0 +1,162 @@
    +    $this->grantPermissions($role1, ['deprecated permission 1']);
    

    I'm wondering whether it makes sense to name the permissions in a way that as a reader you already know which permission is used an which isn't. So 'deprecated used permission' and 'deprecated unused permission'.

  4. +++ b/core/modules/user/tests/src/Functional/PermissionFormTest.php
    @@ -0,0 +1,162 @@
    +  protected static function rowSelector($name) {
    

    Nice helper methods ...

xjm’s picture

StatusFileSize
new13.73 KB
new9.04 KB

WTF @ https://3v4l.org/7qgqe... wow. Oh PHP.

Attached addresses #23.

xjm’s picture

StatusFileSize
new13.72 KB
new816 bytes
+++ b/core/modules/user/tests/src/Functional/PermissionFormTest.php
@@ -0,0 +1,165 @@
+    $this->assertNoText('A used, used deprecated admin permission');

That text will indeed never be displayed.

xjm’s picture

StatusFileSize
new13.73 KB
new1.09 KB

Docblocks had a bit of copypasta.

Status: Needs review » Needs work

The last submitted patch, 26: user-interdiff-26.patch, failed testing. View results

dawehner’s picture

I really agree with the approach:

  • Hide the permission if nothing is using it right now
  • Provide a warning otherwise. I would have personally added another drupal_set_message(, 'warning') to make people aware,
    even if they just save the long form. What do you think about this?

Docblocks had a bit of copypasta.

For me its all about good method names, because this is what people actually most likely see.

xjm’s picture

I've mixed feelings about a dsm(). It could be bad UX to go to the form to grant Content Editors permission to create new revisions of My Whatsit Content Type, but to get a message out of nowhere Content Admins should no longer be granted the Update media permission. (Especially since the form is so long that it's hard to understand all the things that are there.)

We could instead add a status report message or such so it's in the context of reviewing their site's status rather than updating something else.

dawehner’s picture

We could instead add a status report message or such so it's in the context of reviewing their site's status rather than updating something else.

Now that you think about it, the existing test deprecation messages are sort of the same order than status messages. Given that sending the messages not always make sense.
+1 for adding a status report message as well?

xjm’s picture

Status: Needs work » Needs review
StatusFileSize
new15.97 KB
new2.24 KB

Here's that.

Status: Needs review » Needs work

The last submitted patch, 31: user-2924785-31.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

xjm’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new16.57 KB
new2.85 KB
new19.66 KB
new27.11 KB

It does help if we actually test our patches.

xjm’s picture

StatusFileSize
new16.09 KB
--- a/core/modules/system/system.permissions.yml
+++ b/core/modules/system/system.permissions.yml

@@ -19,6 +19,7 @@ view the administration theme:
 access content:
   title: 'View published content'
+  deprecated: true

It also helps if we don't leave our testing code in the patch.

The last submitted patch, 33: user-2924785-33.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

phenaproxima’s picture

Status: Needs review » Needs work

Looks pretty great to me. I found nothing major that needs work here -- mostly just suggestions, nitpicks, etc.

  1. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -124,13 +124,29 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +        foreach ($role_permissions as $role_name => $role_permission) {
    

    $role_permission is a confusing variable name. It sounds like a singular thing, but it's an array of permissions in the role. Can it be renamed to $permissions_in_role or something like that?

  2. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -124,13 +124,29 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +    if ($this->moduleHandler->moduleExists('node') && !empty($permissions['access content'])) {
    

    I don't quite understand how this change is in scope...?

  3. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -162,10 +178,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +          'deprecated_warning' => !empty($perm_item['deprecated']) ? $this->t('This permission should no longer be used.') : '',
    

    It might be prudent to only add this key if the permission is deprecated, so that it can properly pass isset() checks (for example, in hook_form_alter implementations).

  4. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -162,10 +178,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +          '#template' => '<div class="permission"><span class="title">{{ title }}</span>{% if description or warning or deprecated_warning %}<div class="description">{% if warning %}<em class="permission-warning">{{ warning }}</em> {% endif %}{% if deprecated_warning %}<em class="permission-warning">{{ deprecated_warning }} </em> {% endif %}{{ description }}</div>{% endif %}</div>',
    

    Superdupernit: There is an extra space after {{ deprecated_warning }}, before the </em>. Not sure if that is intentional?

  5. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -174,6 +191,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
             if (!$hide_descriptions) {
               $form['permissions'][$perm]['description']['#context']['description'] = $perm_item['description'];
               $form['permissions'][$perm]['description']['#context']['warning'] = $perm_item['warning'];
    +          $form['permissions'][$perm]['description']['#context']['deprecated_warning'] = $perm_item['deprecated_warning'];
    

    Because the deprecated_warning key is hidden behind the $hide_descriptions check, this will hide the deprecation warning if descriptions are turned off. Seems like we might want to show the deprecation warning unconditionally instead...

  6. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -183,10 +201,20 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +          if (in_array($perm, $role_permissions[$rid])) {
    

    This should be strict-checked (TRUE as the third and final argument).

  7. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -183,10 +201,20 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    +            $form['permissions'][$perm][$rid]['#default_value'] = 0;
    +            // If the role is not already assigned the deprecated permission,
    +            // don't allow it to be added.
    +            if (!empty($permissions[$perm]['deprecated'])) {
    +              $form['permissions'][$perm][$rid]['#disabled'] = TRUE;
    +            }
    

    If the checkbox has or can have a title attribute, maybe we should add a little text to that attribute to explain why the checkbox is disabled ("This permission cannot be used because it is deprecated" or something).

  8. +++ b/core/modules/user/src/PermissionHandlerInterface.php
    @@ -35,6 +35,11 @@
    +   *     and informing the developer. Be sure to also provide an ugprade path
    

    s/ugprade/upgrade :)

  9. +++ b/core/modules/user/tests/src/Functional/PermissionFormTest.php
    @@ -0,0 +1,165 @@
    +  protected function rowElement($name) {
    +    $element = $this->cssSelect(static::rowSelector($name));
    +    return !empty($element[0]) ? $element[0] : NULL;
    +  }
    

    Not a big deal, but I would suggest that this return the entire NodeElement associated with the row, which can allow future assertions to look for descriptions/checkboxes/etc. in the context of the element, rather than the entire page. (For example, $row_element->find('css', 'div.description')). If you do this with assertSession(), you can also implicitly assert that the row, in fact, exists. So this method could look like:

    return $this->assertSession()->elementExists('css', static::rowSelector($name))

xjm’s picture

Thanks @phenaproxima!

1 is not in scope; that variable already exists and is used in HEAD.

2 is in scope because otherwise, if the access content permission is deprecated, the page will fatal with "unsupported operand type".

3 is (again), following the existing pattern in HEAD which handles the restricted permission warnings in the same way.

For 5, I thought we should respect the UI pattern that is already used. Edit: Warnings about the restrict access permission are hidden in the same way and I think those are more important than this one. So I'd leave that out of the scope as well.

I'm not sure about 7; misuse of the title attribute is an accessibility issue. Edit: The other disabled checkboxes on the page for admin permissions don't have such a title so I don't think we should add it.

I'm confused by 9; it already does return the node element for the row?

I'll incorporate 4 and 6 after checking in about the other points. Thanks!

phenaproxima’s picture

1 is not in scope; that variable already exists and is used in HEAD.

That's true of $role_permissions (plural), but not $role_permission, which is introduced in the foreach loop in the patch. So we can totally give it a better name :)

For 5, I thought we should respect the UI pattern that is already used. Edit: Warnings about the restrict access permission are hidden in the same way and I think those are more important than this one. So I'd leave that out of the scope as well.

That makes sense. Should we maybe open a follow-up to unconditionally display security/deprecation notices on permissions?

I'm not sure about 7; misuse of the title attribute is an accessibility issue. Edit: The other disabled checkboxes on the page for admin permissions don't have such a title so I don't think we should add it.

Makes sense.

I'm confused by 9; it already does return the node element for the row?

Yes, it does, but it requires that the calling code assert that the return value is non-empty. Whereas assertSession()->elementExists() will do that for you implicitly, and return the element itself for further use. So we're doing extra unnecessary work in the current patch.

xjm’s picture

Assigned: Unassigned » xjm

That's true of $role_permissions (plural), but not $role_permission, which is introduced in the foreach loop in the patch. So we can totally give it a better name :)

Ah I see. I think foreach ($things as $thing) is usually better, even if $things isn't a great name itself. It allows the code to be read in the surrounding context. (If they'd given the overall variable a better name like $roles_permissions or $role_permissions_map then the looping variable could actually have been called $role_permissions which sounds like singular role, plural permissions.) But I guess what it's definitely not is a singular permission, so renaming the loop variable probably makes sense.

That makes sense. Should we maybe open a follow-up to unconditionally display security/deprecation notices on permissions?

No strong opinion about this since I actually didn't even know about the "hide descriptions" feature in the first place, but a followup will at least mean we don't need to worry about it here.

Yes, it does, but it requires that the calling code to assert that the return value is non-empty. Whereas assertSession()->elementExists() will do that for you implicitly, and return the element itself for further use. So we're doing extra unnecessary work in the current patch.

Ah I get it now. Since elementExists() also returns the element itself, we can do that instead.

I'll reroll to incorporate those fixes. Thanks!

xjm’s picture

Assigned: xjm » Unassigned

Obviously I didn't yet incorporate those fixes. :) Someone else can pick this issue up if they like!

robpowell’s picture

Assigned: Unassigned » robpowell
Status: Needs work » Active
robpowell’s picture

StatusFileSize
new16.16 KB
new3.36 KB

completed 1 and 9 from #36.

Making the change to rowElement($name) had a tickle down effect to descriptionElement($name). This required three changes to the assertions as AssertEmpty() expected a null response.

Finally, I also updated checkboxElement($permission, $role) to also have an assertion rather than returning a null.

robpowell’s picture

Assigned: robpowell » Unassigned
Status: Active » Needs review
larowlan’s picture

  1. +++ b/core/modules/user/src/Form/UserPermissionsForm.php
    @@ -162,10 +178,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    -          '#template' => '<div class="permission"><span class="title">{{ title }}</span>{% if description or warning %}<div class="description">{% if warning %}<em class="permission-warning">{{ warning }}</em> {% endif %}{{ description }}</div>{% endif %}</div>',
    +          '#template' => '<div class="permission"><span class="title">{{ title }}</span>{% if description or warning or deprecated_warning %}<div class="description">{% if warning %}<em class="permission-warning">{{ warning }}</em> {% endif %}{% if deprecated_warning %}<em class="permission-warning">{{ deprecated_warning }} </em> {% endif %}{{ description }}</div>{% endif %}</div>',
    

    I think this is now too complex for an inline template, and we need a custom theme hook.

  2. +++ b/core/modules/user/src/PermissionHandlerInterface.php
    @@ -35,6 +35,11 @@
    +   *   - deprecated: (optional) Whether the permission is deprecated. The
    +   *     implementation is responsible for retaining backwards compatibility
    +   *     and informing the developer. Be sure to also provide an ugprade path
    +   *     revoking the deprecated permission and (if applicable) granting the
    +   *     new permission.
    

    I don't think the implementation should be responsible for informing the developer, I think we should add code to \Drupal\user\RoleStorage::isPermissionInRoles for that and have it fire a trigger_error

  3. +++ b/core/modules/user/tests/modules/user_permission_form_test/user_permission_form_test.permissions.yml
    @@ -0,0 +1,15 @@
    +  deprecated: true
    ...
    +  deprecated: true
    ...
    +  deprecated: true
    

    As mentioned on slack, I don't think these should be a boolean.

    I think they should follow our normal deprecation format that way we can explain to people what to use instead.

    In addition I think 'This permission should no longer be used' isn't very helpful - it doesn't tell people what to use instead or when they need to remove the usages by.

    So by making this a string instead of a boolean, we could have it say This permission was deprecated in Drupal 8.3.0 and will be removed before Drupal 9.0.0. Use 'Administer something' instead. See http://drupal.org/node/the-change-notice-nid.

    We can then use that same message in \Drupal\user\RoleStorage::isPermissionInRoles when we trigger_error for deprecated permissions. So that developers using the deprecated permission get feedback via tests that they're using a deprecated permission and know what to use instead.

larowlan’s picture

We can then use that same message in \Drupal\user\RoleStorage::isPermissionInRoles when we trigger_error for deprecated permissions. So that developers using the deprecated permission get feedback via tests that they're using a deprecated permission and know what to use instead.

This would require us to keep a cache of deprecated permissions for performance sake, as we don't want to be collecting permissions at runtime.

larowlan’s picture

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

Yes this would be great feature!

At this time we will need a D10 version of the patch and there were changes requested in #44 that should be addressed

Please do not just reroll.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

stborchert made their first commit to this issue’s fork.

stborchert’s picture

stborchert’s picture

Status: Needs work » Needs review

I've tried to move the changes from the latest patch into a MR.

Things I could do:

  • add new key deprecated to permissions.yml that allows setting a deprecation message for a permission
  • add new theme hook for the permission information on admin/people/permissions (maybe user_permission_info isn't the best choice but I couldn't come up with a better name for now)
  • add test for UserPermissionsForm

Things I couldn't do yet:

  • find a place to trigger an error if a deprecated permission is used. RoleStorage::isPermissionInRoles() is likely to be deprecated because it isn't used anymore

Setting to "Needs review" for some thoughts about the current progess.

stborchert’s picture

berdir’s picture

Did a basic review.

On deprecations, I think you want to do a deprecation when a role with a deprecated permission is saved. We already have checks for non-existing permissions in \Drupal\user\Entity\Role::calculateDependencies, so the info is already available.

This will not cover code that uses it in hasPermission(), but we do not cache permissions atm, and checking it at runtime (access check time) would have way too much overhead. Doing it on role save matches the handling of non-existing permissions and deprecations are mostly for test, any test that tests a certain permission will ultimately need to set it on a role for it to do anything.