Make WordPress Core

Ticket #35614: 35614.2.patch

File 35614.2.patch, 18.0 KB (added by johnbillion, 8 years ago)
  • src/wp-includes/taxonomy.php

     
    6161                'show_ui' => true,
    6262                'show_admin_column' => true,
    6363                '_builtin' => true,
     64                'capabilities' => array(
     65                        'manage_terms' => 'manage_categories',
     66                        'edit_terms'   => 'edit_categories',
     67                        'delete_terms' => 'delete_categories',
     68                        'assign_terms' => 'assign_categories',
     69                ),
    6470        ) );
    6571
    6672        register_taxonomy( 'post_tag', 'post', array(
     
    7177                'show_ui' => true,
    7278                'show_admin_column' => true,
    7379                '_builtin' => true,
     80                'capabilities' => array(
     81                        'manage_terms' => 'manage_post_tags',
     82                        'edit_terms'   => 'edit_post_tags',
     83                        'delete_terms' => 'delete_post_tags',
     84                        'assign_terms' => 'assign_post_tags',
     85                ),
    7486        ) );
    7587
    7688        register_taxonomy( 'nav_menu', 'nav_menu_item', array(
  • src/wp-includes/link-template.php

     
    930930        }
    931931
    932932        $tax = get_taxonomy( $term->taxonomy );
    933         if ( ! $tax || ! current_user_can( $tax->cap->edit_terms ) ) {
     933        if ( ! $tax || ! current_user_can( 'edit_term', $term->term_id ) ) {
    934934                return;
    935935        }
    936936
     
    984984                return;
    985985
    986986        $tax = get_taxonomy( $term->taxonomy );
    987         if ( ! current_user_can( $tax->cap->edit_terms ) ) {
     987        if ( ! current_user_can( 'edit_term', $term->term_id ) ) {
    988988                return;
    989989        }
    990990
  • src/wp-includes/class-wp-xmlrpc-server.php

     
    18821882
    18831883                $taxonomy = get_taxonomy( $content_struct['taxonomy'] );
    18841884
    1885                 if ( ! current_user_can( $taxonomy->cap->manage_terms ) )
     1885                if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) {
    18861886                        return new IXR_Error( 401, __( 'Sorry, you are not allowed to create terms in this taxonomy.' ) );
     1887                }
    18871888
    18881889                $taxonomy = (array) $taxonomy;
    18891890
     
    19691970
    19701971                $taxonomy = get_taxonomy( $content_struct['taxonomy'] );
    19711972
    1972                 if ( ! current_user_can( $taxonomy->cap->edit_terms ) )
    1973                         return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ) );
    1974 
    19751973                $taxonomy = (array) $taxonomy;
    19761974
    19771975                // hold the data of the term
     
    19851983                if ( ! $term )
    19861984                        return new IXR_Error( 404, __( 'Invalid term ID.' ) );
    19871985
     1986                if ( ! current_user_can( 'edit_term', $term_id ) ) {
     1987                        return new IXR_Error( 401, __( 'Sorry, you are not allowed to edit this term.' ) );
     1988                }
     1989
    19881990                if ( isset( $content_struct['name'] ) ) {
    19891991                        $term_data['name'] = trim( $content_struct['name'] );
    19901992
     
    20642066                        return new IXR_Error( 403, __( 'Invalid taxonomy.' ) );
    20652067
    20662068                $taxonomy = get_taxonomy( $taxonomy );
    2067 
    2068                 if ( ! current_user_can( $taxonomy->cap->delete_terms ) )
    2069                         return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete terms in this taxonomy.' ) );
    2070 
    20712069                $term = get_term( $term_id, $taxonomy->name );
    20722070
    20732071                if ( is_wp_error( $term ) )
     
    20762074                if ( ! $term )
    20772075                        return new IXR_Error( 404, __( 'Invalid term ID.' ) );
    20782076
     2077                if ( ! current_user_can( 'delete_term', $term_id ) ) {
     2078                        return new IXR_Error( 401, __( 'Sorry, you are not allowed to delete this term.' ) );
     2079                }
     2080
    20792081                $result = wp_delete_term( $term_id, $taxonomy->name );
    20802082
    20812083                if ( is_wp_error( $result ) )
     
    21362138
    21372139                $taxonomy = get_taxonomy( $taxonomy );
    21382140
    2139                 if ( ! current_user_can( $taxonomy->cap->assign_terms ) )
    2140                         return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ) );
    2141 
    21422141                $term = get_term( $term_id , $taxonomy->name, ARRAY_A );
    21432142
    21442143                if ( is_wp_error( $term ) )
     
    21472146                if ( ! $term )
    21482147                        return new IXR_Error( 404, __( 'Invalid term ID.' ) );
    21492148
     2149                if ( ! current_user_can( 'assign_term', $term_id ) ) {
     2150                        return new IXR_Error( 401, __( 'Sorry, you are not allowed to assign this term.' ) );
     2151                }
     2152
    21502153                return $this->_prepare_term( $term );
    21512154        }
    21522155
  • src/wp-includes/capabilities.php

     
    402402        case 'delete_site':
    403403                $caps[] = 'manage_options';
    404404                break;
     405        case 'edit_term':
     406        case 'delete_term':
     407        case 'assign_term':
     408                $term_id = $args[0];
     409                $term = get_term( $term_id );
     410                if ( ! $term || is_wp_error( $term ) ) {
     411                        $caps[] = 'do_not_allow';
     412                        break;
     413                }
     414
     415                $tax = get_taxonomy( $term->taxonomy );
     416                if ( ! $tax ) {
     417                        $caps[] = 'do_not_allow';
     418                        break;
     419                }
     420
     421                if ( 'delete_term' === $cap && ( $term->term_id == get_option( 'default_' . $term->taxonomy ) ) ) {
     422                        $caps[] = 'do_not_allow';
     423                        break;
     424                }
     425
     426                $taxo_cap = $cap . 's';
     427
     428                $caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id );
     429
     430                break;
     431        case 'manage_categories':
     432        case 'manage_post_tags':
     433        case 'edit_categories':
     434        case 'edit_post_tags':
     435        case 'delete_categories':
     436        case 'delete_post_tags':
     437                $caps[] = 'manage_categories';
     438                break;
     439        case 'assign_categories':
     440        case 'assign_post_tags':
     441                $caps[] = 'edit_posts';
     442                break;
    405443        default:
    406444                // Handle meta capabilities for custom post types.
    407445                global $post_type_meta_caps;
     
    413451                // If no meta caps match, return the original cap.
    414452                $caps[] = $cap;
    415453        }
    416 
     454       
    417455        /**
    418456         * Filters a user's capabilities depending on specific context and/or privilege.
    419457         *
  • src/wp-includes/admin-bar.php

     
    607607                        ) );
    608608                } elseif ( ! empty( $current_object->taxonomy )
    609609                        && ( $tax = get_taxonomy( $current_object->taxonomy ) )
    610                         && current_user_can( $tax->cap->edit_terms )
     610                        && current_user_can( 'edit_term', $current_object->term_id )
    611611                        && $edit_term_link = get_edit_term_link( $current_object->term_id, $current_object->taxonomy ) )
    612612                {
    613613                        $wp_admin_bar->add_menu( array(
  • src/wp-admin/term.php

     
    3131$title    = $tax->labels->edit_item;
    3232
    3333if ( ! in_array( $taxonomy, get_taxonomies( array( 'show_ui' => true ) ) ) ||
    34      ! current_user_can( $tax->cap->manage_terms )
     34     ! current_user_can( 'edit_term', $tag->term_id )
    3535) {
    3636        wp_die(
    3737                '<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
    38                 '<p>' . __( 'Sorry, you are not allowed to manage this item.' ) . '</p>',
     38                '<p>' . __( 'Sorry, you are not allowed to edit this item.' ) . '</p>',
    3939                403
    4040        );
    4141}
  • src/wp-admin/includes/meta-boxes.php

     
    434434                <input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" /></p>
    435435        </div>
    436436        <p class="howto" id="new-tag-<?php echo $tax_name; ?>-desc"><?php echo $taxonomy->labels->separate_items_with_commas; ?></p>
     437        <?php elseif ( empty( $terms_to_edit ) ): ?>
     438                <p><?php echo $taxonomy->labels->no_terms; ?></p>
    437439        <?php endif; ?>
    438440        </div>
    439441        <div class="tagchecklist"></div>
  • src/wp-admin/includes/class-wp-terms-list-table.php

     
    151151         */
    152152        protected function get_bulk_actions() {
    153153                $actions = array();
    154                 $actions['delete'] = __( 'Delete' );
     154
     155                if ( current_user_can( get_taxonomy( $this->screen->taxonomy )->cap->delete_terms ) ) {
     156                        $actions['delete'] = __( 'Delete' );
     157                }
    155158
    156159                return $actions;
    157160        }
     
    332335         * @return string
    333336         */
    334337        public function column_cb( $tag ) {
    335                 $default_term = get_option( 'default_' . $this->screen->taxonomy );
    336 
    337                 if ( current_user_can( get_taxonomy( $this->screen->taxonomy )->cap->delete_terms ) && $tag->term_id != $default_term )
     338                if ( current_user_can( 'delete_term', $tag->term_id ) ) {
    338339                        return '<label class="screen-reader-text" for="cb-select-' . $tag->term_id . '">' . sprintf( __( 'Select %s' ), $tag->name ) . '</label>'
    339340                                . '<input type="checkbox" name="delete_tags[]" value="' . $tag->term_id . '" id="cb-select-' . $tag->term_id . '" />';
     341                }
    340342
    341343                return '&nbsp;';
    342344        }
     
    423425
    424426                $taxonomy = $this->screen->taxonomy;
    425427                $tax = get_taxonomy( $taxonomy );
    426                 $default_term = get_option( 'default_' . $taxonomy );
    427 
    428428                $uri = wp_doing_ajax() ? wp_get_referer() : $_SERVER['REQUEST_URI'];
    429429
    430430                $edit_link = add_query_arg(
     
    434434                );
    435435
    436436                $actions = array();
    437                 if ( current_user_can( $tax->cap->edit_terms ) ) {
     437                if ( current_user_can( 'edit_term', $tag->term_id ) ) {
    438438                        $actions['edit'] = sprintf(
    439439                                '<a href="%s" aria-label="%s">%s</a>',
    440440                                esc_url( $edit_link ),
     
    449449                                __( 'Quick&nbsp;Edit' )
    450450                        );
    451451                }
    452                 if ( current_user_can( $tax->cap->delete_terms ) && $tag->term_id != $default_term ) {
     452                if ( current_user_can( 'delete_term', $tag->term_id ) ) {
    453453                        $actions['delete'] = sprintf(
    454454                                '<a href="%s" class="delete-tag aria-button-if-js" aria-label="%s">%s</a>',
    455455                                wp_nonce_url( "edit-tags.php?action=delete&amp;taxonomy=$taxonomy&amp;tag_ID=$tag->term_id", 'delete-tag_' . $tag->term_id ),
  • src/wp-admin/includes/ajax-actions.php

     
    597597        $taxonomy = !empty($_POST['taxonomy']) ? $_POST['taxonomy'] : 'post_tag';
    598598        $tax = get_taxonomy($taxonomy);
    599599
    600         if ( !current_user_can( $tax->cap->delete_terms ) )
     600        if ( ! current_user_can( 'delete_term', $tag_id ) ) {
    601601                wp_die( -1 );
     602        }
    602603
    603604        $tag = get_term( $tag_id, $taxonomy );
    604605        if ( !$tag || is_wp_error( $tag ) )
     
    796797        if ( empty( $action ) )
    797798                $action = 'add-link-category';
    798799        check_ajax_referer( $action );
    799         if ( !current_user_can( 'manage_categories' ) )
     800        $tax = get_taxonomy( 'link_category' );
     801        if ( ! current_user_can( $tax->cap->manage_terms ) ) {
    800802                wp_die( -1 );
     803        }
    801804        $names = explode(',', wp_unslash( $_POST['newcat'] ) );
    802805        $x = new WP_Ajax_Response();
    803806        foreach ( $names as $cat_name ) {
     
    17031706        if ( ! $tax )
    17041707                wp_die( 0 );
    17051708
    1706         if ( ! current_user_can( $tax->cap->edit_terms ) )
     1709        if ( ! isset( $_POST['tax_ID'] ) || ! ( $id = (int) $_POST['tax_ID'] ) ) {
    17071710                wp_die( -1 );
     1711        }
    17081712
    1709         $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) );
    1710 
    1711         if ( ! isset($_POST['tax_ID']) || ! ( $id = (int) $_POST['tax_ID'] ) )
     1713        if ( ! current_user_can( 'edit_term', $id ) ) {
    17121714                wp_die( -1 );
     1715        }
     1716
     1717        $wp_list_table = _get_list_table( 'WP_Terms_List_Table', array( 'screen' => 'edit-' . $taxonomy ) );
    17131718
    17141719        $tag = get_term( $id, $taxonomy );
    17151720        $_POST['description'] = $tag->description;
  • src/wp-admin/edit-tags.php

     
    108108        $tag_ID = (int) $_REQUEST['tag_ID'];
    109109        check_admin_referer( 'delete-tag_' . $tag_ID );
    110110
    111         if ( ! current_user_can( $tax->cap->delete_terms ) ) {
     111        if ( ! current_user_can( 'delete_term', $tag_ID ) ) {
    112112                wp_die(
    113113                        '<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
    114114                        '<p>' . __( 'Sorry, you are not allowed to delete this item.' ) . '</p>',
     
    168168        $tag_ID = (int) $_POST['tag_ID'];
    169169        check_admin_referer( 'update-tag_' . $tag_ID );
    170170
    171         if ( ! current_user_can( $tax->cap->edit_terms ) ) {
     171        if ( ! current_user_can( 'edit_term', $tag_ID ) ) {
    172172                wp_die(
    173173                        '<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
    174174                        '<p>' . __( 'Sorry, you are not allowed to edit this item.' ) . '</p>',
     
    294294
    295295require_once( ABSPATH . 'wp-admin/admin-header.php' );
    296296
    297 if ( ! current_user_can( $tax->cap->edit_terms ) ) {
    298         wp_die(
    299                 '<h1>' . __( 'Cheatin&#8217; uh?' ) . '</h1>' .
    300                 '<p>' . __( 'Sorry, you are not allowed to edit this item.' ) . '</p>',
    301                 403
    302         );
    303 }
    304 
    305297/** Also used by the Edit Tag  form */
    306298require_once( ABSPATH . 'wp-admin/includes/edit-tag-messages.php' );
    307299
  • tests/phpunit/tests/xmlrpc/wp/getTerm.php

     
    4343                $result = $this->myxmlrpcserver->wp_getTerm( array( 1, 'subscriber', 'subscriber', 'category', $this->term['term_id'] ) );
    4444                $this->assertInstanceOf( 'IXR_Error', $result );
    4545                $this->assertEquals( 401, $result->code );
    46                 $this->assertEquals( __( 'Sorry, you are not allowed to assign terms in this taxonomy.' ), $result->message );
     46                $this->assertEquals( __( 'Sorry, you are not allowed to assign this term.' ), $result->message );
    4747        }
    4848
    4949
  • tests/phpunit/tests/xmlrpc/wp/editTerm.php

     
    4949                $result = $this->myxmlrpcserver->wp_editTerm( array( 1, 'subscriber', 'subscriber', $this->parent_term['term_id'], array( 'taxonomy' => 'category' ) ) );
    5050                $this->assertInstanceOf( 'IXR_Error', $result );
    5151                $this->assertEquals( 401, $result->code );
    52                 $this->assertEquals( __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), $result->message );
     52                $this->assertEquals( __( 'Sorry, you are not allowed to edit this term.' ), $result->message );
    5353        }
    5454
    5555        function test_term_not_exists() {
  • tests/phpunit/tests/xmlrpc/wp/deleteTerm.php

     
    4343                $result = $this->myxmlrpcserver->wp_deleteTerm( array( 1, 'subscriber', 'subscriber', 'category', $this->term['term_id'] ) );
    4444                $this->assertInstanceOf( 'IXR_Error', $result );
    4545                $this->assertEquals( 401, $result->code );
    46                 $this->assertEquals( __( 'Sorry, you are not allowed to delete terms in this taxonomy.' ), $result->message );
     46                $this->assertEquals( __( 'Sorry, you are not allowed to delete this term.' ), $result->message );
    4747        }
    4848
    4949        function test_empty_term() {
  • tests/phpunit/tests/user/capabilities.php

     
    231231                        'customize'              => array( 'administrator' ),
    232232                        'delete_site'            => array( 'administrator' ),
    233233                        'add_users'              => array( 'administrator' ),
     234
     235                        'edit_categories'        => array( 'administrator', 'editor' ),
     236                        'delete_categories'      => array( 'administrator', 'editor' ),
     237                        'manage_post_tags'       => array( 'administrator', 'editor' ),
     238                        'edit_post_tags'         => array( 'administrator', 'editor' ),
     239                        'delete_post_tags'       => array( 'administrator', 'editor' ),
     240
     241                        'assign_categories'      => array( 'administrator', 'editor', 'author', 'contributor' ),
     242                        'assign_post_tags'       => array( 'administrator', 'editor', 'author', 'contributor' ),
    234243                );
    235244        }
    236245
     
    238247                return array(
    239248                        'upload_plugins'         => array(),
    240249                        'upload_themes'          => array(),
     250
    241251                        'customize'              => array( 'administrator' ),
    242252                        'delete_site'            => array( 'administrator' ),
    243253                        'add_users'              => array( 'administrator' ),
     254
     255                        'edit_categories'        => array( 'administrator', 'editor' ),
     256                        'delete_categories'      => array( 'administrator', 'editor' ),
     257                        'manage_post_tags'       => array( 'administrator', 'editor' ),
     258                        'edit_post_tags'         => array( 'administrator', 'editor' ),
     259                        'delete_post_tags'       => array( 'administrator', 'editor' ),
     260
     261                        'assign_categories'      => array( 'administrator', 'editor', 'author', 'contributor' ),
     262                        'assign_post_tags'       => array( 'administrator', 'editor', 'author', 'contributor' ),
    244263                );
    245264        }
    246265
     
    972991                }
    973992        }
    974993
     994        /**
     995         * @dataProvider dataTaxonomies
     996         *
     997         * @ticket 35614
     998         */
     999        public function test_default_taxonomy_term_cannot_be_deleted( $taxonomy ) {
     1000                if ( ! taxonomy_exists( $taxonomy ) ) {
     1001                        register_taxonomy( $taxonomy, 'post' );
     1002                }
     1003
     1004                $tax  = get_taxonomy( $taxonomy );
     1005                $user = self::$users['administrator'];
     1006                $term = self::factory()->term->create_and_get( array(
     1007                        'taxonomy' => $taxonomy,
     1008                ) );
     1009
     1010                update_option( "default_{$taxonomy}", $term->term_id );
     1011
     1012                $this->assertTrue( user_can( $user->ID, $tax->cap->delete_terms ) );
     1013                $this->assertFalse( user_can( $user->ID, 'delete_term', $term->term_id ) );
     1014        }
     1015
     1016        /**
     1017         * @dataProvider dataTaxonomies
     1018         *
     1019         * @ticket 35614
     1020         */
     1021        public function test_taxonomy_caps_map_correctly_to_their_meta_cap( $taxonomy ) {
     1022                if ( ! taxonomy_exists( $taxonomy ) ) {
     1023                        register_taxonomy( $taxonomy, 'post' );
     1024                }
     1025
     1026                $tax  = get_taxonomy( $taxonomy );
     1027                $term = self::factory()->term->create_and_get( array(
     1028                        'taxonomy' => $taxonomy,
     1029                ) );
     1030
     1031                foreach ( self::$users as $role => $user ) {
     1032                        $this->assertSame(
     1033                                user_can( $user->ID, 'edit_term', $term->term_id ),
     1034                                user_can( $user->ID, $tax->cap->edit_terms ),
     1035                                "Role: {$role}"
     1036                        );
     1037                        $this->assertSame(
     1038                                user_can( $user->ID, 'delete_term', $term->term_id ),
     1039                                user_can( $user->ID, $tax->cap->delete_terms ),
     1040                                "Role: {$role}"
     1041                        );
     1042                        $this->assertSame(
     1043                                user_can( $user->ID, 'assign_term', $term->term_id ),
     1044                                user_can( $user->ID, $tax->cap->assign_terms ),
     1045                                "Role: {$role}"
     1046                        );
     1047                }
     1048
     1049        }
     1050
    9751051        public function dataTaxonomies() {
    9761052                return array(
    9771053                        array(