XML-RPC: Improve error messages for unprivileged users.
Add specific permission checks to avoid ambiguous failure messages. Props zieladam, peterwilsoncc, xknown, whyisjake. git-svn-id: https://develop.svn.wordpress.org/trunk@49380 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
ed2b1a43e0
commit
c9e6b98968
@ -3876,6 +3876,21 @@ class wp_xmlrpc_server extends IXR_Server {
|
||||
return new IXR_Error( 403, __( 'Sorry, comments are closed for this item.' ) );
|
||||
}
|
||||
|
||||
if (
|
||||
'publish' === get_post_status( $post_id ) &&
|
||||
! current_user_can( 'edit_post', $post_id ) &&
|
||||
post_password_required( $post_id )
|
||||
) {
|
||||
return new IXR_Error( 403, __( 'Sorry, you are not allowed to comment on this post.' ) );
|
||||
}
|
||||
|
||||
if (
|
||||
'private' === get_post_status( $post_id ) &&
|
||||
! current_user_can( 'read_post', $post_id )
|
||||
) {
|
||||
return new IXR_Error( 403, __( 'Sorry, you are not allowed to comment on this post.' ) );
|
||||
}
|
||||
|
||||
$comment = array(
|
||||
'comment_post_ID' => $post_id,
|
||||
'comment_content' => trim( $content_struct['content'] ),
|
||||
|
@ -6,15 +6,45 @@
|
||||
class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
|
||||
/**
|
||||
* Post object for shared fixture.
|
||||
* Array of posts.
|
||||
*
|
||||
* @var WP_Post
|
||||
* @var WP_Post[]
|
||||
*/
|
||||
public static $post;
|
||||
public static $posts;
|
||||
|
||||
/**
|
||||
* User IDs.
|
||||
*
|
||||
* Array of user IDs keyed by role.
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
public static $user_ids;
|
||||
|
||||
public static function wpSetUpBeforeClass( $factory ) {
|
||||
self::make_user_by_role( 'administrator' );
|
||||
self::$post = $factory->post->create_and_get();
|
||||
self::$user_ids = array(
|
||||
'administrator' => self::make_user_by_role( 'administrator' ),
|
||||
'contributor' => self::make_user_by_role( 'contributor' ),
|
||||
);
|
||||
self::$posts['publish'] = $factory->post->create_and_get();
|
||||
self::$posts['password'] = $factory->post->create_and_get(
|
||||
array(
|
||||
'post_password' => 'xmlrpc',
|
||||
'post_author' => self::$user_ids['administrator'],
|
||||
)
|
||||
);
|
||||
self::$posts['private'] = $factory->post->create_and_get(
|
||||
array(
|
||||
'post_status' => 'private',
|
||||
'post_author' => self::$user_ids['administrator'],
|
||||
)
|
||||
);
|
||||
self::$posts['private_contributor'] = $factory->post->create_and_get(
|
||||
array(
|
||||
'post_status' => 'private',
|
||||
'post_author' => self::$user_ids['contributor'],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function test_valid_comment() {
|
||||
@ -23,7 +53,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'administrator',
|
||||
'administrator',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'content' => rand_str( 100 ),
|
||||
),
|
||||
@ -39,7 +69,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'administrator',
|
||||
'administrator',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'content' => '',
|
||||
),
|
||||
@ -59,7 +89,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'administrator',
|
||||
'administrator',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'content' => ' ',
|
||||
),
|
||||
@ -79,7 +109,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'administrator',
|
||||
'administrator',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'content' => '0',
|
||||
),
|
||||
@ -99,7 +129,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'administrator',
|
||||
'administrator',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'content' => ' ',
|
||||
),
|
||||
@ -139,7 +169,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'administrator',
|
||||
'administrator',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'content' => rand_str( 100 ),
|
||||
),
|
||||
@ -168,7 +198,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'',
|
||||
'',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'author' => 'WordPress',
|
||||
'author_email' => 'noreply@wordpress.org',
|
||||
@ -193,7 +223,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'',
|
||||
'',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'author' => 'WordPress',
|
||||
'author_email' => 'noreply at wordpress.org',
|
||||
@ -218,7 +248,7 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
1,
|
||||
'administrator',
|
||||
'administrator',
|
||||
self::$post->ID,
|
||||
self::$posts['publish']->ID,
|
||||
array(
|
||||
'author' => 'WordPress',
|
||||
'author_email' => 'noreply at wordpress.org',
|
||||
@ -232,4 +262,131 @@ class Tests_XMLRPC_wp_newComment extends WP_XMLRPC_UnitTestCase {
|
||||
|
||||
$this->assertSame( $user_id, (int) $comment->user_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure users can only comment on posts they're permitted to access.
|
||||
*
|
||||
* @dataProvider data_comments_observe_post_permissions
|
||||
*
|
||||
* @param string $post_key Post identifier from the self::$posts array.
|
||||
* @param string $username Username leaving comment.
|
||||
* @param bool $expected Expected result. True: successfull comment. False: Refused comment.
|
||||
* @param string $anon_callback Optional. Allow anonymous comment callback. Default __return_false.
|
||||
*/
|
||||
function test_comments_observe_post_permissions( $post_key, $username, $expected, $anon_callback = '__return_false' ) {
|
||||
add_filter( 'xmlrpc_allow_anonymous_comments', $anon_callback );
|
||||
|
||||
$comment_args = array(
|
||||
1,
|
||||
$username,
|
||||
$username,
|
||||
self::$posts[ $post_key ]->ID,
|
||||
array(
|
||||
'author' => 'WordPress',
|
||||
'author_email' => 'noreply@wordpress.org',
|
||||
'content' => 'Test Comment',
|
||||
),
|
||||
);
|
||||
|
||||
$result = $this->myxmlrpcserver->wp_newComment( $comment_args );
|
||||
if ( $expected ) {
|
||||
$this->assertInternalType( 'int', $result );
|
||||
return;
|
||||
}
|
||||
|
||||
$this->assertIXRError( $result );
|
||||
$this->assertSame( 403, $result->code );
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_comments_observe_post_permissions.
|
||||
*
|
||||
* @return array[] {
|
||||
* @type string Post identifier from the self::$posts array.
|
||||
* @type string Username leaving comment.
|
||||
* @type bool Expected result. True: successfull comment. False: Refused comment.
|
||||
* @type string Optional. Allow anonymous comment callback. Default __return_false.
|
||||
* }
|
||||
*/
|
||||
function data_comments_observe_post_permissions() {
|
||||
return array(
|
||||
// 0: Post author, password protected public post.
|
||||
array(
|
||||
'password',
|
||||
'administrator',
|
||||
true,
|
||||
),
|
||||
// 1: Low privileged non-author, password protected public post.
|
||||
array(
|
||||
'password',
|
||||
'contributor',
|
||||
false,
|
||||
),
|
||||
// 2: Anonymous user, password protected public post.
|
||||
array(
|
||||
'password',
|
||||
'', // Anonymous user.
|
||||
false,
|
||||
),
|
||||
// 3: Anonymous user, anon comments allowed, password protected public post.
|
||||
array(
|
||||
'password',
|
||||
'', // Anonymous user.
|
||||
false,
|
||||
'__return_true',
|
||||
),
|
||||
|
||||
// 4: Post author, private post.
|
||||
array(
|
||||
'private',
|
||||
'administrator',
|
||||
true,
|
||||
),
|
||||
// 5: Low privileged non-author, private post.
|
||||
array(
|
||||
'private',
|
||||
'contributor',
|
||||
false,
|
||||
),
|
||||
// 6: Anonymous user, private post.
|
||||
array(
|
||||
'private',
|
||||
'', // Anonymous user.
|
||||
false,
|
||||
),
|
||||
// 7: Anonymous user, anon comments allowed, private post.
|
||||
array(
|
||||
'private',
|
||||
'', // Anonymous user.
|
||||
false,
|
||||
'__return_true',
|
||||
),
|
||||
|
||||
// 8: High privileged non-author, private post.
|
||||
array(
|
||||
'private_contributor',
|
||||
'administrator',
|
||||
true,
|
||||
),
|
||||
// 9: Low privileged author, private post.
|
||||
array(
|
||||
'private_contributor',
|
||||
'contributor',
|
||||
true,
|
||||
),
|
||||
// 10: Anonymous user, private post.
|
||||
array(
|
||||
'private_contributor',
|
||||
'', // Anonymous user.
|
||||
false,
|
||||
),
|
||||
// 11: Anonymous user, anon comments allowed, private post.
|
||||
array(
|
||||
'private_contributor',
|
||||
'', // Anonymous user.
|
||||
false,
|
||||
'__return_true',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user