Make WordPress Core


Ignore:
Timestamp:
07/11/2018 09:20:10 AM (7 years ago)
Author:
pento
Message:

REST API: Declare user capabilities using JSON Hyper Schema's "targetSchema".

There are a variety of operations a WordPress user can only perform if they have the correct capabilities. A REST API client should only display UI for one of these operations if the WordPress user can perform the operation.

Rather than requiring REST API clients to calculate whether to display UI based on potentially complicated combinations of user capabilities, targetSchema allows us to expose a single flag to show whether the corresponding UI should be displayed.

This change also includes flags on post objects for the following actions:

  • action-publish: The current user can publish this post.
  • action-sticky: The current user can make this post sticky, and the post type supports sticking.
  • `action-assign-author': The current user can change the author on this post.
  • action-assign-{$taxonomy}: The current user can assign terms from the "$taxonomy" taxonomy to this post.
  • action-create-{$taxonomy}: The current user can create terms int the "$taxonomy" taxonomy.

Merges [43437] to the 4.9 branch.

Props TimothyBlynJacobs, danielbachhuber.
Fixes #44287.

Location:
branches/4.9
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/4.9

  • branches/4.9/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r43072 r43438  
    32473247    }
    32483248
     3249    public function test_publish_action_ldo_registered() {
     3250
     3251        $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3252        $data     = $response->get_data();
     3253        $schema   = $data['schema'];
     3254
     3255        $this->assertArrayHasKey( 'links', $schema );
     3256        $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-publish' ) );
     3257
     3258        $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3259    }
     3260
     3261    public function test_sticky_action_ldo_registered_for_posts() {
     3262
     3263        $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3264        $data     = $response->get_data();
     3265        $schema   = $data['schema'];
     3266
     3267        $this->assertArrayHasKey( 'links', $schema );
     3268        $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-sticky' ) );
     3269
     3270        $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3271    }
     3272
     3273    public function test_sticky_action_ldo_not_registered_for_non_posts() {
     3274
     3275        $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/pages' ) );
     3276        $data     = $response->get_data();
     3277        $schema   = $data['schema'];
     3278
     3279        $this->assertArrayHasKey( 'links', $schema );
     3280        $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-sticky' ) );
     3281
     3282        $this->assertCount( 0, $publish, 'LDO found on schema.' );
     3283    }
     3284
     3285    public function test_author_action_ldo_registered_for_post_types_with_author_support() {
     3286
     3287        $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3288        $data     = $response->get_data();
     3289        $schema   = $data['schema'];
     3290
     3291        $this->assertArrayHasKey( 'links', $schema );
     3292        $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-assign-author' ) );
     3293
     3294        $this->assertCount( 1, $publish, 'LDO found on schema.' );
     3295    }
     3296
     3297    public function test_author_action_ldo_not_registered_for_post_types_without_author_support() {
     3298
     3299        remove_post_type_support( 'post', 'author' );
     3300
     3301        $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3302        $data     = $response->get_data();
     3303        $schema   = $data['schema'];
     3304
     3305        $this->assertArrayHasKey( 'links', $schema );
     3306        $publish = wp_list_filter( $schema['links'], array( 'rel' => 'https://api.w.org/action-assign-author' ) );
     3307
     3308        $this->assertCount( 0, $publish, 'LDO found on schema.' );
     3309    }
     3310
     3311    public function test_term_action_ldos_registered() {
     3312
     3313        $response = rest_get_server()->dispatch( new WP_REST_Request( 'OPTIONS', '/wp/v2/posts' ) );
     3314        $data     = $response->get_data();
     3315        $schema   = $data['schema'];
     3316
     3317        $this->assertArrayHasKey( 'links', $schema );
     3318        $rels = array_flip( wp_list_pluck( $schema['links'], 'rel' ) );
     3319
     3320        $this->assertArrayHasKey( 'https://api.w.org/action-assign-categories', $rels );
     3321        $this->assertArrayHasKey( 'https://api.w.org/action-create-categories', $rels );
     3322        $this->assertArrayHasKey( 'https://api.w.org/action-assign-tags', $rels );
     3323        $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $rels );
     3324
     3325        $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-post_format', $rels );
     3326        $this->assertArrayNotHasKey( 'https://api.w.org/action-create-post_format', $rels );
     3327        $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-nav_menu', $rels );
     3328        $this->assertArrayNotHasKey( 'https://api.w.org/action-create-nav_menu', $rels );
     3329    }
     3330
     3331    public function test_action_links_only_available_in_edit_context() {
     3332
     3333        wp_set_current_user( self::$author_id );
     3334
     3335        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3336        $this->assertGreaterThan( 0, $post );
     3337
     3338        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3339        $request->set_query_params( array( 'context' => 'view' ) );
     3340
     3341        $response = rest_get_server()->dispatch( $request );
     3342        $links    = $response->get_links();
     3343
     3344        $this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
     3345    }
     3346
     3347    public function test_publish_action_link_exists_for_author() {
     3348
     3349        wp_set_current_user( self::$author_id );
     3350
     3351        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3352        $this->assertGreaterThan( 0, $post );
     3353
     3354        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3355        $request->set_query_params( array( 'context' => 'edit' ) );
     3356
     3357        $response = rest_get_server()->dispatch( $request );
     3358        $links    = $response->get_links();
     3359
     3360        $this->assertArrayHasKey( 'https://api.w.org/action-publish', $links );
     3361    }
     3362
     3363    public function test_publish_action_link_does_not_exist_for_contributor() {
     3364
     3365        wp_set_current_user( self::$contributor_id );
     3366
     3367        $post = self::factory()->post->create( array( 'post_author' => self::$contributor_id ) );
     3368        $this->assertGreaterThan( 0, $post );
     3369
     3370        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3371        $request->set_query_params( array( 'context' => 'edit' ) );
     3372
     3373        $response = rest_get_server()->dispatch( $request );
     3374        $links    = $response->get_links();
     3375
     3376        $this->assertArrayNotHasKey( 'https://api.w.org/action-publish', $links );
     3377    }
     3378
     3379    public function test_sticky_action_exists_for_editor() {
     3380
     3381        wp_set_current_user( self::$editor_id );
     3382
     3383        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3384        $this->assertGreaterThan( 0, $post );
     3385
     3386        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3387        $request->set_query_params( array( 'context' => 'edit' ) );
     3388
     3389        $response = rest_get_server()->dispatch( $request );
     3390        $links    = $response->get_links();
     3391
     3392        $this->assertArrayHasKey( 'https://api.w.org/action-sticky', $links );
     3393    }
     3394
     3395    public function test_sticky_action_does_not_exist_for_author() {
     3396
     3397        wp_set_current_user( self::$author_id );
     3398
     3399        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3400        $this->assertGreaterThan( 0, $post );
     3401
     3402        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3403        $request->set_query_params( array( 'context' => 'edit' ) );
     3404
     3405        $response = rest_get_server()->dispatch( $request );
     3406        $links    = $response->get_links();
     3407
     3408        $this->assertArrayNotHasKey( 'https://api.w.org/action-sticky', $links );
     3409    }
     3410
     3411    public function test_sticky_action_does_not_exist_for_non_post_posts() {
     3412
     3413        wp_set_current_user( self::$editor_id );
     3414
     3415        $post = self::factory()->post->create(
     3416            array(
     3417                'post_author' => self::$author_id,
     3418                'post_type'   => 'page',
     3419            )
     3420        );
     3421        $this->assertGreaterThan( 0, $post );
     3422
     3423        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3424        $request->set_query_params( array( 'context' => 'edit' ) );
     3425
     3426        $response = rest_get_server()->dispatch( $request );
     3427        $links    = $response->get_links();
     3428
     3429        $this->assertArrayNotHasKey( 'https://api.w.org/action-sticky', $links );
     3430    }
     3431
     3432
     3433    public function test_assign_author_action_exists_for_editor() {
     3434
     3435        wp_set_current_user( self::$editor_id );
     3436
     3437        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3438        $this->assertGreaterThan( 0, $post );
     3439
     3440        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3441        $request->set_query_params( array( 'context' => 'edit' ) );
     3442
     3443        $response = rest_get_server()->dispatch( $request );
     3444        $links    = $response->get_links();
     3445
     3446        $this->assertArrayHasKey( 'https://api.w.org/action-assign-author', $links );
     3447    }
     3448
     3449    public function test_assign_author_action_does_not_exist_for_author() {
     3450
     3451        wp_set_current_user( self::$author_id );
     3452
     3453        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3454        $this->assertGreaterThan( 0, $post );
     3455
     3456        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3457        $request->set_query_params( array( 'context' => 'edit' ) );
     3458
     3459        $response = rest_get_server()->dispatch( $request );
     3460        $links    = $response->get_links();
     3461
     3462        $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-author', $links );
     3463    }
     3464
     3465    public function test_assign_author_action_does_not_exist_for_post_types_without_author_support() {
     3466
     3467        remove_post_type_support( 'post', 'author' );
     3468
     3469        wp_set_current_user( self::$editor_id );
     3470
     3471        $post = self::factory()->post->create();
     3472        $this->assertGreaterThan( 0, $post );
     3473
     3474        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3475        $request->set_query_params( array( 'context' => 'edit' ) );
     3476
     3477        $response = rest_get_server()->dispatch( $request );
     3478        $links    = $response->get_links();
     3479
     3480        $this->assertArrayNotHasKey( 'https://api.w.org/action-assign-author', $links );
     3481    }
     3482
     3483    public function test_create_term_action_exists_for_editor() {
     3484
     3485        wp_set_current_user( self::$editor_id );
     3486
     3487        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3488        $this->assertGreaterThan( 0, $post );
     3489
     3490        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3491        $request->set_query_params( array( 'context' => 'edit' ) );
     3492
     3493        $response = rest_get_server()->dispatch( $request );
     3494        $links    = $response->get_links();
     3495
     3496        $this->assertArrayHasKey( 'https://api.w.org/action-create-categories', $links );
     3497        $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $links );
     3498        $this->assertArrayNotHasKey( 'https://api.w.org/action-create-post_format', $links );
     3499    }
     3500
     3501    public function test_create_term_action_non_hierarchical_exists_for_author() {
     3502
     3503        wp_set_current_user( self::$author_id );
     3504
     3505        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3506        $this->assertGreaterThan( 0, $post );
     3507
     3508        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3509        $request->set_query_params( array( 'context' => 'edit' ) );
     3510
     3511        $response = rest_get_server()->dispatch( $request );
     3512        $links    = $response->get_links();
     3513
     3514        $this->assertArrayHasKey( 'https://api.w.org/action-create-tags', $links );
     3515    }
     3516
     3517    public function test_create_term_action_hierarchical_does_not_exists_for_author() {
     3518
     3519        wp_set_current_user( self::$author_id );
     3520
     3521        $post = self::factory()->post->create( array( 'post_author' => self::$author_id ) );
     3522        $this->assertGreaterThan( 0, $post );
     3523
     3524        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3525        $request->set_query_params( array( 'context' => 'edit' ) );
     3526
     3527        $response = rest_get_server()->dispatch( $request );
     3528        $links    = $response->get_links();
     3529
     3530        $this->assertArrayNotHasKey( 'https://api.w.org/action-create-categories', $links );
     3531    }
     3532
     3533    public function test_assign_term_action_exists_for_contributor() {
     3534
     3535        wp_set_current_user( self::$contributor_id );
     3536
     3537        $post = self::factory()->post->create(
     3538            array(
     3539                'post_author' => self::$contributor_id,
     3540                'post_status' => 'draft',
     3541            )
     3542        );
     3543        $this->assertGreaterThan( 0, $post );
     3544
     3545        $request = new WP_REST_Request( 'GET', "/wp/v2/posts/{$post}" );
     3546        $request->set_query_params( array( 'context' => 'edit' ) );
     3547
     3548        $response = rest_get_server()->dispatch( $request );
     3549        $links    = $response->get_links();
     3550
     3551        $this->assertArrayHasKey( 'https://api.w.org/action-assign-categories', $links );
     3552        $this->assertArrayHasKey( 'https://api.w.org/action-assign-tags', $links );
     3553    }
     3554
    32493555    public function tearDown() {
    32503556        _unregister_post_type( 'youseeeme' );
Note: See TracChangeset for help on using the changeset viewer.