Ticket #38303: 38303.diff
File 38303.diff, 17.9 KB (added by , 7 years ago) |
---|
-
src/wp-includes/capabilities.php
29 29 function map_meta_cap( $cap, $user_id ) { 30 30 $args = array_slice( func_get_args(), 2 ); 31 31 $caps = array(); 32 33 32 switch ( $cap ) { 34 33 case 'remove_user': 35 34 $caps[] = 'remove_users'; … … 51 50 $caps[] = 'edit_users'; // edit_user maps to edit_users. 52 51 } 53 52 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 54 91 case 'delete_post': 55 92 case 'delete_page': 56 93 $post = get_post( $args[0] ); … … 250 287 251 288 $post_type = get_post_type( $post ); 252 289 253 $caps = map_meta_cap( 'edit_post', $user_id, $post->ID );254 255 290 $meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false; 256 291 257 292 if ( $meta_key && ( has_filter( "auth_post_meta_{$meta_key}" ) || has_filter( "auth_post_{$post_type}_meta_{$meta_key}" ) ) ) { … … 293 328 $caps[] = $cap; 294 329 } elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) { 295 330 $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 ); 296 334 } 297 335 break; 298 336 case 'edit_comment': 299 337 $comment = get_comment( $args[0] ); 338 300 339 if ( ! $comment ) { 301 340 $caps[] = 'do_not_allow'; 302 341 break; … … 314 353 $caps = map_meta_cap( 'edit_posts', $user_id ); 315 354 } 316 355 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; 317 393 case 'unfiltered_upload': 318 394 if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) ) ) 319 395 $caps[] = $cap; … … 428 504 $caps = map_meta_cap( $tax->cap->$taxo_cap, $user_id, $term_id ); 429 505 430 506 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; 431 544 case 'manage_post_tags': 432 545 case 'edit_categories': 433 546 case 'edit_post_tags': -
src/wp-includes/meta.php
1038 1038 if ( empty( $args['auth_callback'] ) ) { 1039 1039 if ( is_protected_meta( $meta_key, $object_type ) ) { 1040 1040 $args['auth_callback'] = '__return_false'; 1041 } else { 1042 $args['auth_callback'] = '__return_true'; 1043 } 1041 } 1044 1042 } 1045 1043 1046 1044 // 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 */ 7 class 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
74 74 'description' => '', 75 75 'single' => false, 76 76 'sanitize_callback' => null, 77 'auth_callback' => '__return_true',77 'auth_callback' => null, 78 78 'show_in_rest' => false, 79 79 ), 80 80 ), … … 96 96 'description' => '', 97 97 'single' => false, 98 98 'sanitize_callback' => null, 99 'auth_callback' => '__return_true',99 'auth_callback' => null, 100 100 'show_in_rest' => false, 101 101 ), 102 102 ), … … 148 148 'description' => '', 149 149 'single' => false, 150 150 'sanitize_callback' => array( $this, '_new_sanitize_meta_cb' ), 151 'auth_callback' => '__return_true',151 'auth_callback' => null, 152 152 'show_in_rest' => false, 153 153 ), 154 154 ), -
tests/phpunit/tests/post/meta.php
237 237 $this->assertEquals($funky_meta, get_post_meta($this->post_id, 'test_funky_post_meta', true)); 238 238 239 239 } 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 } 240 308 } -
tests/phpunit/tests/term/meta.php
407 407 public static function set_cache_results( $q ) { 408 408 $q->set( 'cache_results', true ); 409 409 } 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 } 410 478 } -
tests/phpunit/tests/user/capabilities.php
406 406 $expected['remove_user'], 407 407 $expected['promote_user'], 408 408 $expected['edit_user'], 409 $expected['edit_user_meta'], 410 $expected['delete_user_meta'], 411 $expected['add_user_meta'], 409 412 $expected['delete_post'], 410 413 $expected['delete_page'], 411 414 $expected['edit_post'], … … 417 420 $expected['delete_post_meta'], 418 421 $expected['add_post_meta'], 419 422 $expected['edit_comment'], 423 $expected['edit_comment_meta'], 424 $expected['delete_comment_meta'], 425 $expected['add_comment_meta'], 420 426 $expected['edit_term'], 421 427 $expected['delete_term'], 422 428 $expected['assign_term'], 429 $expected['edit_term_meta'], 430 $expected['delete_term_meta'], 431 $expected['add_term_meta'], 423 432 $expected['delete_user'] 424 433 ); 425 434 -
tests/phpunit/tests/user/editUserMeta.php
1 <?php 2 3 /** 4 * @group user 5 * @group meta 6 */ 7 class 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 }