Make WordPress Core

Changeset 42380


Ignore:
Timestamp:
12/09/2017 10:50:13 PM (7 years ago)
Author:
johnbillion
Message:

Role/Capability: When checking capabilities before setting a post slug, ensure the correct post type capabilities are used.

Previously, only the publish_posts capability was checked. Now, the correct meta or primitive capability for the post type is used where appropriate.

Props peterwilsoncc

Fixes #42464

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/post.php

    r42343 r42380  
    33053305    }
    33063306
    3307     // Don't allow contributors to set the post slug for pending review posts.
    3308     if ( 'pending' == $post_status && ! current_user_can( 'publish_posts' ) ) {
     3307    /*
     3308     * Don't allow contributors to set the post slug for pending review posts.
     3309     *
     3310     * For new posts check the primitive capability, for updates check the meta capability.
     3311     */
     3312    $post_type_object = get_post_type_object( $post_type );
     3313
     3314    if ( ! $update && 'pending' === $post_status && ! current_user_can( $post_type_object->cap->publish_posts ) ) {
     3315        $post_name = '';
     3316    } elseif ( $update && 'pending' === $post_status && ! current_user_can( 'publish_post', $post_ID ) ) {
    33093317        $post_name = '';
    33103318    }
  • trunk/tests/phpunit/tests/post/wpInsertPost.php

    r42343 r42380  
    66class Tests_WPInsertPost extends WP_UnitTestCase {
    77
     8    protected static $user_ids = array(
     9        'administrator' => null,
     10        'contributor'   => null,
     11    );
     12
     13    static function wpSetUpBeforeClass( $factory ) {
     14        self::$user_ids = array(
     15            'administrator' => $factory->user->create( array(
     16                'role' => 'administrator',
     17            ) ),
     18            'contributor'   => $factory->user->create( array(
     19                'role' => 'contributor',
     20            ) ),
     21        );
     22
     23        $role = get_role( 'administrator' );
     24        $role->add_cap( 'publish_mapped_meta_caps' );
     25        $role->add_cap( 'publish_unmapped_meta_caps' );
     26    }
     27
     28    static function tearDownAfterClass() {
     29        $role = get_role( 'administrator' );
     30        $role->remove_cap( 'publish_mapped_meta_caps' );
     31        $role->remove_cap( 'publish_unmapped_meta_caps' );
     32
     33        parent::tearDownAfterClass();
     34    }
     35
     36    function setUp() {
     37        parent::setUp();
     38
     39        register_post_type( 'mapped_meta_caps', array(
     40            'capability_type' => array( 'mapped_meta_cap', 'mapped_meta_caps' ),
     41            'map_meta_cap'    => true,
     42        ) );
     43
     44        register_post_type( 'unmapped_meta_caps', array(
     45            'capability_type' => array( 'unmapped_meta_cap', 'unmapped_meta_caps' ),
     46            'map_meta_cap'    => false,
     47        ) );
     48
     49        register_post_type( 'no_admin_caps', array(
     50            'capability_type' => array( 'no_admin_cap', 'no_admin_caps' ),
     51            'map_meta_cap'    => false,
     52        ) );
     53    }
     54
    855    /**
    956     * @ticket 11863
     
    104151        $this->assertEquals( 'about-2', get_post( $about_page_id )->post_name );
    105152    }
     153
     154    /**
     155     * Data for testing the ability for users to set the post slug.
     156     *
     157     * @return array Array of test arguments.
     158     */
     159    function data_various_post_types() {
     160        return array(
     161            array(
     162                'mapped_meta_caps',
     163            ),
     164            array(
     165                'unmapped_meta_caps',
     166            ),
     167            array(
     168                'post',
     169            ),
     170        );
     171    }
     172
     173    /**
     174     * Test contributor making changes to the pending post slug.
     175     *
     176     * @ticket 42464
     177     * @dataProvider data_various_post_types
     178     */
     179    function test_contributor_cannot_set_post_slug( $post_type ) {
     180        wp_set_current_user( self::$user_ids['contributor'] );
     181
     182        $post_id = $this->factory()->post->create( array(
     183            'post_title'   => 'Jefferson claim: nice to have Washington on your side.',
     184            'post_content' => "I’m in the cabinet. I am complicit in watching him grabbin’ at power and kiss it.\n\nIf Washington isn’t gon’ listen to disciplined dissidents, this is the difference: this kid is out!",
     185            'post_type'    => $post_type,
     186            'post_name'    => 'new-washington',
     187            'post_status'  => 'pending',
     188        ) );
     189
     190        $expected = '';
     191        $actual = get_post_field( 'post_name', $post_id );
     192
     193        $this->assertSame( $expected, $actual );
     194
     195        // Now update the post.
     196        wp_update_post( array(
     197            'ID' => $post_id,
     198            'post_title' => 'Hamilton has Washington on side: Jefferson',
     199            'post_name'  => 'edited-washington',
     200        ) );
     201
     202        $expected = '';
     203        $actual = get_post_field( 'post_name', $post_id );
     204
     205        $this->assertSame( $expected, $actual );
     206    }
     207
     208    /**
     209     * Test administrator making changes to the pending post slug.
     210     *
     211     * @ticket 42464
     212     * @dataProvider data_various_post_types
     213     */
     214    function test_administrator_can_set_post_slug( $post_type ) {
     215        wp_set_current_user( self::$user_ids['administrator'] );
     216
     217        $post_id = $this->factory()->post->create( array(
     218            'post_title'   => 'What is the Conner Project?',
     219            'post_content' => "Evan Hansen’s last link to his friend Conner is a signature on his broken arm.",
     220            'post_type'    => $post_type,
     221            'post_name'    => 'dear-evan-hansen-explainer',
     222            'post_status'  => 'pending',
     223        ) );
     224
     225        $expected = 'dear-evan-hansen-explainer';
     226        $actual = get_post_field( 'post_name', $post_id );
     227
     228        $this->assertSame( $expected, $actual );
     229
     230        // Now update the post.
     231        wp_update_post( array(
     232            'ID' => $post_id,
     233            'post_title' => 'Conner Project to close',
     234            'post_name'  => 'dear-evan-hansen-spoiler',
     235        ) );
     236
     237        $expected = 'dear-evan-hansen-spoiler';
     238        $actual = get_post_field( 'post_name', $post_id );
     239
     240        $this->assertSame( $expected, $actual );
     241    }
     242
     243    /**
     244     * Test administrator making changes to a pending post slug for a post type they don't
     245     * have permission to publish.
     246     *
     247     * These assertions failed prior to ticket #42464.
     248     *
     249     * @ticket 42464
     250     */
     251    function test_administrator_cannot_set_post_slug_on_post_type_they_cannot_publish() {
     252        wp_set_current_user( self::$user_ids['administrator'] );
     253
     254        $post_id = $this->factory()->post->create( array(
     255            'post_title'   => 'Everything is legal in New Jersey',
     256            'post_content' => 'Shortly before his death, Philip Hamilton was heard to claim everything was legal in the garden state.',
     257            'post_type'    => 'no_admin_caps',
     258            'post_name'    => 'yet-another-duel',
     259            'post_status'  => 'pending',
     260        ) );
     261
     262        $expected = '';
     263        $actual = get_post_field( 'post_name', $post_id );
     264
     265        $this->assertSame( $expected, $actual );
     266
     267        // Now update the post.
     268        wp_update_post( array(
     269            'ID' => $post_id,
     270            'post_title' => 'Ten things illegal in New Jersey',
     271            'post_name'  => 'foreshadowing-in-nj',
     272        ) );
     273
     274        $expected = '';
     275        $actual = get_post_field( 'post_name', $post_id );
     276
     277        $this->assertSame( $expected, $actual );
     278    }
     279
    106280}
Note: See TracChangeset for help on using the changeset viewer.