mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-06-28 14:20:15 +00:00
Embeds: Filter HTML response in oEmbed proxy controller.
Adapts the response from `WP_oEmbed_Controller::get_proxy_item()` so that the response is correctly filtered and embeds work properly in JavaSccript editors. Introduces new `get_oembed_response_data_for_url()` function for preparing internal oEmbed responses. Merges [43810] from the 5.0 branch to trunk. Props danielbachhuber, imath, swissspidy. Fixes #45142. git-svn-id: https://develop.svn.wordpress.org/trunk@44154 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -14,6 +14,7 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
protected static $subscriber;
|
||||
const YOUTUBE_VIDEO_ID = 'OQSNhk5ICTI';
|
||||
const INVALID_OEMBED_URL = 'https://www.notreallyanoembedprovider.com/watch?v=awesome-cat-video';
|
||||
const UNTRUSTED_PROVIDER_URL = 'https://www.untrustedprovider.com';
|
||||
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
self::$subscriber = $factory->user->create(
|
||||
@@ -49,7 +50,10 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
do_action( 'rest_api_init', $wp_rest_server );
|
||||
|
||||
add_filter( 'pre_http_request', array( $this, 'mock_embed_request' ), 10, 3 );
|
||||
add_filter( 'oembed_result', array( $this, 'filter_oembed_result' ), 10, 3 );
|
||||
$this->request_count = 0;
|
||||
|
||||
$this->oembed_result_filter_count = 0;
|
||||
}
|
||||
|
||||
public function tearDown() {
|
||||
@@ -59,6 +63,7 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
$wp_rest_server = null;
|
||||
|
||||
remove_filter( 'pre_http_request', array( $this, 'mock_embed_request' ), 10 );
|
||||
remove_filter( 'oembed_result', array( $this, 'filter_oembed_result' ), 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,6 +73,13 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
*/
|
||||
public $request_count = 0;
|
||||
|
||||
/**
|
||||
* Count of the number of times the oembed_result filter was called.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $oembed_result_filter_count = 0;
|
||||
|
||||
/**
|
||||
* Intercept oEmbed requests and mock responses.
|
||||
*
|
||||
@@ -80,7 +92,8 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
unset( $preempt, $r );
|
||||
|
||||
$parsed_url = wp_parse_url( $url );
|
||||
parse_str( $parsed_url['query'], $query_params );
|
||||
$query = isset( $parsed_url['query'] ) ? $parsed_url['query'] : '';
|
||||
parse_str( $query, $query_params );
|
||||
$this->request_count += 1;
|
||||
|
||||
// Mock request to YouTube Embed.
|
||||
@@ -99,20 +112,66 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
'width' => $query_params['maxwidth'],
|
||||
'thumbnail_height' => $query_params['maxheight'],
|
||||
'height' => $query_params['maxheight'],
|
||||
'html' => '<iframe width="' . $query_params['maxwidth'] . '" height="' . $query_params['maxheight'] . '" src="https://www.youtube.com/embed/' . self::YOUTUBE_VIDEO_ID . '?feature=oembed" frameborder="0" allowfullscreen></iframe>',
|
||||
'html' => '<b>Unfiltered</b><iframe width="' . $query_params['maxwidth'] . '" height="' . $query_params['maxheight'] . '" src="https://www.youtube.com/embed/' . self::YOUTUBE_VIDEO_ID . '?feature=oembed" frameborder="0" allowfullscreen></iframe>',
|
||||
'author_name' => 'Yosemitebear62',
|
||||
'thumbnail_url' => 'https://i.ytimg.com/vi/' . self::YOUTUBE_VIDEO_ID . '/hqdefault.jpg',
|
||||
'title' => 'Yosemitebear Mountain Double Rainbow 1-8-10',
|
||||
)
|
||||
),
|
||||
);
|
||||
} else {
|
||||
}
|
||||
|
||||
if ( $url === self::UNTRUSTED_PROVIDER_URL ) {
|
||||
return array(
|
||||
'response' => array(
|
||||
'code' => 404,
|
||||
'code' => 200,
|
||||
),
|
||||
'body' => '<html><head><link rel="alternate" type="application/json+oembed" href="' . self::UNTRUSTED_PROVIDER_URL . '" /></head><body></body></html>',
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $query_params['url'] ) && false !== strpos( $query_params['url'], self::UNTRUSTED_PROVIDER_URL ) ) {
|
||||
return array(
|
||||
'response' => array(
|
||||
'code' => 200,
|
||||
),
|
||||
'body' => wp_json_encode(
|
||||
array(
|
||||
'version' => '1.0',
|
||||
'type' => 'rich',
|
||||
'provider_name' => 'Untrusted',
|
||||
'provider_url' => self::UNTRUSTED_PROVIDER_URL,
|
||||
'html' => '<b>Filtered</b><a href="">Unfiltered</a>',
|
||||
'author_name' => 'Untrusted Embed Author',
|
||||
'title' => 'Untrusted Embed',
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'response' => array(
|
||||
'code' => 404,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters 'oembed_result' to ensure correct type.
|
||||
*
|
||||
* @param string|false $data The returned oEmbed HTML.
|
||||
* @param string $url URL of the content to be embedded.
|
||||
* @param array $args Optional arguments, usually passed from a shortcode.
|
||||
* @return string
|
||||
*/
|
||||
public function filter_oembed_result( $data, $url, $args ) {
|
||||
if ( ! is_string( $data ) && false !== $data ) {
|
||||
$this->fail( 'Unexpected type for $data.' );
|
||||
}
|
||||
$this->assertInternalType( 'string', $url );
|
||||
$this->assertInternalType( 'array', $args );
|
||||
$this->oembed_result_filter_count++;
|
||||
return $data;
|
||||
}
|
||||
|
||||
function test_wp_oembed_ensure_format() {
|
||||
@@ -543,7 +602,7 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertNotEmpty( $data );
|
||||
$this->assertTrue( is_object( $data ) );
|
||||
$this->assertInternalType( 'object', $data );
|
||||
$this->assertEquals( 'YouTube', $data->provider_name );
|
||||
$this->assertEquals( 'https://i.ytimg.com/vi/' . self::YOUTUBE_VIDEO_ID . '/hqdefault.jpg', $data->thumbnail_url );
|
||||
$this->assertEquals( $data->width, $request['maxwidth'] );
|
||||
@@ -585,4 +644,141 @@ class Test_oEmbed_Controller extends WP_UnitTestCase {
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( $data['code'], 'rest_invalid_param' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 45142
|
||||
*/
|
||||
function test_proxy_with_internal_url() {
|
||||
wp_set_current_user( self::$editor );
|
||||
|
||||
$user = self::factory()->user->create_and_get( array(
|
||||
'display_name' => 'John Doe',
|
||||
) );
|
||||
$post = self::factory()->post->create_and_get( array(
|
||||
'post_author' => $user->ID,
|
||||
'post_title' => 'Hello World',
|
||||
) );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' );
|
||||
$request->set_param( 'url', get_permalink( $post->ID ) );
|
||||
$request->set_param( 'maxwidth', 400 );
|
||||
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$data = (array) $data;
|
||||
|
||||
$this->assertNotEmpty( $data );
|
||||
|
||||
$this->assertArrayHasKey( 'version', $data );
|
||||
$this->assertArrayHasKey( 'provider_name', $data );
|
||||
$this->assertArrayHasKey( 'provider_url', $data );
|
||||
$this->assertArrayHasKey( 'author_name', $data );
|
||||
$this->assertArrayHasKey( 'author_url', $data );
|
||||
$this->assertArrayHasKey( 'title', $data );
|
||||
$this->assertArrayHasKey( 'type', $data );
|
||||
$this->assertArrayHasKey( 'width', $data );
|
||||
|
||||
$this->assertEquals( '1.0', $data['version'] );
|
||||
$this->assertEquals( get_bloginfo( 'name' ), $data['provider_name'] );
|
||||
$this->assertEquals( get_home_url(), $data['provider_url'] );
|
||||
$this->assertEquals( $user->display_name, $data['author_name'] );
|
||||
$this->assertEquals( get_author_posts_url( $user->ID, $user->user_nicename ), $data['author_url'] );
|
||||
$this->assertEquals( $post->post_title, $data['title'] );
|
||||
$this->assertEquals( 'rich', $data['type'] );
|
||||
$this->assertTrue( $data['width'] <= $request['maxwidth'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 45142
|
||||
*/
|
||||
function test_proxy_with_static_front_page_url() {
|
||||
wp_set_current_user( self::$editor );
|
||||
|
||||
$post = self::factory()->post->create_and_get( array(
|
||||
'post_title' => 'Front page',
|
||||
'post_type' => 'page',
|
||||
'post_author' => 0,
|
||||
) );
|
||||
|
||||
update_option( 'show_on_front', 'page' );
|
||||
update_option( 'page_on_front', $post->ID );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' );
|
||||
$request->set_param( 'url', home_url() );
|
||||
$request->set_param( 'maxwidth', 400 );
|
||||
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertInternalType( 'object', $data );
|
||||
|
||||
$data = (array) $data;
|
||||
|
||||
$this->assertNotEmpty( $data );
|
||||
|
||||
$this->assertArrayHasKey( 'version', $data );
|
||||
$this->assertArrayHasKey( 'provider_name', $data );
|
||||
$this->assertArrayHasKey( 'provider_url', $data );
|
||||
$this->assertArrayHasKey( 'author_name', $data );
|
||||
$this->assertArrayHasKey( 'author_url', $data );
|
||||
$this->assertArrayHasKey( 'title', $data );
|
||||
$this->assertArrayHasKey( 'type', $data );
|
||||
$this->assertArrayHasKey( 'width', $data );
|
||||
|
||||
$this->assertEquals( '1.0', $data['version'] );
|
||||
$this->assertEquals( get_bloginfo( 'name' ), $data['provider_name'] );
|
||||
$this->assertEquals( get_home_url(), $data['provider_url'] );
|
||||
$this->assertEquals( get_bloginfo( 'name' ), $data['author_name'] );
|
||||
$this->assertEquals( get_home_url(), $data['author_url'] );
|
||||
$this->assertEquals( $post->post_title, $data['title'] );
|
||||
$this->assertEquals( 'rich', $data['type'] );
|
||||
$this->assertTrue( $data['width'] <= $request['maxwidth'] );
|
||||
|
||||
update_option( 'show_on_front', 'posts' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 45142
|
||||
*/
|
||||
public function test_proxy_filters_result_of_untrusted_oembed_provider() {
|
||||
wp_set_current_user( self::$editor );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' );
|
||||
$request->set_param( 'url', self::UNTRUSTED_PROVIDER_URL );
|
||||
$request->set_param( 'maxwidth', 456 );
|
||||
$request->set_param( 'maxheight', 789 );
|
||||
$request->set_param( '_wpnonce', wp_create_nonce( 'wp_rest' ) );
|
||||
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 1, $this->oembed_result_filter_count );
|
||||
$this->assertInternalType( 'object', $data );
|
||||
$this->assertEquals( 'Untrusted', $data->provider_name );
|
||||
$this->assertEquals( self::UNTRUSTED_PROVIDER_URL, $data->provider_url );
|
||||
$this->assertEquals( 'rich', $data->type );
|
||||
$this->assertFalse( $data->html );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 45142
|
||||
*/
|
||||
public function test_proxy_does_not_filter_result_of_trusted_oembed_provider() {
|
||||
wp_set_current_user( self::$editor );
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/oembed/1.0/proxy' );
|
||||
$request->set_param( 'url', 'https://www.youtube.com/watch?v=' . self::YOUTUBE_VIDEO_ID );
|
||||
$request->set_param( 'maxwidth', 456 );
|
||||
$request->set_param( 'maxheight', 789 );
|
||||
$request->set_param( '_wpnonce', wp_create_nonce( 'wp_rest' ) );
|
||||
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 1, $this->oembed_result_filter_count );
|
||||
$this->assertInternalType( 'object', $data );
|
||||
|
||||
$this->assertStringStartsWith( '<b>Unfiltered</b>', $data->html );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user