Making WordPress.org

Changeset 11744


Ignore:
Timestamp:
04/05/2022 05:14:18 AM (2 years ago)
Author:
dd32
Message:

Plugin Directory: Introduce specific capabilities for various actions, rather than just using "edit access".

See #5654.

Location:
sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-release-confirmation.php

    r11297 r11744  
    3030                $plugin = Plugin_Directory::get_plugin_post( $request['plugin_slug'] );
    3131
    32                 return current_user_can( 'plugin_admin_edit', $plugin ) && 'publish' === $plugin->post_status;
     32                return current_user_can( 'plugin_manage_releases', $plugin );
    3333            },
    3434        ] );
     
    5050                return (
    5151                    Release_Confirmation_Shortcode::can_access() &&
    52                     current_user_can( 'plugin_admin_edit', $plugin ) &&
    53                     'publish' === $plugin->post_status
     52                    current_user_can( 'plugin_manage_releases', $plugin )
    5453                );
    5554            },
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-self-close.php

    r10196 r11744  
    2525                $plugin = Plugin_Directory::get_plugin_post( $request['plugin_slug'] );
    2626
    27                 return current_user_can( 'plugin_admin_edit', $plugin ) && 'publish' === $plugin->post_status;
     27                return current_user_can( 'plugin_self_close', $plugin );
    2828            },
    2929        ] );
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/api/routes/class-plugin-self-transfer.php

    r11373 r11744  
    3131                $plugin = Plugin_Directory::get_plugin_post( $request['plugin_slug'] );
    3232
    33                 return
    34                     current_user_can( 'plugin_admin_edit', $plugin ) &&
    35                     get_current_user_id() == $plugin->post_author &&
    36                     'publish' === $plugin->post_status;
     33                return current_user_can( 'plugin_self_transfer', $plugin );
    3734            },
    3835        ] );
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/plugin-directory/class-capabilities.php

    r6287 r11744  
    2323     */
    2424    public static function map_meta_cap( $required_caps, $cap, $user_id, $context ) {
    25         $plugin_edit_cap = false;
    26         switch ( $cap ) {
    27             case 'plugin_admin_edit':
    28             case 'plugin_add_committer':
    29             case 'plugin_remove_committer':
    30             case 'plugin_add_support_rep':
    31             case 'plugin_remove_support_rep':
    32                 $plugin_edit_cap = true;
    33 
    34                 // Fall through
    35                 // Although we no longer have a admin view, this capability is still used to determine if the current user is a committer/contributor.
    36             case 'plugin_admin_view':
    37                 // Committers + Contributors.
    38                 // If no committers, post_author.
    39                 $required_caps = array();
    40                 $post          = get_post( $context[0] );
    41 
    42                 if ( ! $post ) {
    43                     $required_caps[] = 'do_not_allow';
    44                     break;
    45                 }
    46 
    47                 $user = new \WP_User( $user_id );
    48                 if ( $user->has_cap( 'plugin_review' ) ) {
    49                     $required_caps[] = 'plugin_review';
    50                     break;
    51                 }
    52 
    53                 // Committers
    54                 $committers = Tools::get_plugin_committers( $post->post_name );
    55                 if ( ! $committers && 'publish' === $post->post_status ) {
    56                     // post_author in the event no committers exist (yet?)
    57                     $committers = array( get_user_by( 'ID', $post->post_author )->user_login );
    58                 }
    59 
    60                 if ( in_array( $user->user_login, $committers ) ) {
    61                     $required_caps[] = 'exist'; // All users are allowed to exist, even when they have no role.
    62                     break;
    63                 }
    64 
    65                 if ( ! $plugin_edit_cap ) {
    66                     // Contributors can view, but not edit.
    67                     $terms = get_the_terms( $post, 'plugin_contributors' );
    68                     if ( is_array( $terms ) ) {
    69                         $contributors = (array) wp_list_pluck( $terms, 'name' );
    70                         if ( in_array( $user->user_nicename, $contributors, true ) ) {
    71                             $required_caps[] = 'exist'; // All users are allowed to exist, even when they have no role.
    72                             break;
    73                         }
    74                     }
    75                 }
    76 
    77                 // Else;
    78                 $required_caps[] = 'do_not_allow';
    79                 break;
    80 
    81             case 'plugin_transition':
    82                 /*
    83                  Handle the transition between
    84                  pending -> publish
    85                  publish -> rejected
    86                  publish -> closed
    87                  etc
    88                 */
    89                 break;
     25        $handled_caps = array(
     26            // All these caps must pass a WP_Post context.
     27            'plugin_admin_view',
     28            'plugin_admin_edit',
     29            'plugin_add_committer',
     30            'plugin_remove_committer',
     31            'plugin_add_support_rep',
     32            'plugin_remove_support_rep',
     33            'plugin_self_transfer',
     34            'plugin_self_close',
     35            'plugin_manage_releases',
     36        );
     37        if ( ! in_array( $cap, $handled_caps ) ) {
     38            return $required_caps;
    9039        }
    9140
    92         return $required_caps;
     41        // Protect against a cap call without a plugin context.
     42        $post = $context ? get_post( $context[0] ) : false;
     43        if ( ! $post ) {
     44            return array( 'do_not_allow' );
     45        }
     46
     47        // Start over, we'll specify all caps below.
     48        $required_caps = array();
     49
     50        // Certain actions require the plugin to be published.
     51        if (
     52            'publish' !== $post->post_status &&
     53            in_array(
     54                $cap,
     55                array(
     56                    'plugin_self_transfer',
     57                    'plugin_self_close',
     58                    'plugin_manage_releases',
     59                )
     60            )
     61        ) {
     62            $required_caps[] = 'do_not_allow';
     63        }
     64
     65        // If a plugin is in the Beta or Featured views, they're not able to self-manage certain things. Require reviewer.
     66        if (
     67            in_array(
     68                $cap,
     69                array(
     70                    'plugin_self_close',
     71                    'plugin_self_transfer',
     72                    'plugin_add_committer',
     73                    'plugin_remove_committer',
     74                )
     75            ) &&
     76            is_object_in_term( $post->ID, 'plugin_section', array( 'beta', 'featured' ) )
     77        ) {
     78            $required_caps[] = 'plugin_review';
     79        }
     80
     81        // Only the Owner of a plugin is able to transfer plugins.
     82        if ( 'plugin_self_transfer' === $cap && $user_id != $post->post_author ) {
     83            $required_caps[] = 'do_not_allow';
     84        }
     85
     86        // Committers
     87        $committers = Tools::get_plugin_committers( $post->post_name );
     88        // If there are no committers, use the plugin author if the plugin is published.
     89        if ( ! $committers && 'publish' === $post->post_status ) {
     90            $committers = array( get_user_by( 'ID', $post->post_author )->user_login );
     91        }
     92
     93        if ( in_array( $user->user_login, $committers ) ) {
     94            $required_caps[] = 'exist';
     95        }
     96
     97        // Contributors can view, but not edit.
     98        if ( 'plugin_admin_view' === $cap ) {
     99            $terms = get_the_terms( $post, 'plugin_contributors' );
     100            if ( is_array( $terms ) ) {
     101                $contributors = (array) wp_list_pluck( $terms, 'name' );
     102                if ( in_array( $user->user_nicename, $contributors, true ) ) {
     103                    $required_caps[] = 'exist';
     104                }
     105            }
     106        }
     107
     108        // Allow users with review caps to access.
     109        $user = new \WP_User( $user_id );
     110        if ( $user->has_cap( 'plugin_review' ) ) {
     111            $required_caps[] = 'plugin_review';
     112        }
     113
     114        // If we've not found a matching user/cap, deny.
     115        if ( ! $required_caps ) {
     116            $required_caps[] = 'do_not_allow';
     117        }
     118
     119        return array_unique( $required_caps );
    93120    }
    94121
Note: See TracChangeset for help on using the changeset viewer.