updated plugin ActivityPub version 9.1.0
This commit is contained in:
@ -7,6 +7,8 @@
|
||||
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
use Activitypub\Signature;
|
||||
|
||||
/**
|
||||
* ActivityPub Server REST-Class.
|
||||
*
|
||||
@ -19,6 +21,7 @@ class Server {
|
||||
* Initialize the class, registering WordPress hooks.
|
||||
*/
|
||||
public static function init() {
|
||||
\add_filter( 'rest_pre_dispatch', array( self::class, 'maybe_add_actor_from_signature' ), 10, 3 );
|
||||
\add_filter( 'rest_request_before_callbacks', array( self::class, 'validate_requests' ), 9, 3 );
|
||||
\add_filter( 'rest_request_parameter_order', array( self::class, 'request_parameter_order' ), 10, 2 );
|
||||
|
||||
@ -60,7 +63,7 @@ class Server {
|
||||
|
||||
if (
|
||||
ACTIVITYPUB_DISABLE_INCOMING_INTERACTIONS &&
|
||||
in_array( $params['type'], array( 'Create', 'Like', 'Announce' ), true )
|
||||
\in_array( $params['type'], array( 'Create', 'Like', 'Announce' ), true )
|
||||
) {
|
||||
return new \WP_Error(
|
||||
'activitypub_server_does_not_accept_incoming_interactions',
|
||||
@ -104,6 +107,67 @@ class Server {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Backfill a missing `actor` on incoming FeatureRequest activities from the signature.
|
||||
*
|
||||
* Mastodon (FEP-7aa9) omits `actor` from the FeatureRequest body and conveys the
|
||||
* requesting actor only through the HTTP signature keyId. Our inbox routes require
|
||||
* `actor`, so such a request is rejected during parameter validation before it can
|
||||
* reach the inbox or its handler, which is why no Accept is ever sent.
|
||||
*
|
||||
* Derive the actor from the keyId and add it as a request parameter. The actor is
|
||||
* injected with `set_param()` rather than by rewriting the request body, so the raw
|
||||
* body stays byte-identical and the signed `Digest` still verifies. Inbox POSTs read
|
||||
* JSON parameters first (see `request_parameter_order()`), so the value is visible to
|
||||
* both parameter validation and the handler via `get_json_params()`.
|
||||
*
|
||||
* Scoped to FeatureRequest, the only activity type known to address this way. Runs on
|
||||
* `rest_pre_dispatch` because that is the only hook that fires before required-parameter
|
||||
* validation. Signature verification still runs afterwards and remains authoritative:
|
||||
* the injected actor is derived from the very keyId the signature is checked against, so
|
||||
* it cannot be used to impersonate another actor.
|
||||
*
|
||||
* @since 9.0.0
|
||||
*
|
||||
* @param mixed $result Response to replace the request with, or null to continue.
|
||||
* @param \WP_REST_Server $server Server instance.
|
||||
* @param \WP_REST_Request $request The request object.
|
||||
*
|
||||
* @return mixed The unmodified `$result`.
|
||||
*/
|
||||
public static function maybe_add_actor_from_signature( $result, $server, $request ) {
|
||||
// Respect an earlier short-circuit.
|
||||
if ( null !== $result ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( \WP_REST_Server::CREATABLE !== $request->get_method() ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$route = $request->get_route();
|
||||
if (
|
||||
! \str_starts_with( $route, '/' . ACTIVITYPUB_REST_NAMESPACE ) ||
|
||||
! \str_ends_with( $route, '/inbox' )
|
||||
) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$json = $request->get_json_params();
|
||||
if ( ! \is_array( $json ) || 'FeatureRequest' !== ( $json['type'] ?? '' ) || ! empty( $json['actor'] ) ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$key_id = Signature::get_key_id( $request );
|
||||
if ( ! $key_id ) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$request->set_param( 'actor', \strip_fragment_from_url( $key_id ) );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the REST API response to properly handle the ActivityPub error formatting.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user