Skip to content

Commit

Permalink
REST: Restore WP_REST_Blocks_Controller for permissions check
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Oct 19, 2018
1 parent e681848 commit e3b1279
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 11 deletions.
36 changes: 36 additions & 0 deletions lib/class-wp-rest-blocks-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* Reusable blocks REST API: WP_REST_Blocks_Controller class
*
* @package gutenberg
* @since 0.10.0
*/

/**
* Controller which provides a REST endpoint for Gutenberg to read, create,
* edit and delete reusable blocks. Blocks are stored as posts with the wp_block
* post type.
*
* @since 0.10.0
*
* @see WP_REST_Controller
*/
class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller {
/**
* Checks if a block can be read.
*
* @since 2.1.0
*
* @param object $post Post object that backs the block.
* @return bool Whether the block can be read.
*/
public function check_read_permission( $post ) {
// Ensure that the user is logged in and has the read_blocks capability.
$post_type = get_post_type_object( $post->post_type );
if ( ! current_user_can( $post_type->cap->read_post, $post->ID ) ) {
return false;
}

return parent::check_read_permission( $post );
}
}
3 changes: 3 additions & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
// These files only need to be loaded if within a rest server instance
// which this class will exist if that is the case.
if ( class_exists( 'WP_REST_Controller' ) ) {
if ( ! class_exists( 'WP_REST_Blocks_Controller' ) ) {
require dirname( __FILE__ ) . '/class-wp-rest-blocks-controller.php';
}
if ( ! class_exists( 'WP_REST_Autosaves_Controller' ) ) {
require dirname( __FILE__ ) . '/class-wp-rest-autosaves-controller.php';
}
Expand Down
23 changes: 12 additions & 11 deletions lib/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -439,24 +439,25 @@ function gutenberg_register_post_types() {
register_post_type(
'wp_block',
array(
'labels' => array(
'labels' => array(
'name' => __( 'Blocks', 'gutenberg' ),
'singular_name' => __( 'Block', 'gutenberg' ),
'search_items' => __( 'Search Blocks', 'gutenberg' ),
),
'public' => false,
'show_ui' => true,
'show_in_menu' => false,
'rewrite' => false,
'show_in_rest' => true,
'rest_base' => 'blocks',
'capability_type' => 'block',
'capabilities' => array(
'public' => false,
'show_ui' => true,
'show_in_menu' => false,
'rewrite' => false,
'show_in_rest' => true,
'rest_base' => 'blocks',
'rest_controller_class' => 'WP_REST_Blocks_Controller',
'capability_type' => 'block',
'capabilities' => array(
'read' => 'read_blocks',
'create_posts' => 'create_blocks',
),
'map_meta_cap' => true,
'supports' => array(
'map_meta_cap' => true,
'supports' => array(
'title',
'editor',
),
Expand Down
179 changes: 179 additions & 0 deletions phpunit/class-rest-blocks-controller-test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<?php
/**
* WP_REST_Blocks_Controller tests
*
* @package gutenberg
*/

/**
* Tests for WP_REST_Blocks_Controller.
*/
class REST_Blocks_Controller_Test extends WP_UnitTestCase {

/**
* Our fake block's post ID.
*
* @var int
*/
protected static $post_id;

/**
* Our fake user's ID.
*
* @var int
*/
protected static $user_id;

/**
* Create fake data before our tests run.
*
* @param WP_UnitTest_Factory $factory Helper that lets us create fake data.
*/
public static function wpSetUpBeforeClass( $factory ) {
self::$post_id = wp_insert_post(
array(
'post_type' => 'wp_block',
'post_status' => 'publish',
'post_title' => 'My cool block',
'post_content' => '<!-- wp:core/paragraph --><p>Hello!</p><!-- /wp:core/paragraph -->',
)
);

self::$user_id = $factory->user->create(
array(
'role' => 'editor',
)
);
}

/**
* Delete our fake data after our tests run.
*/
public static function wpTearDownAfterClass() {
wp_delete_post( self::$post_id );

self::delete_user( self::$user_id );
}

/**
* Test cases for test_capabilities().
*/
public function data_capabilities() {
return array(
array( 'create', 'editor', 201 ),
array( 'create', 'author', 201 ),
array( 'create', 'contributor', 403 ),
array( 'create', null, 401 ),

array( 'read', 'editor', 200 ),
array( 'read', 'author', 200 ),
array( 'read', 'contributor', 200 ),
array( 'read', null, 401 ),

array( 'update_delete_own', 'editor', 200 ),
array( 'update_delete_own', 'author', 200 ),
array( 'update_delete_own', 'contributor', 403 ),

array( 'update_delete_others', 'editor', 200 ),
array( 'update_delete_others', 'author', 403 ),
array( 'update_delete_others', 'contributor', 403 ),
array( 'update_delete_others', null, 401 ),
);
}

/**
* Exhaustively check that each role either can or cannot create, edit,
* update, and delete reusable blocks.
*
* @dataProvider data_capabilities
*/
public function test_capabilities( $action, $role, $expected_status ) {
if ( $role ) {
$user_id = $this->factory->user->create( array( 'role' => $role ) );
wp_set_current_user( $user_id );
} else {
wp_set_current_user( 0 );
}

switch ( $action ) {
case 'create':
$request = new WP_REST_Request( 'POST', '/wp/v2/blocks' );
$request->set_body_params(
array(
'title' => 'Test',
'content' => '<!-- wp:core/paragraph --><p>Test</p><!-- /wp:core/paragraph -->',
)
);

$response = rest_get_server()->dispatch( $request );
$this->assertEquals( $expected_status, $response->get_status() );

break;

case 'read':
$request = new WP_REST_Request( 'GET', '/wp/v2/blocks/' . self::$post_id );

$response = rest_get_server()->dispatch( $request );
$this->assertEquals( $expected_status, $response->get_status() );

break;

case 'update_delete_own':
$post_id = wp_insert_post(
array(
'post_type' => 'wp_block',
'post_status' => 'publish',
'post_title' => 'My cool block',
'post_content' => '<!-- wp:core/paragraph --><p>Hello!</p><!-- /wp:core/paragraph -->',
'post_author' => $user_id,
)
);

$request = new WP_REST_Request( 'PUT', '/wp/v2/blocks/' . $post_id );
$request->set_body_params(
array(
'title' => 'Test',
'content' => '<!-- wp:core/paragraph --><p>Test</p><!-- /wp:core/paragraph -->',
)
);

$response = rest_get_server()->dispatch( $request );
$this->assertEquals( $expected_status, $response->get_status() );

$request = new WP_REST_Request( 'DELETE', '/wp/v2/blocks/' . $post_id );

$response = rest_get_server()->dispatch( $request );
$this->assertEquals( $expected_status, $response->get_status() );

wp_delete_post( $post_id );

break;

case 'update_delete_others':
$request = new WP_REST_Request( 'PUT', '/wp/v2/blocks/' . self::$post_id );
$request->set_body_params(
array(
'title' => 'Test',
'content' => '<!-- wp:core/paragraph --><p>Test</p><!-- /wp:core/paragraph -->',
)
);

$response = rest_get_server()->dispatch( $request );
$this->assertEquals( $expected_status, $response->get_status() );

$request = new WP_REST_Request( 'DELETE', '/wp/v2/blocks/' . self::$post_id );

$response = rest_get_server()->dispatch( $request );
$this->assertEquals( $expected_status, $response->get_status() );

break;

default:
$this->fail( "'$action' is not a valid action." );
}

if ( isset( $user_id ) ) {
self::delete_user( $user_id );
}
}
}

0 comments on commit e3b1279

Please sign in to comment.