refactorings

This commit is contained in:
Matthias Pfefferle 2019-11-18 20:57:00 +01:00
parent 60e9c8554c
commit 65034d2a76
15 changed files with 167 additions and 75 deletions

View file

@ -23,15 +23,15 @@ function init() {
require_once dirname( __FILE__ ) . '/includes/table/followers-list.php'; require_once dirname( __FILE__ ) . '/includes/table/followers-list.php';
require_once dirname( __FILE__ ) . '/includes/class-signature.php'; require_once dirname( __FILE__ ) . '/includes/class-signature.php';
require_once dirname( __FILE__ ) . '/includes/class-activity.php'; require_once dirname( __FILE__ ) . '/includes/peer/class-followers.php';
require_once dirname( __FILE__ ) . '/includes/db/class-followers.php';
require_once dirname( __FILE__ ) . '/includes/functions.php'; require_once dirname( __FILE__ ) . '/includes/functions.php';
require_once dirname( __FILE__ ) . '/includes/class-activity-dispatcher.php'; require_once dirname( __FILE__ ) . '/includes/class-activity-dispatcher.php';
\Activitypub\Activity_Dispatcher::init(); \Activitypub\Activity_Dispatcher::init();
require_once dirname( __FILE__ ) . '/includes/class-post.php'; require_once dirname( __FILE__ ) . '/includes/model/class-activity.php';
\Activitypub\Post::init(); require_once dirname( __FILE__ ) . '/includes/model/class-post.php';
\Activitypub\Model\Post::init();
require_once dirname( __FILE__ ) . '/includes/class-activitypub.php'; require_once dirname( __FILE__ ) . '/includes/class-activitypub.php';
\Activitypub\Activitypub::init(); \Activitypub\Activitypub::init();

View file

@ -15,7 +15,7 @@ class Activity_Dispatcher {
public static function init() { public static function init() {
\add_action( 'activitypub_send_post_activity', array( '\Activitypub\Activity_Dispatcher', 'send_post_activity' ) ); \add_action( 'activitypub_send_post_activity', array( '\Activitypub\Activity_Dispatcher', 'send_post_activity' ) );
\add_action( 'activitypub_send_update_activity', array( '\Activitypub\Activity_Dispatcher', 'send_update_activity' ) ); \add_action( 'activitypub_send_update_activity', array( '\Activitypub\Activity_Dispatcher', 'send_update_activity' ) );
//\add_action( 'activitypub_send_delete_activity', array( '\Activitypub\Activity_Dispatcher', 'send_delete_activity' ) ); \add_action( 'activitypub_send_delete_activity', array( '\Activitypub\Activity_Dispatcher', 'send_delete_activity' ) );
} }
/** /**
@ -27,8 +27,8 @@ class Activity_Dispatcher {
$post = \get_post( $post_id ); $post = \get_post( $post_id );
$user_id = $post->post_author; $user_id = $post->post_author;
$activitypub_post = new \Activitypub\Post( $post ); $activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Create', \Activitypub\Activity::TYPE_FULL ); $activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
$activitypub_activity->from_post( $activitypub_post->to_array() ); $activitypub_activity->from_post( $activitypub_post->to_array() );
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) { foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
@ -48,8 +48,8 @@ class Activity_Dispatcher {
$post = \get_post( $post_id ); $post = \get_post( $post_id );
$user_id = $post->post_author; $user_id = $post->post_author;
$activitypub_post = new \Activitypub\Post( $post ); $activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Update', \Activitypub\Activity::TYPE_FULL ); $activitypub_activity = new \Activitypub\Model\Activity( 'Update', \Activitypub\Model\Activity::TYPE_FULL );
$activitypub_activity->from_post( $activitypub_post->to_array() ); $activitypub_activity->from_post( $activitypub_post->to_array() );
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) { foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
@ -69,8 +69,8 @@ class Activity_Dispatcher {
$post = \get_post( $post_id ); $post = \get_post( $post_id );
$user_id = $post->post_author; $user_id = $post->post_author;
$activitypub_post = new \Activitypub\Post( $post ); $activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Delete', \Activitypub\Activity::TYPE_FULL ); $activitypub_activity = new \Activitypub\Model\Activity( 'Delete', \Activitypub\Model\Activity::TYPE_FULL );
$activitypub_activity->from_post( $activitypub_post->to_array() ); $activitypub_activity->from_post( $activitypub_post->to_array() );
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) { foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {

View file

@ -12,28 +12,8 @@ function get_context() {
'https://w3id.org/security/v1', 'https://w3id.org/security/v1',
array( array(
'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
'sensitive' => 'as:sensitive',
'movedTo' => array(
'@id' => 'as:movedTo',
'@type' => '@id',
),
'Hashtag' => 'as:Hashtag',
'ostatus' => 'http://ostatus.org#',
'atomUri' => 'ostatus:atomUri',
'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri',
'conversation' => 'ostatus:conversation',
'toot' => 'http://joinmastodon.org/ns#',
'Emoji' => 'toot:Emoji',
'focalPoint' => array(
'@container' => '@list',
'@id' => 'toot:focalPoint',
),
'featured' => array(
'@id' => 'toot:featured',
'@type' => '@id',
),
'schema' => 'http://schema.org#',
'PropertyValue' => 'schema:PropertyValue', 'PropertyValue' => 'schema:PropertyValue',
'schema' => 'http://schema.org#',
'value' => 'schema:value', 'value' => 'schema:value',
), ),
); );
@ -185,7 +165,7 @@ function get_publickey_by_actor( $actor, $key_id ) {
} }
function get_follower_inboxes( $user_id ) { function get_follower_inboxes( $user_id ) {
$followers = \Activitypub\Db\Followers::get_followers( $user_id ); $followers = \Activitypub\Peer\Followers::get_followers( $user_id );
$inboxes = array(); $inboxes = array();
foreach ( $followers as $follower ) { foreach ( $followers as $follower ) {
@ -223,7 +203,7 @@ function get_identifier_settings( $user_id ) {
} }
function get_followers( $user_id ) { function get_followers( $user_id ) {
$followers = \Activitypub\Db\Followers::get_followers( $user_id ); $followers = \Activitypub\Peer\Followers::get_followers( $user_id );
if ( ! $followers ) { if ( ! $followers ) {
return array(); return array();
@ -237,3 +217,51 @@ function count_followers( $user_id ) {
return \count( $followers ); return \count( $followers );
} }
/**
* Examine a url and try to determine the author ID it represents.
*
* Checks are supposedly from the hosted site blog.
*
* @param string $url Permalink to check.
*
* @return int User ID, or 0 on failure.
*/
function url_to_authorid( $url ) {
global $wp_rewrite;
// check if url hase the same host
if ( wp_parse_url( site_url(), PHP_URL_HOST ) !== wp_parse_url( $url, PHP_URL_HOST ) ) {
return 0;
}
// first, check to see if there is a 'author=N' to match against
if ( preg_match( '/[?&]author=(\d+)/i', $url, $values ) ) {
$id = absint( $values[1] );
if ( $id ) {
return $id;
}
}
// check to see if we are using rewrite rules
$rewrite = $wp_rewrite->wp_rewrite_rules();
// not using rewrite rules, and 'author=N' method failed, so we're out of options
if ( empty( $rewrite ) ) {
return 0;
}
// generate rewrite rule for the author url
$author_rewrite = $wp_rewrite->get_author_permastruct();
$author_regexp = str_replace( '%author%', '', $author_rewrite );
// match the rewrite rule with the passed url
if ( preg_match( '/https?:\/\/(.+)' . preg_quote( $author_regexp, '/' ) . '([^\/]+)/i', $url, $match ) ) {
$user = get_user_by( 'slug', $match[2] );
if ( $user ) {
return $user->ID;
}
}
return 0;
}

View file

@ -1,5 +1,5 @@
<?php <?php
namespace Activitypub; namespace Activitypub\Model;
/** /**
* ActivityPub Post Class * ActivityPub Post Class

View file

@ -1,5 +1,5 @@
<?php <?php
namespace Activitypub; namespace Activitypub\Model;
/** /**
* ActivityPub Post Class * ActivityPub Post Class
@ -13,8 +13,8 @@ class Post {
* Initialize the class, registering WordPress hooks * Initialize the class, registering WordPress hooks
*/ */
public static function init() { public static function init() {
\add_filter( 'activitypub_the_summary', array( '\Activitypub\Post', 'add_backlink_to_content' ), 15, 2 ); \add_filter( 'activitypub_the_summary', array( '\Activitypub\Model\Post', 'add_backlink_to_content' ), 15, 2 );
\add_filter( 'activitypub_the_content', array( '\Activitypub\Post', 'add_backlink_to_content' ), 15, 2 ); \add_filter( 'activitypub_the_content', array( '\Activitypub\Model\Post', 'add_backlink_to_content' ), 15, 2 );
} }
public function __construct( $post = null ) { public function __construct( $post = null ) {

View file

@ -1,5 +1,5 @@
<?php <?php
namespace Activitypub\Db; namespace Activitypub\Peer;
/** /**
* ActivityPub Followers DB-Class * ActivityPub Followers DB-Class

View file

@ -62,7 +62,7 @@ class Followers {
$json->partOf = \get_rest_url( null, "/activitypub/1.0/users/$user_id/followers" ); // phpcs:ignore $json->partOf = \get_rest_url( null, "/activitypub/1.0/users/$user_id/followers" ); // phpcs:ignore
$json->totalItems = \Activitypub\count_followers( $user_id ); // phpcs:ignore $json->totalItems = \Activitypub\count_followers( $user_id ); // phpcs:ignore
$json->orderedItems = \Activitypub\Db\Followers::get_followers( $user_id ); // phpcs:ignore $json->orderedItems = \Activitypub\Peer\Followers::get_followers( $user_id ); // phpcs:ignore
$json->first = $json->partOf; // phpcs:ignore $json->first = $json->partOf; // phpcs:ignore

View file

@ -30,7 +30,7 @@ class Inbox {
'activitypub/1.0', '/inbox', array( 'activitypub/1.0', '/inbox', array(
array( array(
'methods' => \WP_REST_Server::EDITABLE, 'methods' => \WP_REST_Server::EDITABLE,
'callback' => array( '\Activitypub\Rest\Inbox', 'global_inbox' ), 'callback' => array( '\Activitypub\Rest\Inbox', 'shared_inbox' ),
), ),
) )
); );
@ -87,7 +87,6 @@ class Inbox {
*/ */
public static function user_inbox( $request ) { public static function user_inbox( $request ) {
$author_id = $request->get_param( 'id' ); $author_id = $request->get_param( 'id' );
$author = \get_user_by( 'ID', $author_id );
$data = \json_decode( $request->get_body(), true ); $data = \json_decode( $request->get_body(), true );
@ -113,9 +112,62 @@ class Inbox {
* *
* @return WP_Error not yet implemented * @return WP_Error not yet implemented
*/ */
public static function global_inbox( $request ) { public static function shared_inbox( $request ) {
// Create the response object $data = \json_decode( $request->get_body(), true );
return new \WP_Error( 'rest_not_implemented', \__( 'This method is not yet implemented', 'activitypub' ), array( 'status' => 501 ) );
if ( empty( $data['to'] ) ) {
return new \WP_Error( 'rest_invalid_data', \__( 'No receiving actor set', 'activitypub' ), array( 'status' => 422 ) );
}
if ( \filter_var( $data['to'], \FILTER_VALIDATE_URL ) ) {
$author_id = \Activitypub\url_to_authorid( $data['to'] );
if ( ! $author_id ) {
return new \WP_Error( 'rest_invalid_data', \__( 'No matching user', 'activitypub' ), array( 'status' => 422 ) );
}
} else {
// get the identifier at the left of the '@'
$parts = \explode( '@', $data['to'] );
if ( 3 === \count( $parts ) ) {
$username = $parts[1];
$host = $parts[2];
} elseif ( 2 === \count( $parts ) ) {
$username = $parts[0];
$host = $parts[1];
}
if ( ! $username || ! $host ) {
return new \WP_Error( 'rest_invalid_data', \__( 'Invalid actor identifier', 'activitypub' ), array( 'status' => 422 ) );
}
// check domain
if ( ! \wp_parse_url( \home_url(), \PHP_URL_HOST ) !== $host ) {
return new \WP_Error( 'rest_invalid_data', \__( 'Invalid host', 'activitypub' ), array( 'status' => 422 ) );
}
$author = \get_user_by( 'login', $username );
if ( ! $author ) {
return new \WP_Error( 'rest_invalid_data', \__( 'No matching user', 'activitypub' ), array( 'status' => 422 ) );
}
$author_id = $author->ID;
}
$type = 'create';
if ( ! empty( $data['type'] ) ) {
$type = \strtolower( $data['type'] );
}
if ( ! \is_array( $data ) || ! \array_key_exists( 'type', $data ) ) {
return new \WP_Error( 'rest_invalid_data', \__( 'Invalid payload', 'activitypub' ), array( 'status' => 422 ) );
}
\do_action( 'activitypub_inbox', $data, $author_id, $type );
\do_action( "activitypub_inbox_{$type}", $data, $author_id );
return new \WP_REST_Response( array(), 202 );
} }
/** /**
@ -150,13 +202,13 @@ class Inbox {
} }
// save follower // save follower
\Activitypub\Db\Followers::add_follower( $object['actor'], $user_id ); \Activitypub\Peer\Followers::add_follower( $object['actor'], $user_id );
// get inbox // get inbox
$inbox = \Activitypub\get_inbox_by_actor( $object['actor'] ); $inbox = \Activitypub\get_inbox_by_actor( $object['actor'] );
// send "Accept" activity // send "Accept" activity
$activity = new \Activitypub\Activity( 'Accept', \Activitypub\Activity::TYPE_SIMPLE ); $activity = new \Activitypub\Model\Activity( 'Accept', \Activitypub\Model\Activity::TYPE_SIMPLE );
$activity->set_object( $object ); $activity->set_object( $object );
$activity->set_actor( \get_author_posts_url( $user_id ) ); $activity->set_actor( \get_author_posts_url( $user_id ) );
$activity->set_to( $object['actor'] ); $activity->set_to( $object['actor'] );
@ -178,7 +230,7 @@ class Inbox {
return new \WP_Error( 'activitypub_no_actor', \__( 'No "Actor" found', 'activitypub' ) ); return new \WP_Error( 'activitypub_no_actor', \__( 'No "Actor" found', 'activitypub' ) );
} }
\Activitypub\Db\Followers::remove_follower( $object['actor'], $user_id ); \Activitypub\Peer\Followers::remove_follower( $object['actor'], $user_id );
} }
/** /**

View file

@ -83,8 +83,8 @@ class Outbox {
} }
foreach ( $posts as $post ) { foreach ( $posts as $post ) {
$activitypub_post = new \Activitypub\Post( $post ); $activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Create', \Activitypub\Activity::TYPE_NONE ); $activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_NONE );
$activitypub_activity->from_post( $activitypub_post->to_array() ); $activitypub_activity->from_post( $activitypub_post->to_array() );
$json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore $json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore
} }

View file

@ -25,7 +25,7 @@ class Followers_List extends \WP_List_Table {
$this->items = array(); $this->items = array();
foreach ( \Activitypub\Db\Followers::get_followers( \get_current_user_id() ) as $follower ) { foreach ( \Activitypub\Peer\Followers::get_followers( \get_current_user_id() ) as $follower ) {
$this->items[]['identifier'] = \esc_attr( $follower ); $this->items[]['identifier'] = \esc_attr( $follower );
} }
} }

View file

@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: ActivityPub 0.8.3\n" "Project-Id-Version: ActivityPub 0.8.3\n"
"Report-Msgid-Bugs-To: " "Report-Msgid-Bugs-To: "
"https://wordpress.org/support/plugin/wordpress-activitypub\n" "https://wordpress.org/support/plugin/wordpress-activitypub\n"
"POT-Creation-Date: 2019-09-30 06:07:59+00:00\n" "POT-Creation-Date: 2019-11-18 19:51:49+00:00\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
@ -88,35 +88,35 @@ msgstr ""
msgid "Fediverse" msgid "Fediverse"
msgstr "" msgstr ""
#: includes/db/class-followers.php:53 #: includes/functions.php:84
msgid "Unknown Actor schema"
msgstr ""
#: includes/functions.php:104
msgid "The \"actor\" is no valid URL" msgid "The \"actor\" is no valid URL"
msgstr "" msgstr ""
#: includes/functions.php:130 #: includes/functions.php:110
msgid "No valid JSON data" msgid "No valid JSON data"
msgstr "" msgstr ""
#: includes/functions.php:158 #: includes/functions.php:138
msgid "No \"Inbox\" found" msgid "No \"Inbox\" found"
msgstr "" msgstr ""
#: includes/functions.php:184 #: includes/functions.php:164
msgid "No \"Public-Key\" found" msgid "No \"Public-Key\" found"
msgstr "" msgstr ""
#: includes/functions.php:212 #: includes/functions.php:192
msgid "Profile identifier" msgid "Profile identifier"
msgstr "" msgstr ""
#: includes/functions.php:217 #: includes/functions.php:197
#. translators: the webfinger resource #. translators: the webfinger resource
msgid "Try to follow \"@%s\" in the Mastodon/Friendica search field." msgid "Try to follow \"@%s\" in the Mastodon/Friendica search field."
msgstr "" msgstr ""
#: includes/peer/class-followers.php:53
msgid "Unknown Actor schema"
msgstr ""
#: includes/rest/class-followers.php:46 includes/rest/class-followers.php:49 #: includes/rest/class-followers.php:46 includes/rest/class-followers.php:49
#: includes/rest/class-following.php:46 includes/rest/class-following.php:49 #: includes/rest/class-following.php:46 includes/rest/class-following.php:49
#: includes/rest/class-outbox.php:45 includes/rest/class-outbox.php:48 #: includes/rest/class-outbox.php:45 includes/rest/class-outbox.php:48
@ -124,16 +124,28 @@ msgstr ""
msgid "User not found" msgid "User not found"
msgstr "" msgstr ""
#: includes/rest/class-inbox.php:100 #: includes/rest/class-inbox.php:99 includes/rest/class-inbox.php:164
msgid "Invalid payload" msgid "Invalid payload"
msgstr "" msgstr ""
#: includes/rest/class-inbox.php:118 #: includes/rest/class-inbox.php:119
msgid "This method is not yet implemented" msgid "No receiving actor set"
msgstr "" msgstr ""
#: includes/rest/class-inbox.php:149 includes/rest/class-inbox.php:178 #: includes/rest/class-inbox.php:126 includes/rest/class-inbox.php:152
#: includes/rest/class-inbox.php:192 includes/rest/class-inbox.php:229 msgid "No matching user"
msgstr ""
#: includes/rest/class-inbox.php:141
msgid "Invalid actor identifier"
msgstr ""
#: includes/rest/class-inbox.php:146
msgid "Invalid host"
msgstr ""
#: includes/rest/class-inbox.php:201 includes/rest/class-inbox.php:230
#: includes/rest/class-inbox.php:244 includes/rest/class-inbox.php:281
msgid "No \"Actor\" found" msgid "No \"Actor\" found"
msgstr "" msgstr ""

View file

@ -1,7 +1,7 @@
<div class="wrap"> <div class="wrap">
<h1><?php \esc_html_e( 'Followers (Fediverse)', 'activitypub' ); ?></h1> <h1><?php \esc_html_e( 'Followers (Fediverse)', 'activitypub' ); ?></h1>
<p><?php \printf( \__( 'You currently have %s followers.', 'activitypub' ), \esc_attr( \Activitypub\Db\Followers::count_followers( \get_current_user_id() ) ) ); ?></p> <p><?php \printf( \__( 'You currently have %s followers.', 'activitypub' ), \esc_attr( \Activitypub\Peer\Followers::count_followers( \get_current_user_id() ) ) ); ?></p>
<?php $token_table = new \Activitypub\Table\Followers_List(); ?> <?php $token_table = new \Activitypub\Table\Followers_List(); ?>

View file

@ -75,9 +75,9 @@ if ( \get_the_author_meta( 'user_url', $author_id ) ) {
); );
} }
//$json->endpoints = array( $json->endpoints = array(
// 'sharedInbox' => \get_rest_url( null, '/activitypub/1.0/inbox' ), 'sharedInbox' => \get_rest_url( null, '/activitypub/1.0/inbox' ),
//); );
// filter output // filter output
$json = \apply_filters( 'activitypub_json_author_array', $json ); $json = \apply_filters( 'activitypub_json_author_array', $json );

View file

@ -1,7 +1,7 @@
<?php <?php
$post = \get_post(); $post = \get_post();
$activitypub_post = new \Activitypub\Post( $post ); $activitypub_post = new \Activitypub\Model\Post( $post );
$json = \array_merge( array( '@context' => \Activitypub\get_context() ), $activitypub_post->to_array() ); $json = \array_merge( array( '@context' => \Activitypub\get_context() ), $activitypub_post->to_array() );
// filter output // filter output

View file

@ -9,7 +9,7 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
); );
update_user_meta( 1, 'activitypub_followers', $followers ); update_user_meta( 1, 'activitypub_followers', $followers );
$db_followers = \Activitypub\Db\Followers::get_followers( 1 ); $db_followers = \Activitypub\Peer\Followers::get_followers( 1 );
$this->assertEquals( 3, count( $db_followers ) ); $this->assertEquals( 3, count( $db_followers ) );
@ -18,9 +18,9 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
public function test_add_follower() { public function test_add_follower() {
$follower = 'https://example.com/author/' . time(); $follower = 'https://example.com/author/' . time();
\Activitypub\Db\Followers::add_follower( $follower, 1 ); \Activitypub\Peer\Followers::add_follower( $follower, 1 );
$db_followers = \Activitypub\Db\Followers::get_followers( 1 ); $db_followers = \Activitypub\Peer\Followers::get_followers( 1 );
$this->assertContains( $follower, $db_followers ); $this->assertContains( $follower, $db_followers );
} }