WordPress.org

Make WordPress Core

Ticket #38303: 38303.diff

File 38303.diff, 17.9 KB (added by tharsheblows, 4 years ago)

add capabilities used in register_meta() with tests

  • src/wp-includes/capabilities.php

     
    2929function map_meta_cap( $cap, $user_id ) {
    3030        $args = array_slice( func_get_args(), 2 );
    3131        $caps = array();
    32 
    3332        switch ( $cap ) {
    3433        case 'remove_user':
    3534                $caps[] = 'remove_users';
     
    5150                        $caps[] = 'edit_users'; // edit_user maps to edit_users.
    5251                }
    5352                break;
     53        case 'edit_user_meta':
     54        case 'delete_user_meta':
     55        case 'add_user_meta':
     56                $user = get_user_by( 'id', $args[0] );
     57                if( ! $user ){
     58                        $caps[] = 'do_not_allow';
     59                        break;
     60                }
     61
     62                $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false;
     63
     64                if ( $meta_key && ( has_filter( "auth_user_meta_{$meta_key}" ) ) ) {
     65                        /**
     66                         * Filters whether the user is allowed to add user meta to a user.
     67                         *
     68                         * The dynamic portion of the hook name, `$meta_key`, refers to the
     69                         * meta key passed to map_meta_cap().
     70                         *
     71                         * @since 4.7.0
     72                         *
     73                         * @param bool   $allowed  Whether the user can add the user meta. Default false.
     74                         * @param string $meta_key The meta key.
     75                         * @param int    $user->ID The user being edited.
     76                         * @param int    $user_id  User ID.
     77                         * @param string $cap      Capability name.
     78                         * @param array  $caps     User capabilities.
     79                         */
     80                        $allowed = apply_filters( "auth_user_meta_{$meta_key}", false, $meta_key, $user->ID, $user_id, $cap, $caps );
     81       
     82                        if ( ! $allowed ){
     83                                $caps[] = $cap;
     84                        }
     85                } else {
     86                        // If there is no auth_callback registered, anyone who can edit the post can edit the post's metadata.
     87                        $caps = map_meta_cap( 'edit_user', $user_id, $user->ID );
     88                }
     89                break;
     90
    5491        case 'delete_post':
    5592        case 'delete_page':
    5693                $post = get_post( $args[0] );
     
    250287
    251288                $post_type = get_post_type( $post );
    252289
    253                 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
    254 
    255290                $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false;
    256291
    257292                if ( $meta_key && ( has_filter( "auth_post_meta_{$meta_key}" ) || has_filter( "auth_post_{$post_type}_meta_{$meta_key}" ) ) ) {
     
    293328                                $caps[] = $cap;
    294329                } elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) {
    295330                        $caps[] = $cap;
     331                } else {
     332                        // If there is no auth_callback registered, anyone who can edit the post can edit the post's metadata.
     333                        $caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
    296334                }
    297335                break;
    298336        case 'edit_comment':
    299337                $comment = get_comment( $args[0] );
     338
    300339                if ( ! $comment ) {
    301340                        $caps[] = 'do_not_allow';
    302341                        break;
     
    314353                        $caps = map_meta_cap( 'edit_posts', $user_id );
    315354                }
    316355                break;
     356        case 'edit_comment_meta':
     357        case 'delete_comment_meta':
     358        case 'add_comment_meta':
     359                $comment = get_comment( $args[0] );
     360                if ( ! $comment ) {
     361                        $caps[] = 'do_not_allow';
     362                        break;
     363                }
     364               
     365                $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false;
     366
     367                if ( $meta_key && ( has_filter( "auth_comment_meta_{$meta_key}" ) ) ) {
     368                        /**
     369                         * Filters whether the user is allowed to add comment meta to a comment.
     370                         *
     371                         * The dynamic portion of the hook name, `$meta_key`, refers to the
     372                         * meta key passed to map_meta_cap().
     373                         *
     374                         * @since 4.7.0
     375                         *
     376                         * @param bool   $allowed  Whether the user can add the comment meta. Default false.
     377                         * @param string $meta_key The meta key.
     378                         * @param int    $comment_id  Comment ID.
     379                         * @param int    $user_id  User ID.
     380                         * @param string $cap      Capability name.
     381                         * @param array  $caps     User capabilities.
     382                         */
     383                        $allowed = apply_filters( "auth_comment_meta_{$meta_key}", false, $meta_key, $comment->comment_post_ID, $user_id, $cap, $caps );
     384       
     385                        if ( ! $allowed ){
     386                                $caps[] = $cap;
     387                        }
     388                } else {
     389                        // If there is no auth_callback registered, anyone who can edit the comment can edit the comment's metadata.
     390                        $caps = map_meta_cap( 'edit_comment', $user_id, $comment->comment_ID );
     391                }
     392                break;
    317393        case 'unfiltered_upload':
    318394                if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) )  )
    319395                        $caps[] = $cap;
     
    428504                $caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id );
    429505
    430506                break;
     507        case 'edit_term_meta':
     508        case 'delete_term_meta':
     509        case 'add_term_meta':
     510                $term_id = $args[0];
     511                $term = get_term( $term_id );
     512                if ( ! $term || is_wp_error( $term ) ) {
     513                        $caps[] = 'do_not_allow';
     514                        break;
     515                }
     516
     517                $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false;
     518
     519                if ( $meta_key && ( has_filter( "auth_term_meta_{$meta_key}" ) ) ) {
     520                        /**
     521                         * Filters whether the user is allowed to add term meta to a term.
     522                         *
     523                         * The dynamic portion of the hook name, `$meta_key`, refers to the
     524                         * meta key passed to map_meta_cap().
     525                         *
     526                         * @since 4.7.0
     527                         *
     528                         * @param bool   $allowed  Whether the user can add the term meta. Default false.
     529                         * @param string $meta_key The meta key.
     530                         * @param int    $term_id  Term ID.
     531                         * @param int    $user_id  User ID.
     532                         * @param string $cap      Capability name.
     533                         * @param array  $caps     User capabilities.
     534                         */
     535                        $allowed = apply_filters( "auth_term_meta_{$meta_key}", false, $meta_key, $term_id, $user_id, $cap, $caps );
     536                        if ( ! $allowed ){
     537                                $caps[] = $cap;
     538                        }
     539                } else {
     540                        // If there is no auth_callback registered, anyone who can edit the term can edit the term's metadata.
     541                        $caps = map_meta_cap( 'edit_term', $user_id, $term_id );
     542                }
     543                break;
    431544        case 'manage_post_tags':
    432545        case 'edit_categories':
    433546        case 'edit_post_tags':
  • src/wp-includes/meta.php

     
    10381038        if ( empty( $args['auth_callback'] ) ) {
    10391039                if ( is_protected_meta( $meta_key, $object_type ) ) {
    10401040                        $args['auth_callback'] = '__return_false';
    1041                 } else {
    1042                         $args['auth_callback'] = '__return_true';
    1043                 }
     1041                }
    10441042        }
    10451043
    10461044        // Back-compat: old sanitize and auth callbacks are applied to all of an object type.
  • tests/phpunit/tests/comment/editCommentMeta.php

     
     1<?php
     2
     3/**
     4 * @group comment
     5 * @group meta
     6 */
     7class Tests_Edit_Comment_Meta extends WP_UnitTestCase {
     8
     9        public function test_edit_comment_meta_cap(){
     10
     11                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     12                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     13                $p = self::factory()->post->create( array( 'post_status' => 'publish' ) );
     14                $c_id = self::factory()->comment->create_post_comments( $p );
     15               
     16                register_meta( 'comment', 'flag', array() );
     17
     18                wp_set_current_user( $u1 );
     19                $admin_update = false;
     20                if( current_user_can( 'edit_comment_meta', $c_id[0], 'flag' ) ){
     21                        $admin_update = update_comment_meta( $c_id[0], 'flag', 'yes' );
     22                }
     23                $this->assertNotEmpty( $admin_update );
     24
     25                wp_set_current_user( $u2 );
     26                $auth_update = false;
     27                if( current_user_can( 'edit_comment_meta', $c_id[0], 'flag' ) ){
     28                        $auth_update = update_comment_meta( $c_id[0], 'flag', 'no' );
     29                }
     30                $this->assertFalse( $auth_update );
     31
     32                unregister_meta_key( 'comment', 'flag' );
     33
     34        }
     35
     36        public function test_edit_comment_meta_with_auth_callback(){
     37
     38                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     39                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     40                $p = self::factory()->post->create( array( 'post_status' => 'publish' ) );
     41                $c_id = self::factory()->comment->create_post_comments( $p, 1 );
     42
     43                $args1 = array(
     44                        'auth_callback' => array( $this, 'test_edit_comment_meta_auth_callback_false' )
     45                );
     46
     47                $args2 = array(
     48                        'auth_callback' => array( $this, 'test_edit_comment_meta_auth_callback_true' )
     49                );
     50
     51                register_meta( 'comment', 'worthy', $args1 );
     52                register_meta( 'comment', 'notworthy', $args2 );
     53
     54                wp_set_current_user( $u1 );
     55                $admin_update = false;
     56                if( current_user_can( 'edit_comment_meta', $c_id[0], 'worthy' ) ){
     57                        $admin_update = update_comment_meta( $c_id[0], 'worthy', 'no' );
     58                }
     59                $this->assertFalse( $admin_update );
     60
     61                wp_set_current_user( $u2 );
     62                $auth_update = false;
     63                if( current_user_can( 'edit_comment_meta', $c_id[0], 'notworthy' ) ){
     64                        $auth_update = update_comment_meta( $c_id[0], 'notworthy', 'no' );
     65                }
     66                $this->assertNotEmpty( $auth_update );
     67
     68                unregister_meta_key( 'comment', 'worthy' );
     69                unregister_meta_key( 'comment', 'notworthy' );
     70
     71        }
     72
     73        public function test_edit_comment_meta_auth_callback_false(){
     74                return false;
     75        }
     76
     77        public function test_edit_comment_meta_auth_callback_true(){
     78                return true;
     79        }
     80}
  • tests/phpunit/tests/meta/registerMeta.php

     
    7474                                        'description' => '',
    7575                                        'single' => false,
    7676                                        'sanitize_callback' => null,
    77                                         'auth_callback' => '__return_true',
     77                                        'auth_callback' => null,
    7878                                        'show_in_rest' => false,
    7979                                ),
    8080                        ),
     
    9696                                        'description' => '',
    9797                                        'single' => false,
    9898                                        'sanitize_callback' => null,
    99                                         'auth_callback' => '__return_true',
     99                                        'auth_callback' => null,
    100100                                        'show_in_rest' => false,
    101101                                ),
    102102                        ),
     
    148148                                        'description' => '',
    149149                                        'single' => false,
    150150                                        'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ),
    151                                         'auth_callback' => '__return_true',
     151                                        'auth_callback' => null,
    152152                                        'show_in_rest' => false,
    153153                                ),
    154154                        ),
  • tests/phpunit/tests/post/meta.php

     
    237237                $this->assertEquals($funky_meta, get_post_meta($this->post_id, 'test_funky_post_meta', true));
    238238
    239239        }
     240
     241        public function test_edit_term_meta_cap(){
     242                $p = self::factory()->post->create( array( 'post_status' => 'publish' ) );
     243                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     244                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     245
     246                register_meta( 'post', 'foo', array() );
     247
     248                wp_set_current_user( $u1 );
     249                $admin_update = false;
     250                if( current_user_can( 'edit_post_meta', $p, 'foo' ) ){
     251                        $admin_update = update_term_meta( $p, 'foo', 'bar1' );
     252                }
     253                $this->assertNotEmpty( $admin_update );
     254
     255                wp_set_current_user( $u2 );
     256                $auth_update = false;
     257                if( current_user_can( 'edit_post_meta', $p, 'foo' ) ){
     258                        $auth_update = update_term_meta( $p, 'foo', 'bar2' );
     259                }
     260                $this->assertFalse( $auth_update );
     261
     262                unregister_meta_key( 'post', 'foo' );
     263
     264        }
     265
     266        public function test_edit_post_meta_with_auth_callback(){
     267                $p = self::factory()->post->create( array( 'post_status' => 'publish' ) );
     268                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     269                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     270
     271                $args1 = array(
     272                        'auth_callback' => array( $this, 'test_edit_post_meta_auth_callback_false' )
     273                );
     274
     275                $args2 = array(
     276                        'auth_callback' => array( $this, 'test_edit_post_meta_auth_callback_true' )
     277                );
     278
     279                register_meta( 'post', 'foo1', $args1 );
     280                register_meta( 'post', 'foo2', $args2 );
     281
     282                wp_set_current_user( $u1 );
     283                $admin_update = false;
     284                if( current_user_can( 'edit_post_meta', $p, 'foo1' ) ){
     285                        $admin_update = update_term_meta( $p, 'foo1', 'bar1' );
     286                }
     287                $this->assertFalse( $admin_update );
     288
     289                wp_set_current_user( $u2 );
     290                $auth_update = false;
     291                if( current_user_can( 'edit_post_meta', $p, 'foo2' ) ){
     292                        $auth_update = update_term_meta( $p, 'foo2', 'bar2' );
     293                }
     294                $this->assertNotEmpty( $auth_update );
     295
     296                unregister_meta_key( 'post', 'foo1' );
     297                unregister_meta_key( 'post', 'foo2' );
     298
     299        }
     300
     301        public function test_edit_post_meta_auth_callback_false(){
     302                return false;
     303        }
     304
     305        public function test_edit_post_meta_auth_callback_true(){
     306                return true;
     307        }
    240308}
  • tests/phpunit/tests/term/meta.php

     
    407407        public static function set_cache_results( $q ) {
    408408                $q->set( 'cache_results', true );
    409409        }
     410
     411        public function test_edit_term_meta_cap(){
     412                $t      = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     413                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     414                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     415
     416                register_meta( 'term', 'foo', array() );
     417
     418                wp_set_current_user( $u1 );
     419                $admin_update = false;
     420                if( current_user_can( 'edit_term_meta', $t, 'foo' ) ){
     421                        $admin_update = update_term_meta( $t, 'foo', 'bar1' );
     422                }
     423                $this->assertNotEmpty( $admin_update );
     424
     425                wp_set_current_user( $u2 );
     426                $auth_update = false;
     427                if( current_user_can( 'edit_term_meta', $t, 'foo' ) ){
     428                        $auth_update = update_term_meta( $t, 'foo', 'bar2' );
     429                }
     430                $this->assertFalse( $auth_update );
     431
     432                unregister_meta_key( 'term', 'foo' );
     433
     434        }
     435
     436        public function test_edit_term_meta_with_auth_callback(){
     437                $t      = self::factory()->term->create( array( 'taxonomy' => 'wptests_tax' ) );
     438                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     439                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     440
     441                $args1 = array(
     442                        'auth_callback' => array( $this, 'test_edit_term_meta_auth_callback_false' )
     443                );
     444
     445                $args2 = array(
     446                        'auth_callback' => array( $this, 'test_edit_term_meta_auth_callback_true' )
     447                );
     448
     449                register_meta( 'term', 'foo1', $args1 );
     450                register_meta( 'term', 'foo2', $args2 );
     451
     452                wp_set_current_user( $u1 );
     453                $admin_update = false;
     454                if( current_user_can( 'edit_term_meta', $t, 'foo1' ) ){
     455                        $admin_update = update_term_meta( $t, 'foo1', 'bar1' );
     456                }
     457                $this->assertFalse( $admin_update );
     458
     459                wp_set_current_user( $u2 );
     460                $auth_update = false;
     461                if( current_user_can( 'edit_term_meta', $t, 'foo2' ) ){
     462                        $auth_update = update_term_meta( $t, 'foo2', 'bar2' );
     463                }
     464                $this->assertNotEmpty( $auth_update );
     465               
     466                unregister_meta_key( 'term', 'foo1' );
     467                unregister_meta_key( 'term', 'foo2' );
     468
     469        }
     470
     471        public function test_edit_term_meta_auth_callback_false(){
     472                return false;
     473        }
     474
     475        public function test_edit_term_meta_auth_callback_true(){
     476                return true;
     477        }
    410478}
  • tests/phpunit/tests/user/capabilities.php

     
    406406                        $expected['remove_user'],
    407407                        $expected['promote_user'],
    408408                        $expected['edit_user'],
     409                        $expected['edit_user_meta'],
     410                        $expected['delete_user_meta'],
     411                        $expected['add_user_meta'],                     
    409412                        $expected['delete_post'],
    410413                        $expected['delete_page'],
    411414                        $expected['edit_post'],
     
    417420                        $expected['delete_post_meta'],
    418421                        $expected['add_post_meta'],
    419422                        $expected['edit_comment'],
     423                        $expected['edit_comment_meta'],
     424                        $expected['delete_comment_meta'],
     425                        $expected['add_comment_meta'],
    420426                        $expected['edit_term'],
    421427                        $expected['delete_term'],
    422428                        $expected['assign_term'],
     429                        $expected['edit_term_meta'],
     430                        $expected['delete_term_meta'],
     431                        $expected['add_term_meta'],                     
    423432                        $expected['delete_user']
    424433                );
    425434
  • tests/phpunit/tests/user/editUserMeta.php

     
     1<?php
     2
     3/**
     4 * @group user
     5 * @group meta
     6 */
     7class Tests_Edit_User_Meta extends WP_UnitTestCase {
     8
     9        public function test_edit_user_meta_cap(){
     10
     11                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     12                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     13                $u_edit = self::factory()->user->create( array( 'role' => 'author' ) );
     14
     15                register_meta( 'user', 'spammer', array() );
     16
     17                wp_set_current_user( $u1 );
     18                $admin_update = false;
     19                if( current_user_can( 'edit_user_meta', $u_edit, 'spammer' ) ){
     20                        $admin_update = update_user_meta( $u_edit, 'spammer', 'yes' );
     21                }
     22                $this->assertNotEmpty( $admin_update );
     23
     24                wp_set_current_user( $u2 );
     25                $auth_update = false;
     26                if( current_user_can( 'edit_user_meta', $u_edit, 'spammer' ) ){
     27                        $auth_update = update_user_meta( $u_edit, 'spammer', 'no' );
     28                }
     29                $this->assertFalse( $auth_update );
     30
     31                unregister_meta_key( 'user', 'spammer' );
     32
     33        }
     34
     35        public function test_edit_user_meta_with_auth_callback(){
     36
     37                $u1 = self::factory()->user->create( array( 'role' => 'administrator' ) );
     38                $u2 = self::factory()->user->create( array( 'role' => 'author' ) );
     39                $u_edit = self::factory()->user->create( array( 'role' => 'author' ) );
     40
     41                $args1 = array(
     42                        'auth_callback' => array( $this, 'test_edit_user_meta_auth_callback_false' )
     43                );
     44
     45                $args2 = array(
     46                        'auth_callback' => array( $this, 'test_edit_user_meta_auth_callback_true' )
     47                );
     48
     49                register_meta( 'user', 'flagged', $args1 );
     50                register_meta( 'user', 'alright', $args2 );
     51
     52                wp_set_current_user( $u1 );
     53                $admin_update = false;
     54                if( current_user_can( 'edit_user_meta', $u_edit, 'flagged' ) ){
     55                        $admin_update = update_user_meta( $u_edit, 'flagged', 'no' );
     56                }
     57                $this->assertFalse( $admin_update );
     58
     59                wp_set_current_user( $u2 );
     60                $auth_update = false;
     61                if( current_user_can( 'edit_user_meta', $u_edit, 'alright' ) ){
     62                        $auth_update = update_user_meta( $u_edit, 'alright', 'no' );
     63                }
     64                $this->assertNotEmpty( $auth_update );
     65
     66                unregister_meta_key( 'user', 'flagged' );
     67                unregister_meta_key( 'user', 'alright' );
     68
     69        }
     70
     71        public function test_edit_user_meta_auth_callback_false(){
     72                return false;
     73        }
     74
     75        public function test_edit_user_meta_auth_callback_true(){
     76                return true;
     77        }
     78}