updated plugin ActivityPub
version 2.4.0
This commit is contained in:
@ -12,13 +12,13 @@ use Activitypub\Collection\Users as User_Collection;
|
||||
use function Activitypub\is_activitypub_request;
|
||||
|
||||
/**
|
||||
* ActivityPub Followers REST-Class
|
||||
* ActivityPub Actors REST-Class
|
||||
*
|
||||
* @author Matthias Pfefferle
|
||||
*
|
||||
* @see https://www.w3.org/TR/activitypub/#followers
|
||||
*/
|
||||
class Users {
|
||||
class Actors {
|
||||
/**
|
||||
* Initialize the class, registering WordPress hooks
|
||||
*/
|
||||
@ -32,7 +32,7 @@ class Users {
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
@ -45,7 +45,7 @@ class Users {
|
||||
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)/remote-follow',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)/remote-follow',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
@ -1,13 +1,12 @@
|
||||
<?php
|
||||
namespace Activitypub\Rest;
|
||||
|
||||
use WP_Error;
|
||||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\Transformer\Post;
|
||||
use Activitypub\Activity\Actor;
|
||||
use Activitypub\Activity\Base_Object;
|
||||
use Activitypub\Collection\Users as User_Collection;
|
||||
use Activitypub\Transformer\Factory;
|
||||
|
||||
use function Activitypub\esc_hashtag;
|
||||
use function Activitypub\is_single_user;
|
||||
@ -35,7 +34,7 @@ class Collection {
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)/collections/tags',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)/collections/tags',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
@ -48,7 +47,7 @@ class Collection {
|
||||
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)/collections/featured',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)/collections/featured',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
@ -104,7 +103,7 @@ class Collection {
|
||||
|
||||
$response = array(
|
||||
'@context' => Base_Object::JSON_LD_CONTEXT,
|
||||
'id' => get_rest_url_by_path( sprintf( 'users/%d/collections/tags', $user->get__id() ) ),
|
||||
'id' => get_rest_url_by_path( sprintf( 'actors/%d/collections/tags', $user->get__id() ) ),
|
||||
'type' => 'Collection',
|
||||
'totalItems' => is_countable( $tags ) ? count( $tags ) : 0,
|
||||
'items' => array(),
|
||||
@ -162,14 +161,20 @@ class Collection {
|
||||
|
||||
$response = array(
|
||||
'@context' => Base_Object::JSON_LD_CONTEXT,
|
||||
'id' => get_rest_url_by_path( sprintf( 'users/%d/collections/featured', $user_id ) ),
|
||||
'id' => get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $user_id ) ),
|
||||
'type' => 'OrderedCollection',
|
||||
'totalItems' => is_countable( $posts ) ? count( $posts ) : 0,
|
||||
'orderedItems' => array(),
|
||||
);
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$response['orderedItems'][] = Post::transform( $post )->to_object()->to_array( false );
|
||||
$transformer = Factory::get_transformer( $post );
|
||||
|
||||
if ( \is_wp_error( $transformer ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$response['orderedItems'][] = $transformer->to_object()->to_array( false );
|
||||
}
|
||||
|
||||
$rest_response = new WP_REST_Response( $response, 200 );
|
||||
|
@ -29,7 +29,7 @@ class Comment {
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/comments/(?P<comment_id>\d+)/remote-reply',
|
||||
'/(users|actors)/(?P<comment_id>\d+)/remote-reply',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
|
@ -32,7 +32,7 @@ class Followers {
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)/followers',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)/followers',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
@ -74,13 +74,13 @@ class Followers {
|
||||
|
||||
$json->{'@context'} = \Activitypub\get_context();
|
||||
|
||||
$json->id = get_rest_url_by_path( sprintf( 'users/%d/followers', $user->get__id() ) );
|
||||
$json->id = get_rest_url_by_path( sprintf( 'actors/%d/followers', $user->get__id() ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version();
|
||||
$json->actor = $user->get_id();
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
|
||||
$json->totalItems = $data['total']; // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/followers', $user->get__id() ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/followers', $user->get__id() ) ); // phpcs:ignore
|
||||
|
||||
$json->first = \add_query_arg( 'page', 1, $json->partOf ); // phpcs:ignore
|
||||
$json->last = \add_query_arg( 'page', \ceil ( $json->totalItems / $per_page ), $json->partOf ); // phpcs:ignore
|
||||
|
@ -31,7 +31,7 @@ class Following {
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)/following',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)/following',
|
||||
array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
@ -67,12 +67,12 @@ class Following {
|
||||
|
||||
$json->{'@context'} = \Activitypub\get_context();
|
||||
|
||||
$json->id = get_rest_url_by_path( sprintf( 'users/%d/following', $user->get__id() ) );
|
||||
$json->id = get_rest_url_by_path( sprintf( 'actors/%d/following', $user->get__id() ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version();
|
||||
$json->actor = $user->get_id();
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/following', $user->get__id() ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/following', $user->get__id() ) ); // phpcs:ignore
|
||||
|
||||
$items = apply_filters( 'activitypub_rest_following', array(), $user ); // phpcs:ignore
|
||||
|
||||
|
@ -48,7 +48,7 @@ class Inbox {
|
||||
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)/inbox',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)/inbox',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
@ -90,10 +90,10 @@ class Inbox {
|
||||
$json = new \stdClass();
|
||||
|
||||
$json->{'@context'} = get_context();
|
||||
$json->id = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user->get__id() ) );
|
||||
$json->id = get_rest_url_by_path( sprintf( 'actors/%d/inbox', $user->get__id() ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version();
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user->get__id() ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/inbox', $user->get__id() ) ); // phpcs:ignore
|
||||
$json->totalItems = 0; // phpcs:ignore
|
||||
$json->orderedItems = array(); // phpcs:ignore
|
||||
$json->first = $json->partOf; // phpcs:ignore
|
||||
|
@ -5,9 +5,9 @@ use stdClass;
|
||||
use WP_Error;
|
||||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\Transformer\Post;
|
||||
use Activitypub\Activity\Activity;
|
||||
use Activitypub\Collection\Users as User_Collection;
|
||||
use Activitypub\Transformer\Factory;
|
||||
|
||||
use function Activitypub\get_context;
|
||||
use function Activitypub\get_rest_url_by_path;
|
||||
@ -34,7 +34,7 @@ class Outbox {
|
||||
public static function register_routes() {
|
||||
\register_rest_route(
|
||||
ACTIVITYPUB_REST_NAMESPACE,
|
||||
'/users/(?P<user_id>[\w\-\.]+)/outbox',
|
||||
'/(users|actors)/(?P<user_id>[\w\-\.]+)/outbox',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
@ -72,11 +72,11 @@ class Outbox {
|
||||
$json = new stdClass();
|
||||
|
||||
$json->{'@context'} = get_context();
|
||||
$json->id = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user_id ) );
|
||||
$json->id = get_rest_url_by_path( sprintf( 'actors/%d/outbox', $user_id ) );
|
||||
$json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version();
|
||||
$json->actor = $user->get_id();
|
||||
$json->type = 'OrderedCollectionPage';
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user_id ) ); // phpcs:ignore
|
||||
$json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/outbox', $user_id ) ); // phpcs:ignore
|
||||
$json->totalItems = 0; // phpcs:ignore
|
||||
|
||||
if ( $user_id > 0 ) {
|
||||
@ -111,7 +111,13 @@ class Outbox {
|
||||
);
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$post = Post::transform( $post )->to_object();
|
||||
$transformer = Factory::get_transformer( $post );
|
||||
|
||||
if ( \is_wp_error( $transformer ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$post = $transformer->to_object();
|
||||
$activity = new Activity();
|
||||
$activity->set_type( 'Create' );
|
||||
$activity->set_object( $post );
|
||||
|
@ -5,7 +5,7 @@ use stdClass;
|
||||
use WP_Error;
|
||||
use WP_REST_Response;
|
||||
use Activitypub\Signature;
|
||||
use Activitypub\Model\Application_User;
|
||||
use Activitypub\Model\Application;
|
||||
|
||||
/**
|
||||
* ActivityPub Server REST-Class
|
||||
@ -47,7 +47,7 @@ class Server {
|
||||
* @return WP_REST_Response The JSON profile of the Application Actor.
|
||||
*/
|
||||
public static function application_actor() {
|
||||
$user = new Application_User();
|
||||
$user = new Application();
|
||||
|
||||
$json = $user->to_array();
|
||||
|
||||
@ -62,6 +62,9 @@ class Server {
|
||||
*
|
||||
* @see WP_REST_Request
|
||||
*
|
||||
* @see https://www.w3.org/wiki/SocialCG/ActivityPub/Primer/Authentication_Authorization#Authorized_fetch
|
||||
* @see https://swicg.github.io/activitypub-http-signature/#authorized-fetch
|
||||
*
|
||||
* @param WP_REST_Response|WP_HTTP_Response|WP_Error|mixed $response Result to send to the client.
|
||||
* Usually a WP_REST_Response or WP_Error.
|
||||
* @param array $handler Route handler used for the request.
|
||||
@ -80,7 +83,8 @@ class Server {
|
||||
if (
|
||||
! \str_starts_with( $route, '/' . ACTIVITYPUB_REST_NAMESPACE ) ||
|
||||
\str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'webfinger' ) ||
|
||||
\str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'nodeinfo' )
|
||||
\str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'nodeinfo' ) ||
|
||||
\str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'application' )
|
||||
) {
|
||||
return $response;
|
||||
}
|
||||
@ -102,17 +106,12 @@ class Server {
|
||||
return $response;
|
||||
}
|
||||
|
||||
// POST-Requets are always signed
|
||||
if ( 'GET' !== $request->get_method() ) {
|
||||
$verified_request = Signature::verify_http_signature( $request );
|
||||
if ( \is_wp_error( $verified_request ) ) {
|
||||
return new WP_Error(
|
||||
'activitypub_signature_verification',
|
||||
$verified_request->get_error_message(),
|
||||
array( 'status' => 401 )
|
||||
);
|
||||
}
|
||||
} elseif ( 'GET' === $request->get_method() && ACTIVITYPUB_AUTHORIZED_FETCH ) { // GET-Requests are only signed in secure mode
|
||||
if (
|
||||
// POST-Requests are always signed
|
||||
'GET' !== $request->get_method() ||
|
||||
// GET-Requests only require a signature in secure mode
|
||||
( 'GET' === $request->get_method() && ACTIVITYPUB_AUTHORIZED_FETCH )
|
||||
) {
|
||||
$verified_request = Signature::verify_http_signature( $request );
|
||||
if ( \is_wp_error( $verified_request ) ) {
|
||||
return new WP_Error(
|
||||
|
Reference in New Issue
Block a user