Skip to content

Commit

Permalink
Check response body for tombstone type (#1209) (#1222)
Browse files Browse the repository at this point in the history
* Check response body for tombstone type (#1209)

* some small improvements

* fix PHPCS

---------

Co-authored-by: Matthew Exon <[email protected]>
Co-authored-by: Matthias Pfefferle <[email protected]>
  • Loading branch information
3 people authored Jan 28, 2025
1 parent 5f73af8 commit e0c3b67
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Improved content negotiation and AUTHORIZED_FETCH support for third-party plugins

### Fixed

* Handle deletes from remote servers that leave behind an accessible Tombstone object.

## [4.7.3] - 2025-01-21

### Fixed
Expand Down
8 changes: 7 additions & 1 deletion includes/class-http.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,19 @@ public static function is_tombstone( $url ) {
*/
\do_action( 'activitypub_pre_http_is_tombstone', $url );

$response = \wp_safe_remote_get( $url );
$response = \wp_safe_remote_get( $url, array( 'headers' => array( 'Accept' => 'application/activity+json' ) ) );
$code = \wp_remote_retrieve_response_code( $response );

if ( in_array( (int) $code, array( 404, 410 ), true ) ) {
return true;
}

$data = \wp_remote_retrieve_body( $response );
$data = \json_decode( $data, true );
if ( $data && isset( $data['type'] ) && 'Tombstone' === $data['type'] ) {
return true;
}

return false;
}

Expand Down
1 change: 1 addition & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ For reasons of data protection, it is not possible to see the followers of other
= Unreleased =

* Changed: Improved content negotiation and AUTHORIZED_FETCH support for third-party plugins
* Fixed: Handle deletes from remote servers that leave behind an accessible Tombstone object.

= 4.7.3 =

Expand Down
85 changes: 85 additions & 0 deletions tests/includes/class-test-http.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
/**
* Test file for Activitypub HTTP Class
*
* @package Activitypub
*/

namespace Activitypub\Tests;

use Activitypub\Http;

/**
* Test class for ActivityPub HTTP Class
*
* @coversDefaultClass \Activitypub\Http
*/
class Test_Http extends \WP_UnitTestCase {

/**
* Response code is 404 -> is_tombstone returns true
*
* @covers ::is_tombstone
*
* @dataProvider data_is_tombstone
*
* @param array $request The request array.
* @param bool $result The expected result.
*/
public function test_is_tombstone( $request, $result ) {
$fake_request = function () use ( $request ) {
return $request;
};
add_filter( 'pre_http_request', $fake_request, 10, 3 );
$response = Http::is_tombstone( 'https://fake.test/object/123' );
$this->assertEquals( $result, $response );
remove_filter( 'pre_http_request', $fake_request, 10 );
}

/**
* Data provider for test_is_tombstone.
*
* @return array
*/
public function data_is_tombstone() {
return array(
array( array( 'response' => array( 'code' => 404 ) ), true ),
array( array( 'response' => array( 'code' => 410 ) ), true ),
array(
array(
'response' => array( 'code' => 200 ),
'body' => '',
),
false,
),
array(
array(
'response' => array( 'code' => 200 ),
'body' => '{}',
),
false,
),
array(
array(
'response' => array( 'code' => 200 ),
'body' => '{"type": "Note"}',
),
false,
),
array(
array(
'response' => array( 'code' => 200 ),
'body' => '{"type": "Tombstone"}',
),
true,
),
array(
array(
'response' => array( 'code' => 200 ),
'body' => '{"foo": "bar"}',
),
false,
),
);
}
}

0 comments on commit e0c3b67

Please sign in to comment.