Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Bindings: Don't show protected fields that are bound to blocks and post meta #6197

Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
105ffe1
Check if the meta field is protected
SantosGuillamot Feb 28, 2024
00b4d65
Check if the meta field is available in the REST API
SantosGuillamot Feb 28, 2024
46a29e4
Remove unnecessary `show_in_rest` conditional
SantosGuillamot Feb 28, 2024
0b106f9
Use `source_args` instead of `source_attrs`
SantosGuillamot Feb 28, 2024
1736c83
Add post meta bindings source tests
SantosGuillamot Feb 28, 2024
1fb2c47
Unregister only the meta fields containing "tests"
SantosGuillamot Feb 28, 2024
81d4e34
Add test for password protected posts
SantosGuillamot Feb 28, 2024
8d0a0be
Add test for posts that are not viewable
SantosGuillamot Feb 28, 2024
ce4aa0c
Move set up tp `wpSetUpBeforeClass`
SantosGuillamot Feb 29, 2024
f1655d6
Add test for non existing meta key
SantosGuillamot Feb 29, 2024
01d45e5
Remove filters in tests
SantosGuillamot Feb 29, 2024
7d25302
Refactor the way post content is modified
SantosGuillamot Feb 29, 2024
dfe02a5
Add test to check unsafe html is sanitized
SantosGuillamot Feb 29, 2024
6414a97
Move unsafe html test to render bindings
SantosGuillamot Feb 29, 2024
193131f
Add post meta unsafe html test again
SantosGuillamot Feb 29, 2024
a0b761b
Change how we modify the global $post variable
SantosGuillamot Feb 29, 2024
4cdf241
Use snake_case
SantosGuillamot Feb 29, 2024
6e37a4c
Use hooks helper function
SantosGuillamot Feb 29, 2024
8389270
Remove outdated function
SantosGuillamot Feb 29, 2024
953058d
Update class methods descriptions
SantosGuillamot Feb 29, 2024
bc81da4
Unset global post variable after class
SantosGuillamot Feb 29, 2024
64f0784
Add tests for bindings modifying html attribute
SantosGuillamot Feb 29, 2024
56beecc
Apply suggestions from code review
swissspidy Mar 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/wp-includes/block-bindings/post-meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ function _block_bindings_post_meta_get_value( array $source_args, $block_instanc
return null;
}

// Check if the meta field is protected.
if ( is_protected_meta( $source_args['key'], 'post' ) ) {
return null;
}

// Check if the meta field is registered to be shown in REST.
$meta_keys = get_registered_meta_keys( 'post', $block_instance->context['postType'] );
// Add fields registered for all subtypes.
$meta_keys = array_merge( $meta_keys, get_registered_meta_keys( 'post', '' ) );
if ( empty( $meta_keys[ $source_args['key'] ]['show_in_rest'] ) ) {
return null;
}

return get_post_meta( $post_id, $source_args['key'], true );
}

Expand Down
199 changes: 199 additions & 0 deletions tests/phpunit/tests/block-bindings/postMetaSource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
<?php
/**
* Tests for Block Bindings API "core/post-meta" source.
*
* @package WordPress
* @subpackage Blocks
* @since 6.5.0
*
* @group blocks
* @group block-bindings
*/
class Tests_Block_Bindings_Post_Meta_Source extends WP_UnitTestCase {

/**
* Sets up each test method.
*/
public function set_up() {
global $post;

parent::set_up();

$post = self::factory()->post->create_and_get( array() );
gziolo marked this conversation as resolved.
Show resolved Hide resolved
setup_postdata( $post );
}

/**
* Tear down each test method.
*/
public function tear_down() {
gziolo marked this conversation as resolved.
Show resolved Hide resolved
// Removes custom fields registered by test cases.
$meta_keys = get_registered_meta_keys( 'post', '' );
foreach ( $meta_keys as $meta_key_name => $meta_key_value ) {
if ( str_contains( $meta_key_name, 'tests' ) ) {
unregister_meta_key( 'post', $meta_key_name );
}
}

parent::tear_down();
}

/**
* Tests that a block connected to a custom field renders its value.
*
* @ticket 60651
*/
public function test_custom_field_value_is_rendered() {
register_meta(
'post',
'tests_custom_field',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'default' => 'Custom field value',
)
);

$content = apply_filters( 'the_content', '<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"tests_custom_field"}}}}} --><p>Fallback value</p><!-- /wp:paragraph -->' );

$this->assertSame(
'<p>Custom field value</p>',
trim( $content ),
'The post content should show the value of the custom field.'
);
}

/**
* Tests that a blocks connected in a password protected post don't render the value.
*
* @ticket 60651
*/
public function test_custom_field_value_is_not_shown_in_password_protected_posts() {
register_meta(
'post',
'tests_custom_field',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'default' => 'Custom field value',
)
);

add_filter(
'post_password_required',
function () {
return true;
}
);

$content = apply_filters( 'the_content', '<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"tests_custom_field"}}}}} --><p>Fallback value</p><!-- /wp:paragraph -->' );

$this->assertSame(
'<p>Fallback value</p>',
trim( $content ),
'The post content should show the fallback value instead of the custom field value.'
);
}

/**
* Tests that a blocks connected in a post that is not publicly viewable don't render the value.
*
* @ticket 60651
*/
public function test_custom_field_value_is_not_shown_in_non_viewable_posts() {
register_meta(
'post',
'tests_custom_field',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'default' => 'Custom field value',
)
);

add_filter(
'is_post_status_viewable',
function () {
return false;
}
);

$content = apply_filters( 'the_content', '<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"tests_custom_field"}}}}} --><p>Fallback value</p><!-- /wp:paragraph -->' );

$this->assertSame(
'<p>Fallback value</p>',
trim( $content ),
'The post content should show the fallback value instead of the custom field value.'
);
}

/**
* Tests that a block connected without specifying the custom field renders the fallback.
*
* @ticket 60651
*/
public function test_binding_without_key_renders_the_fallback() {
$content = apply_filters( 'the_content', '<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta"}}}} --><p>Fallback value</p><!-- /wp:paragraph -->' );

$this->assertSame(
'<p>Fallback value</p>',
trim( $content ),
'The post content should show the fallback value.'
);
}

/**
* Tests that a block connected to a protected field doesn't show the value.
*
* @ticket 60651
*/
public function test_protected_field_value_is_not_shown() {
register_meta(
'post',
'_tests_protected_field',
array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'default' => 'Protected value',
)
);

$content = apply_filters( 'the_content', '<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"_tests_protected_field"}}}}} --><p>Fallback value</p><!-- /wp:paragraph -->' );

$this->assertSame(
'<p>Fallback value</p>',
trim( $content ),
'The post content should show the fallback value instead of the protected value.'
);
}

/**
* Tests that a block connected to a field not exposed in the REST API doesn't show the value.
*
* @ticket 60651
*/
public function test_custom_field_not_exposed_in_rest_api_is_not_shown() {
register_meta(
'post',
'tests_show_in_rest_false_field',
array(
'show_in_rest' => false,
'single' => true,
'type' => 'string',
'default' => 'Protected value',
)
);

$content = apply_filters( 'the_content', '<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"core/post-meta","args":{"key":"tests_show_in_rest_false_field"}}}}} --><p>Fallback value</p><!-- /wp:paragraph -->' );

$this->assertSame(
'<p>Fallback value</p>',
trim( $content ),
'The post content should show the fallback value instead of the protected value.'
);
}
}
Loading