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/class-signature.php';
require_once dirname( __FILE__ ) . '/includes/class-activity.php';
require_once dirname( __FILE__ ) . '/includes/db/class-followers.php';
require_once dirname( __FILE__ ) . '/includes/peer/class-followers.php';
require_once dirname( __FILE__ ) . '/includes/functions.php';
require_once dirname( __FILE__ ) . '/includes/class-activity-dispatcher.php';
\Activitypub\Activity_Dispatcher::init();
require_once dirname( __FILE__ ) . '/includes/class-post.php';
\Activitypub\Post::init();
require_once dirname( __FILE__ ) . '/includes/model/class-activity.php';
require_once dirname( __FILE__ ) . '/includes/model/class-post.php';
\Activitypub\Model\Post::init();
require_once dirname( __FILE__ ) . '/includes/class-activitypub.php';
\Activitypub\Activitypub::init();

View file

@ -15,7 +15,7 @@ class Activity_Dispatcher {
public static function init() {
\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_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 );
$user_id = $post->post_author;
$activitypub_post = new \Activitypub\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Create', \Activitypub\Activity::TYPE_FULL );
$activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_FULL );
$activitypub_activity->from_post( $activitypub_post->to_array() );
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
@ -48,8 +48,8 @@ class Activity_Dispatcher {
$post = \get_post( $post_id );
$user_id = $post->post_author;
$activitypub_post = new \Activitypub\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Update', \Activitypub\Activity::TYPE_FULL );
$activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Model\Activity( 'Update', \Activitypub\Model\Activity::TYPE_FULL );
$activitypub_activity->from_post( $activitypub_post->to_array() );
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {
@ -69,8 +69,8 @@ class Activity_Dispatcher {
$post = \get_post( $post_id );
$user_id = $post->post_author;
$activitypub_post = new \Activitypub\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Delete', \Activitypub\Activity::TYPE_FULL );
$activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Model\Activity( 'Delete', \Activitypub\Model\Activity::TYPE_FULL );
$activitypub_activity->from_post( $activitypub_post->to_array() );
foreach ( \Activitypub\get_follower_inboxes( $user_id ) as $inbox => $to ) {

View file

@ -12,28 +12,8 @@ function get_context() {
'https://w3id.org/security/v1',
array(
'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',
'schema' => 'http://schema.org#',
'value' => 'schema:value',
),
);
@ -185,7 +165,7 @@ function get_publickey_by_actor( $actor, $key_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();
foreach ( $followers as $follower ) {
@ -223,7 +203,7 @@ function get_identifier_settings( $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 ) {
return array();
@ -237,3 +217,51 @@ function count_followers( $user_id ) {
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
namespace Activitypub;
namespace Activitypub\Model;
/**
* ActivityPub Post Class

View file

@ -1,5 +1,5 @@
<?php
namespace Activitypub;
namespace Activitypub\Model;
/**
* ActivityPub Post Class
@ -13,8 +13,8 @@ class Post {
* Initialize the class, registering WordPress hooks
*/
public static function init() {
\add_filter( 'activitypub_the_summary', array( '\Activitypub\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_summary', array( '\Activitypub\Model\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 ) {

View file

@ -1,5 +1,5 @@
<?php
namespace Activitypub\Db;
namespace Activitypub\Peer;
/**
* 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->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

View file

@ -30,7 +30,7 @@ class Inbox {
'activitypub/1.0', '/inbox', array(
array(
'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 ) {
$author_id = $request->get_param( 'id' );
$author = \get_user_by( 'ID', $author_id );
$data = \json_decode( $request->get_body(), true );
@ -113,9 +112,62 @@ class Inbox {
*
* @return WP_Error not yet implemented
*/
public static function global_inbox( $request ) {
// Create the response object
return new \WP_Error( 'rest_not_implemented', \__( 'This method is not yet implemented', 'activitypub' ), array( 'status' => 501 ) );
public static function shared_inbox( $request ) {
$data = \json_decode( $request->get_body(), true );
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
\Activitypub\Db\Followers::add_follower( $object['actor'], $user_id );
\Activitypub\Peer\Followers::add_follower( $object['actor'], $user_id );
// get inbox
$inbox = \Activitypub\get_inbox_by_actor( $object['actor'] );
// 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_actor( \get_author_posts_url( $user_id ) );
$activity->set_to( $object['actor'] );
@ -178,7 +230,7 @@ class Inbox {
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 ) {
$activitypub_post = new \Activitypub\Post( $post );
$activitypub_activity = new \Activitypub\Activity( 'Create', \Activitypub\Activity::TYPE_NONE );
$activitypub_post = new \Activitypub\Model\Post( $post );
$activitypub_activity = new \Activitypub\Model\Activity( 'Create', \Activitypub\Model\Activity::TYPE_NONE );
$activitypub_activity->from_post( $activitypub_post->to_array() );
$json->orderedItems[] = $activitypub_activity->to_array(); // phpcs:ignore
}

View file

@ -25,7 +25,7 @@ class Followers_List extends \WP_List_Table {
$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 );
}
}

View file

@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: ActivityPub 0.8.3\n"
"Report-Msgid-Bugs-To: "
"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"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -88,35 +88,35 @@ msgstr ""
msgid "Fediverse"
msgstr ""
#: includes/db/class-followers.php:53
msgid "Unknown Actor schema"
msgstr ""
#: includes/functions.php:104
#: includes/functions.php:84
msgid "The \"actor\" is no valid URL"
msgstr ""
#: includes/functions.php:130
#: includes/functions.php:110
msgid "No valid JSON data"
msgstr ""
#: includes/functions.php:158
#: includes/functions.php:138
msgid "No \"Inbox\" found"
msgstr ""
#: includes/functions.php:184
#: includes/functions.php:164
msgid "No \"Public-Key\" found"
msgstr ""
#: includes/functions.php:212
#: includes/functions.php:192
msgid "Profile identifier"
msgstr ""
#: includes/functions.php:217
#: includes/functions.php:197
#. translators: the webfinger resource
msgid "Try to follow \"@%s\" in the Mastodon/Friendica search field."
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-following.php:46 includes/rest/class-following.php:49
#: includes/rest/class-outbox.php:45 includes/rest/class-outbox.php:48
@ -124,16 +124,28 @@ msgstr ""
msgid "User not found"
msgstr ""
#: includes/rest/class-inbox.php:100
#: includes/rest/class-inbox.php:99 includes/rest/class-inbox.php:164
msgid "Invalid payload"
msgstr ""
#: includes/rest/class-inbox.php:118
msgid "This method is not yet implemented"
#: includes/rest/class-inbox.php:119
msgid "No receiving actor set"
msgstr ""
#: includes/rest/class-inbox.php:149 includes/rest/class-inbox.php:178
#: includes/rest/class-inbox.php:192 includes/rest/class-inbox.php:229
#: includes/rest/class-inbox.php:126 includes/rest/class-inbox.php:152
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"
msgstr ""

View file

@ -1,7 +1,7 @@
<div class="wrap">
<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(); ?>

View file

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

View file

@ -1,7 +1,7 @@
<?php
$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() );
// filter output

View file

@ -9,7 +9,7 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
);
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 ) );
@ -18,9 +18,9 @@ class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
public function test_add_follower() {
$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 );
}