Make WordPress Core

Changeset 41290


Ignore:
Timestamp:
08/22/2017 02:01:36 PM (9 years ago)
Author:
johnbillion
Message:

Plugins: Introduce singular capabilities for activating and deactivating individual plugins.

This introduces the following meta capabilities:

  • activate_plugin
  • deactivate_plugin
  • deactivate_plugins

The singular activate_plugin and deactivate_plugin capabilities are used along with the corresponding plugin name when
determining whether or not a user can activate or deactivate an individual plugin.

The plural deactivate_plugins capability is used in place of the existing activate_plugins capability when determining
whether a user can deactivate plugins.

Each of these new meta capabilities map to the existing activate_plugins primitive capability, which means there is no
change in existing behaviour, but plugins can now filter the capabilities required to activate and deactivate individual
plugins.

Fixes #38652

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/ajax-actions.php

    r41289 r41290  
    37053705        $plugins_url = ( 'import' === $pagenow ) ? admin_url( 'plugins.php' ) : network_admin_url( 'plugins.php' );
    37063706
    3707         if ( current_user_can( 'activate_plugins' ) && is_plugin_inactive( $install_status['file'] ) ) {
     3707        if ( current_user_can( 'activate_plugin', $install_status['file'] ) && is_plugin_inactive( $install_status['file'] ) ) {
    37083708                $status['activateUrl'] = add_query_arg( array(
    37093709                        '_wpnonce' => wp_create_nonce( 'activate-plugin_' . $install_status['file'] ),
  • trunk/src/wp-admin/includes/class-plugin-installer-skin.php

    r41161 r41290  
    7272                if ( ! $this->result || is_wp_error($this->result) ) {
    7373                        unset( $install_actions['activate_plugin'], $install_actions['network_activate'] );
    74                 } elseif ( ! current_user_can( 'activate_plugins' ) ) {
     74                } elseif ( ! current_user_can( 'activate_plugin', $plugin_file ) ) {
    7575                        unset( $install_actions['activate_plugin'] );
    7676                }
  • trunk/src/wp-admin/includes/class-plugin-upgrader-skin.php

    r41161 r41290  
    5252                        'plugins_page' => '<a href="' . self_admin_url( 'plugins.php' ) . '" target="_parent">' . __( 'Return to Plugins page' ) . '</a>'
    5353                );
    54                 if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugins' ) )
     54                if ( $this->plugin_active || ! $this->result || is_wp_error( $this->result ) || ! current_user_can( 'activate_plugin', $this->plugin ) )
    5555                        unset( $update_actions['activate_plugin'] );
    5656
  • trunk/src/wp-admin/includes/class-wp-plugin-install-list-table.php

    r41289 r41290  
    469469                                                if ( is_plugin_active( $status['file'] ) ) {
    470470                                                        $action_links[] = '<button type="button" class="button button-disabled" disabled="disabled">' . _x( 'Active', 'plugin' ) . '</button>';
    471                                                 } elseif ( current_user_can( 'activate_plugins' ) ) {
     471                                                } elseif ( current_user_can( 'activate_plugin', $status['file'] ) ) {
    472472                                                        $button_text  = __( 'Activate' );
    473473                                                        /* translators: %s: Plugin name */
  • trunk/src/wp-admin/includes/class-wp-plugins-list-table.php

    r41231 r41290  
    621621                                        );
    622622                                } elseif ( $is_active ) {
    623                                         /* translators: %s: plugin name */
    624                                         $actions['deactivate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'deactivate-plugin_' . $plugin_file ) . '" aria-label="' . esc_attr( sprintf( _x( 'Deactivate %s', 'plugin' ), $plugin_data['Name'] ) ) . '">' . __( 'Deactivate' ) . '</a>';
     623                                        if ( current_user_can( 'deactivate_plugin', $plugin_file ) ) {
     624                                                /* translators: %s: plugin name */
     625                                                $actions['deactivate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=deactivate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'deactivate-plugin_' . $plugin_file ) . '" aria-label="' . esc_attr( sprintf( _x( 'Deactivate %s', 'plugin' ), $plugin_data['Name'] ) ) . '">' . __( 'Deactivate' ) . '</a>';
     626                                        }
    625627                                } else {
    626                                         /* translators: %s: plugin name */
    627                                         $actions['activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'activate-plugin_' . $plugin_file ) . '" class="edit" aria-label="' . esc_attr( sprintf( _x( 'Activate %s', 'plugin' ), $plugin_data['Name'] ) ) . '">' . __( 'Activate' ) . '</a>';
     628                                        if ( current_user_can( 'activate_plugin', $plugin_file ) ) {
     629                                                /* translators: %s: plugin name */
     630                                                $actions['activate'] = '<a href="' . wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $plugin_file . '&amp;plugin_status=' . $context . '&amp;paged=' . $page . '&amp;s=' . $s, 'activate-plugin_' . $plugin_file ) . '" class="edit" aria-label="' . esc_attr( sprintf( _x( 'Activate %s', 'plugin' ), $plugin_data['Name'] ) ) . '">' . __( 'Activate' ) . '</a>';
     631                                        }
    628632
    629633                                        if ( ! is_multisite() && current_user_can( 'delete_plugins' ) ) {
  • trunk/src/wp-admin/plugins.php

    r40169 r41290  
    3030        switch ( $action ) {
    3131                case 'activate':
    32                         if ( ! current_user_can('activate_plugins') )
    33                                 wp_die(__('Sorry, you are not allowed to activate plugins for this site.'));
     32                        if ( ! current_user_can( 'activate_plugin', $plugin ) ) {
     33                                wp_die( __( 'Sorry, you are not allowed to activate this plugin.' ) );
     34                        }
    3435
    3536                        if ( is_multisite() && ! is_network_admin() && is_network_only_plugin( $plugin ) ) {
     
    8990                                                unset( $plugins[ $i ] );
    9091                                        }
     92                                        // Only activate plugins which the user can activate.
     93                                        if ( ! current_user_can( 'activate_plugin', $plugin ) ) {
     94                                                unset( $plugins[ $i ] );
     95                                        }
    9196                                }
    9297                        }
     
    147152
    148153                case 'error_scrape':
    149                         if ( ! current_user_can('activate_plugins') )
    150                                 wp_die(__('Sorry, you are not allowed to activate plugins for this site.'));
     154                        if ( ! current_user_can( 'activate_plugin', $plugin ) ) {
     155                                wp_die( __( 'Sorry, you are not allowed to activate this plugin.' ) );
     156                        }
    151157
    152158                        check_admin_referer('plugin-activation-error_' . $plugin);
     
    168174
    169175                case 'deactivate':
    170                         if ( ! current_user_can('activate_plugins') )
    171                                 wp_die(__('Sorry, you are not allowed to deactivate plugins for this site.'));
     176                        if ( ! current_user_can( 'deactivate_plugin', $plugin ) ) {
     177                                wp_die( __( 'Sorry, you are not allowed to deactivate this plugin.' ) );
     178                        }
    172179
    173180                        check_admin_referer('deactivate-plugin_' . $plugin);
     
    193200
    194201                case 'deactivate-selected':
    195                         if ( ! current_user_can('activate_plugins') )
     202                        if ( ! current_user_can( 'deactivate_plugins' ) ) {
    196203                                wp_die(__('Sorry, you are not allowed to deactivate plugins for this site.'));
     204                        }
    197205
    198206                        check_admin_referer('bulk-plugins');
     
    205213                                $plugins = array_filter( $plugins, 'is_plugin_active' );
    206214                                $plugins = array_diff( $plugins, array_filter( $plugins, 'is_plugin_active_for_network' ) );
     215
     216                                foreach ( $plugins as $i => $plugin ) {
     217                                        // Only deactivate plugins which the user can deactivate.
     218                                        if ( ! current_user_can( 'deactivate_plugin', $plugin ) ) {
     219                                                unset( $plugins[ $i ] );
     220                                        }
     221                                }
     222
    207223                        }
    208224                        if ( empty($plugins) ) {
  • trunk/src/wp-includes/capabilities.php

    r41268 r41290  
    408408                break;
    409409        case 'activate_plugins':
    410                 $caps[] = $cap;
     410        case 'deactivate_plugins':
     411        case 'activate_plugin':
     412        case 'deactivate_plugin':
     413                $caps[] = 'activate_plugins';
    411414                if ( is_multisite() ) {
    412415                        // update_, install_, and delete_ are handled above with is_super_admin().
  • trunk/tests/phpunit/tests/user/capabilities.php

    r41268 r41290  
    236236                        'install_languages'      => array( 'administrator' ),
    237237                        'update_languages'       => array( 'administrator' ),
     238                        'deactivate_plugins'     => array( 'administrator' ),
    238239
    239240                        'edit_categories'        => array( 'administrator', 'editor' ),
     
    266267                        'install_languages'      => array(),
    267268                        'update_languages'       => array(),
     269                        'deactivate_plugins'     => array(),
    268270
    269271                        'customize'              => array( 'administrator' ),
     
    426428                        $expected['manage_links'],
    427429                        // Singular object meta capabilities (where an object ID is passed) are not tested:
     430                        $expected['activate_plugin'],
     431                        $expected['deactivate_plugin'],
    428432                        $expected['remove_user'],
    429433                        $expected['promote_user'],
Note: See TracChangeset for help on using the changeset viewer.