Previously, the Block Data API verified posts were readable using the 'publish' status. This provides basic access limitations to posts in the REST API, but isn't as restrictive as WordPress' built-in REST API.
For example, the Block Data API can be used to access a custom post type with the publish status that isn't allowed by the REST API:
First a custom post type is registered with 'public' => false:
$ wp post create --post_type="vip-test-post-type" --post_title="Custom post_type" \
--post_content='<!-- wp:paragraph --><p>Custom post_type content</p><!-- /wp:paragraph -->' \
--post_status="publish"
Success: Created post 12.
If the post is queried via the built-in REST API, the post is not accessible:
GET /wp-json/wp/v2/posts/12
{"code":"rest_post_invalid_id","message":"Invalid post ID.","data":{"status":404}}
However, the same post was accessible through the block data API due to the publish status:
GET /wp-json/vip-block-data-api/v1/posts/12/blocks
{"blocks":[{"name":"core\/paragraph","attributes":{"content":"Custom post_type content","dropCap":false}}]}
The WordPress REST function is not used directly, as instantiating the REST controller and calling check_read_permission() for a single post is not the intended flow of the class, and can sometimes generate warnings from uninitialized variables. Rather than depending on an internal flow of a specialized class, we moved the permission checking defaults into is_post_readable().
Now when the same non-public post is queried by the block API, it is rejected:
GET /wp-json/vip-block-data-api/v1/posts/12/blocks
{"code":"rest_invalid_param","message":"Invalid parameter(s): id","data":{"status":400,"params":{"id":"Invalid parameter."},"details":[]}}
test_rest_api_returns_blocks_for_custom_post_type(): Ensure custom post types with 'public' => true and 'show_in_rest' => true are returned by the Block Data API successfully.
test_rest_api_returns_error_for_non_public_post_type(): Ensure custom post types with 'public' => false result in an invalid ID error.
test_rest_api_returns_error_for_non_rest_post_type(): Ensure custom post types with 'public' => true but 'show_in_rest' => false also result in an invalid ID error.
Description
Previously, the Block Data API verified posts were readable using the
'publish'
status. This provides basic access limitations to posts in the REST API, but isn't as restrictive as WordPress' built-in REST API.For example, the Block Data API can be used to access a custom post type with the
publish
status that isn't allowed by the REST API:First a custom post type is registered with
'public' => false
:A post is created with that type:
If the post is queried via the built-in REST API, the post is not accessible:
However, the same post was accessible through the block data API due to the
publish
status:This has been fixed to use logic based on WordPress'
WP_REST_Posts_Controller->check_read_permission()
function.The WordPress REST function is not used directly, as instantiating the REST controller and calling
check_read_permission()
for a single post is not the intended flow of the class, and can sometimes generate warnings from uninitialized variables. Rather than depending on an internal flow of a specialized class, we moved the permission checking defaults intois_post_readable()
.Now when the same non-public post is queried by the block API, it is rejected:
Steps to Test
Three tests were added to verify this functionality in https://github.com/Automattic/vip-block-data-api/commit/5bf567b3fdfc1c9bbd921d0491c4d33fc2600807:
test_rest_api_returns_blocks_for_custom_post_type()
: Ensure custom post types with'public' => true
and'show_in_rest' => true
are returned by the Block Data API successfully.test_rest_api_returns_error_for_non_public_post_type()
: Ensure custom post types with'public' => false
result in an invalid ID error.test_rest_api_returns_error_for_non_rest_post_type()
: Ensure custom post types with'public' => true
but'show_in_rest' => false
also result in an invalid ID error.These match the behavior of the default REST API.