From 1fe67d826b812bdd18d856db0fa0df7996a45a70 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 12 Mar 2024 08:54:05 +0100 Subject: [PATCH 1/4] init --- includes/class-activitypub.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index e73a9af6..204cdd7e 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -453,4 +453,21 @@ private static function register_post_types() { \do_action( 'activitypub_after_register_post_type' ); } + + public static function generate_blog_user() { + $user_pass = wp_generate_password( 15, true, true ); + + // check if domain host has a subdomain + $host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST ); + $host = \preg_replace( '/^www\./i', '', $host ); + + $user_id = wp_insert_user( + array( + 'user_login' => $host, + 'user_pass' => $user_pass, + 'description' => \get_bloginfo( 'description' ), + 'role' => '', + ) + ); + } } From 360463db23458a2facde28eb2868e1c7e6652431 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 12 Mar 2024 09:00:36 +0100 Subject: [PATCH 2/4] fix phpcs --- includes/class-activitypub.php | 19 +------------------ includes/class-migration.php | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/includes/class-activitypub.php b/includes/class-activitypub.php index 4f60615d..442cdfa5 100644 --- a/includes/class-activitypub.php +++ b/includes/class-activitypub.php @@ -458,7 +458,7 @@ private static function register_post_types() { \do_action( 'activitypub_after_register_post_type' ); } - /** + /** * Add the 'activitypub' query variable so WordPress won't mangle it. * * @param int $user_id User ID. @@ -470,21 +470,4 @@ public static function user_register( $user_id ) { $user->add_cap( 'activitypub' ); } } - - public static function generate_blog_user() { - $user_pass = wp_generate_password( 15, true, true ); - - // check if domain host has a subdomain - $host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST ); - $host = \preg_replace( '/^www\./i', '', $host ); - - $user_id = wp_insert_user( - array( - 'user_login' => $host, - 'user_pass' => $user_pass, - 'description' => \get_bloginfo( 'description' ), - 'role' => '', - ) - ); - } } diff --git a/includes/class-migration.php b/includes/class-migration.php index 52624c46..faaa8e9d 100644 --- a/includes/class-migration.php +++ b/includes/class-migration.php @@ -284,4 +284,21 @@ private static function add_activitypub_capability() { $user->add_cap( 'activitypub' ); } } + + public static function generate_blog_user() { + $user_pass = wp_generate_password( 15, true, true ); + + // check if domain host has a subdomain + $host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST ); + $host = \preg_replace( '/^www\./i', '', $host ); + + $user_id = wp_insert_user( + array( + 'user_login' => $host, + 'user_pass' => $user_pass, + 'description' => \get_bloginfo( 'description' ), + 'role' => '', + ) + ); + } } From 57d5c1d1fc7fac0f1421d01107ca13bbc7571c6b Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 12 Mar 2024 13:37:02 +0100 Subject: [PATCH 3/4] rewrite user models to a transformer --- activitypub.php | 4 +- includes/activity/class-actor.php | 61 ++++++ includes/class-migration.php | 54 +---- includes/class-setup.php | 133 ++++++++++++ includes/collection/class-users.php | 34 ++- includes/rest/class-webfinger.php | 14 +- includes/transformer/class-base.php | 13 ++ includes/transformer/class-user.php | 307 ++++++++++++++++++++++++++++ integration/class-webfinger.php | 16 +- templates/author-json.php | 9 +- templates/blog-json.php | 15 -- 11 files changed, 569 insertions(+), 91 deletions(-) create mode 100644 includes/class-setup.php create mode 100644 includes/transformer/class-user.php delete mode 100644 templates/blog-json.php diff --git a/activitypub.php b/activitypub.php index e4ac2960..52c80fcc 100644 --- a/activitypub.php +++ b/activitypub.php @@ -71,7 +71,6 @@ function rest_init() { * Initialize plugin. */ function plugin_init() { - \add_action( 'init', array( __NAMESPACE__ . '\Migration', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activitypub', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Activity_Dispatcher', 'init' ) ); \add_action( 'init', array( __NAMESPACE__ . '\Handler', 'init' ) ); @@ -103,6 +102,9 @@ function plugin_init() { } \add_action( 'plugins_loaded', __NAMESPACE__ . '\plugin_init' ); +\add_action( 'init', array( __NAMESPACE__ . '\Migration', 'init' ) ); +\add_action( 'activate_blog', array( __NAMESPACE__ . '\Setup', 'init' ) ); +\add_action( 'wp_initialize_site', array( __NAMESPACE__ . '\Setup', 'init' ) ); /** * Class Autoloader diff --git a/includes/activity/class-actor.php b/includes/activity/class-actor.php index 1751aa29..2c5721b8 100644 --- a/includes/activity/class-actor.php +++ b/includes/activity/class-actor.php @@ -171,4 +171,65 @@ class Actor extends Base_Object { * @var boolean */ protected $manually_approves_followers = false; + + /** + * The Featured-Posts. + * + * @see https://docs.joinmastodon.org/spec/activitypub/#featured + * + * @context { + * "@id": "http://joinmastodon.org/ns#featured", + * "@type": "@id" + * } + * + * @var string + */ + protected $featured; + + /** + * Moderators endpoint. + * + * @see https://join-lemmy.org/docs/contributors/05-federation.html + * + * @var string + */ + protected $moderators; + + /** + * If the User is discoverable. + * + * @see https://docs.joinmastodon.org/spec/activitypub/#discoverable + * + * @context http://joinmastodon.org/ns#discoverable + * + * @var boolean + */ + protected $discoverable = true; + + /** + * If the User is indexable. + * + * @context http://joinmastodon.org/ns#indexable + * + * @var boolean + */ + protected $indexable; + + /** + * The WebFinger Resource. + * + * @see https://codeberg.org/fediverse/fep/src/branch/main/fep/2c59/fep-2c59.md + * + * @var string + */ + protected $webfinger; + + /** + * Restrict posting to mods + * + * @see https://join-lemmy.org/docs/contributors/05-federation.html + * + * @var boolean + */ + protected $posting_restricted_to_mods = null; } diff --git a/includes/class-migration.php b/includes/class-migration.php index faaa8e9d..594094d3 100644 --- a/includes/class-migration.php +++ b/includes/class-migration.php @@ -1,6 +1,7 @@ array( 'publish_posts' ), - ) - ); - - // add ActivityPub capability to all users that can publish posts - foreach ( $users as $user ) { - $user->add_cap( 'activitypub' ); - } - } - - public static function generate_blog_user() { - $user_pass = wp_generate_password( 15, true, true ); - - // check if domain host has a subdomain - $host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST ); - $host = \preg_replace( '/^www\./i', '', $host ); - - $user_id = wp_insert_user( - array( - 'user_login' => $host, - 'user_pass' => $user_pass, - 'description' => \get_bloginfo( 'description' ), - 'role' => '', - ) - ); + Setup::init(); } } diff --git a/includes/class-setup.php b/includes/class-setup.php new file mode 100644 index 00000000..ad2b971a --- /dev/null +++ b/includes/class-setup.php @@ -0,0 +1,133 @@ + array( 'publish_posts' ), + ) + ); + + // add ActivityPub capability to all users that can publish posts + foreach ( $users as $user ) { + $user->add_cap( 'activitypub' ); + } + } + + /** + * Generate the ActivityPub Blog User + * + * @return void + */ + public static function generate_blog_user() { + $user_pass = wp_generate_password( 15, true, true ); + + // check if domain host has a subdomain + $host = \wp_parse_url( \get_home_url(), \PHP_URL_HOST ); + $host = \preg_replace( '/^www\./i', '', $host ); + + wp_insert_user( + array( + 'user_login' => $host, + 'user_pass' => $user_pass, + 'display_name' => 'The ActivityPub Blog User', + 'description' => \get_bloginfo( 'description' ), + 'role' => 'activitypub_blog', + ) + ); + } + + /** + * Generate the ActivityPub Application User + * + * @return void + */ + public static function generate_aplication_user() { + $user_pass = wp_generate_password( 15, true, true ); + + wp_insert_user( + array( + 'user_login' => 'application', + 'display_name' => 'The ActivityPub Application User', + 'user_pass' => $user_pass, + 'description' => \get_bloginfo( 'description' ), + 'role' => 'activitypub_application', + ) + ); + } + + /** + * Add the ActivityPub roles to the site + * + * @return void + */ + public static function add_roles() { + $default_roles = array( + 'activitypub_application' => _x( 'ActivityPub Application', 'User role', 'activitypub' ), + 'activitypub_blog' => _x( 'ActivityPub Blog', 'User role', 'activitypub' ), + ); + + $roles = new WP_Roles(); + + foreach ( $default_roles as $type => $name ) { + $role = false; + foreach ( $roles->roles as $slug => $data ) { + if ( isset( $data['capabilities'][ $type ] ) ) { + $role = get_role( $slug ); + break; + } + } + if ( ! $role ) { + $role = add_role( $type, $name, self::get_role_capabilities( $type ) ); + continue; + } + + // This might update missing capabilities. + foreach ( array_keys( self::get_role_capabilities( $type ) ) as $cap ) { + $role->add_cap( $cap ); + } + } + } + + public static function get_role_capabilities( $role ) { + $capabilities = array(); + + $capabilities['activitypub_application'] = array( + 'activitypub' => true, + ); + + $capabilities['activitypub_blog'] = array( + 'activitypub' => true, + ); + + if ( ! isset( $capabilities[ $role ] ) ) { + return array(); + } + + return $capabilities[ $role ]; + } +} diff --git a/includes/collection/class-users.php b/includes/collection/class-users.php index a331c203..ab078860 100644 --- a/includes/collection/class-users.php +++ b/includes/collection/class-users.php @@ -3,9 +3,7 @@ use WP_Error; use WP_User_Query; -use Activitypub\Model\User; -use Activitypub\Model\Blog_User; -use Activitypub\Model\Application_User; +use Activitypub\Transformer\User; use function Activitypub\url_to_authorid; use function Activitypub\is_user_disabled; @@ -45,12 +43,32 @@ public static function get_by_id( $user_id ) { ); } + $user = null; + if ( self::BLOG_USER_ID === $user_id ) { - return Blog_User::from_wp_user( $user_id ); + $args = array( + 'role' => 'activitypub_blog', + 'orderby' => 'user_nicename', + 'order' => 'ASC', + ); + + $users = get_users( $args ); + $user = current( $users ); } elseif ( self::APPLICATION_USER_ID === $user_id ) { - return Application_User::from_wp_user( $user_id ); + $args = array( + 'role' => 'activitypub_application', + 'orderby' => 'user_nicename', + 'order' => 'ASC', + ); + + $users = get_users( $args ); + $user = current( $users ); } elseif ( $user_id > 0 ) { - return User::from_wp_user( $user_id ); + $user = get_user_by( 'id', $user_id ); + } + + if ( $user ) { + return User::transform( $user )->to_actor(); } return new WP_Error( @@ -69,10 +87,6 @@ public static function get_by_id( $user_id ) { */ public static function get_by_username( $username ) { // check for blog user. - if ( Blog_User::get_default_username() === $username ) { - return self::get_by_id( self::BLOG_USER_ID ); - } - if ( get_option( 'activitypub_blog_user_identifier' ) === $username ) { return self::get_by_id( self::BLOG_USER_ID ); } diff --git a/includes/rest/class-webfinger.php b/includes/rest/class-webfinger.php index a86fde06..aa01ecc0 100644 --- a/includes/rest/class-webfinger.php +++ b/includes/rest/class-webfinger.php @@ -93,20 +93,24 @@ public static function get_profile( $resource ) { } $aliases = array( + $user->get_webfinger(), + $user->get_id(), $user->get_url(), - $user->get_alternate_url(), ); $aliases = array_unique( $aliases ); $profile = array( 'subject' => sprintf( 'acct:%s', $user->get_webfinger() ), - 'aliases' => array_values( array_unique( $aliases ) ), + 'aliases' => array_values( $aliases ), 'links' => array( array( 'rel' => 'self', 'type' => 'application/activity+json', 'href' => $user->get_url(), + 'properties' => array( + 'https://www.w3.org/ns/activitystreams#type' => $user->get_type(), + ), ), array( 'rel' => 'http://webfinger.net/rel/profile-page', @@ -116,12 +120,6 @@ public static function get_profile( $resource ) { ), ); - if ( 'Person' !== $user->get_type() ) { - $profile['links'][0]['properties'] = array( - 'https://www.w3.org/ns/activitystreams#type' => $user->get_type(), - ); - } - return $profile; } } diff --git a/includes/transformer/class-base.php b/includes/transformer/class-base.php index b66703fa..a2c12e4a 100644 --- a/includes/transformer/class-base.php +++ b/includes/transformer/class-base.php @@ -4,6 +4,7 @@ use WP_Post; use WP_Comment; +use Activitypub\Activity\Actor; use Activitypub\Activity\Activity; use Activitypub\Activity\Base_Object; @@ -83,6 +84,18 @@ public function to_object() { return $activitypub_object; } + /** + * Transform the WordPress Object into an ActivityPub Actor. + * + * @return Activitypub\Activity\Actor + */ + public function to_actor() { + $activitypub_actor = new Actor(); + $activitypub_actor = $this->transform_object_properties( $activitypub_actor ); + + return $activitypub_actor; + } + /** * Transforms the ActivityPub Object to an Activity * diff --git a/includes/transformer/class-user.php b/includes/transformer/class-user.php new file mode 100644 index 00000000..b06140e9 --- /dev/null +++ b/includes/transformer/class-user.php @@ -0,0 +1,307 @@ +is_application() ) { + return 'Application'; + } elseif ( $this->is_blog() ) { + return 'Group'; + } else { + return 'Person'; + } + } + + /** + * Returns the ID of the WordPress Post. + * + * @return int The ID of the WordPress Post + */ + public function get_wp_user_id() { + return $this->wp_object->ID; + } + + /** + * Change the User-ID of the WordPress Post. + * + * @return int The User-ID of the WordPress Post + */ + public function change_wp_user_id( $user_id ) { + $this->wp_object->ID = $user_id; + + return $this; + } + + /** + * Get the User-ID. + * + * @return string The User-ID. + */ + public function get_id() { + return $this->get_url(); + } + + /** + * Get the User-Name. + * + * @return string The User-Name. + */ + public function get_name() { + return \esc_attr( \get_the_author_meta( 'display_name', $this->wp_object->ID ) ); + } + + /** + * Get the User-Description. + * + * @return string The User-Description. + */ + public function get_summary() { + $description = get_user_meta( $this->wp_object->ID, 'activitypub_user_description', true ); + if ( empty( $description ) ) { + $description = get_user_meta( $this->wp_object->ID, 'description', true ); + } + return \wpautop( \wp_kses( $description, 'default' ) ); + } + + /** + * Get the User-Url. + * + * @return string The User-Url. + */ + public function get_url() { + return \esc_url( \get_author_posts_url( $this->wp_object->ID ) ); + } + + /** + * Returns the User-URL with @-Prefix for the username. + * + * @return string The User-URL with @-Prefix for the username. + */ + public function get_alternate_url() { + return \esc_url( \trailingslashit( get_home_url() ) . '@' . $this->get_preferred_username() ); + } + + public function get_preferred_username() { + return \esc_attr( \get_the_author_meta( 'login', $this->wp_object->ID ) ); + } + + public function get_icon() { + $icon = \esc_url( + \get_avatar_url( + $this->wp_object, + array( 'size' => 120 ) + ) + ); + + return array( + 'type' => 'Image', + 'url' => $icon, + ); + } + + public function get_image() { + if ( \has_header_image() ) { + $image = \esc_url( \get_header_image() ); + return array( + 'type' => 'Image', + 'url' => $image, + ); + } + + return null; + } + + public function get_published() { + return \gmdate( 'Y-m-d\TH:i:s\Z', \strtotime( \get_the_author_meta( 'registered', $this->wp_object->ID ) ) ); + } + + public function get_public_key() { + return array( + 'id' => $this->get_id() . '#main-key', + 'owner' => $this->get_id(), + 'publicKeyPem' => Signature::get_public_key_for( $this->wp_object->ID ), + ); + } + + /** + * Returns the Inbox-API-Endpoint. + * + * @return string The Inbox-Endpoint. + */ + public function get_inbox() { + return get_rest_url_by_path( sprintf( 'users/%d/inbox', $this->wp_object->ID ) ); + } + + /** + * Returns the Outbox-API-Endpoint. + * + * @return string The Outbox-Endpoint. + */ + public function get_outbox() { + return get_rest_url_by_path( sprintf( 'users/%d/outbox', $this->wp_object->ID ) ); + } + + /** + * Returns the Followers-API-Endpoint. + * + * @return string The Followers-Endpoint. + */ + public function get_followers() { + return get_rest_url_by_path( sprintf( 'users/%d/followers', $this->wp_object->ID ) ); + } + + /** + * Returns the Following-API-Endpoint. + * + * @return string The Following-Endpoint. + */ + public function get_following() { + return get_rest_url_by_path( sprintf( 'users/%d/following', $this->wp_object->ID ) ); + } + + /** + * Returns the Featured-API-Endpoint. + * + * @return string The Featured-Endpoint. + */ + public function get_featured() { + return get_rest_url_by_path( sprintf( 'users/%d/collections/featured', $this->wp_object->ID ) ); + } + + public function get_endpoints() { + $endpoints = null; + + if ( ACTIVITYPUB_SHARED_INBOX_FEATURE ) { + $endpoints = array( + 'sharedInbox' => get_rest_url_by_path( 'inbox' ), + ); + } + + return $endpoints; + } + + /** + * Extend the User-Output with Attachments. + * + * @return array The extended User-Output. + */ + public function get_attachment() { + $array = array(); + + $array[] = array( + 'type' => 'PropertyValue', + 'name' => \__( 'Blog', 'activitypub' ), + 'value' => \html_entity_decode( + '' . \wp_parse_url( \home_url( '/' ), \PHP_URL_HOST ) . '', + \ENT_QUOTES, + 'UTF-8' + ), + ); + + $array[] = array( + 'type' => 'PropertyValue', + 'name' => \__( 'Profile', 'activitypub' ), + 'value' => \html_entity_decode( + '' . \wp_parse_url( \get_author_posts_url( $this->wp_object->ID ), \PHP_URL_HOST ) . '', + \ENT_QUOTES, + 'UTF-8' + ), + ); + + if ( \get_the_author_meta( 'user_url', $this->wp_object->ID ) ) { + $array[] = array( + 'type' => 'PropertyValue', + 'name' => \__( 'Website', 'activitypub' ), + 'value' => \html_entity_decode( + '' . \wp_parse_url( \get_the_author_meta( 'user_url', $this->wp_object->ID ), \PHP_URL_HOST ) . '', + \ENT_QUOTES, + 'UTF-8' + ), + ); + } + + return $array; + } + + /** + * Returns a user@domain type of identifier for the user. + * + * @return string The Webfinger-Identifier. + */ + public function get_webfinger() { + return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST ); + } + + public function get_resource() { + return $this->get_webfinger(); + } + + public function get_canonical_url() { + return $this->get_url(); + } + + public function get_streams() { + return null; + } + + public function get_tag() { + return array(); + } + + public function get_indexable() { + if ( $this->is_application() ) { + return false; + } elseif ( \get_option( 'blog_public', 1 ) ) { + return true; + } else { + return false; + } + } + + public function get_discoverable() { + if ( $this->is_application() ) { + return false; + } + + return true; + } + + public function get_manually_approves_followers() { + if ( $this->is_application() || $this->is_blog() ) { + return true; + } + + return false; + } + + private function is_application() { + $roles = $this->wp_object->roles; + + if ( \in_array( 'activitypub_application', $roles, true ) ) { + return true; + } + + return false; + } + + private function is_blog() { + $roles = $this->wp_object->roles; + + if ( \in_array( 'activitypub_blog', $roles, true ) ) { + return true; + } + + return false; + } +} diff --git a/integration/class-webfinger.php b/integration/class-webfinger.php index c9727861..5225b94b 100644 --- a/integration/class-webfinger.php +++ b/integration/class-webfinger.php @@ -36,12 +36,22 @@ public static function add_user_discovery( $array, $resource, $user ) { $array['subject'] = sprintf( 'acct:%s', $user->get_webfinger() ); + $array['aliases'][] = $user->get_id(); $array['aliases'][] = $user->get_url(); - $array['aliases'][] = $user->get_alternate_url(); + $array['aliases'] = array_unique( $array['aliases'] ); $array['links'][] = array( - 'rel' => 'self', - 'type' => 'application/activity+json', + 'rel' => 'self', + 'type' => 'application/activity+json', + 'href' => $user->get_url(), + 'properties' => array( + 'https://www.w3.org/ns/activitystreams#type' => $user->get_type(), + ), + ); + + $array['links'][] = array( + 'rel' => 'http://webfinger.net/rel/profile-page', + 'type' => 'text/html', 'href' => $user->get_url(), ); diff --git a/templates/author-json.php b/templates/author-json.php index 63f6d12f..e64c37d0 100644 --- a/templates/author-json.php +++ b/templates/author-json.php @@ -1,15 +1,16 @@ to_actor(); /* * Action triggerd prior to the ActivityPub profile being created and sent to the client */ -\do_action( 'activitypub_json_author_pre', $user->get__id() ); +\do_action( 'activitypub_json_author_pre', $user->ID ); \header( 'Content-Type: application/activity+json' ); -echo $user->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +echo $user_actor->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped /* * Action triggerd after the ActivityPub profile has been created and sent to the client */ -\do_action( 'activitypub_json_author_post', $user->get__id() ); +\do_action( 'activitypub_json_author_post', $user->ID ); diff --git a/templates/blog-json.php b/templates/blog-json.php deleted file mode 100644 index 8090b135..00000000 --- a/templates/blog-json.php +++ /dev/null @@ -1,15 +0,0 @@ -get__id() ); - -\header( 'Content-Type: application/activity+json' ); -echo $user->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - -/* - * Action triggerd after the ActivityPub profile has been created and sent to the client - */ -\do_action( 'activitypub_json_author_post', $user->get__id() ); From 4f877ef985ec7ae1b1f98f0932724207da1b50d1 Mon Sep 17 00:00:00 2001 From: Matthias Pfefferle Date: Tue, 12 Mar 2024 19:55:52 +0100 Subject: [PATCH 4/4] some fixes --- includes/class-migration.php | 2 +- includes/class-setup.php | 8 +-- includes/class-signature.php | 2 +- includes/collection/class-users.php | 52 +++++++++++++------ includes/rest/class-server.php | 2 +- includes/transformer/class-comment.php | 10 ++-- includes/transformer/class-post.php | 15 ++---- includes/transformer/class-user.php | 4 ++ templates/settings.php | 2 +- templates/welcome.php | 2 +- tests/bootstrap.php | 2 +- ...-class-activitypub-activity-dispatcher.php | 4 +- ...est-class-activitypub-users-collection.php | 32 ++++++------ 13 files changed, 78 insertions(+), 59 deletions(-) diff --git a/includes/class-migration.php b/includes/class-migration.php index 594094d3..f52ead52 100644 --- a/includes/class-migration.php +++ b/includes/class-migration.php @@ -3,7 +3,7 @@ use Activitypub\Setup; use Activitypub\Activitypub; -use Activitypub\Model\Blog_User; +use Activitypub\Activity\Actor; use Activitypub\Collection\Followers; /** diff --git a/includes/class-setup.php b/includes/class-setup.php index ad2b971a..7e4a01a5 100644 --- a/includes/class-setup.php +++ b/includes/class-setup.php @@ -52,11 +52,11 @@ public static function generate_blog_user() { wp_insert_user( array( - 'user_login' => $host, - 'user_pass' => $user_pass, + 'user_login' => $host, + 'user_pass' => $user_pass, 'display_name' => 'The ActivityPub Blog User', - 'description' => \get_bloginfo( 'description' ), - 'role' => 'activitypub_blog', + 'description' => \get_bloginfo( 'description' ), + 'role' => 'activitypub_blog', ) ); } diff --git a/includes/class-signature.php b/includes/class-signature.php index e59a1f97..23afac6e 100644 --- a/includes/class-signature.php +++ b/includes/class-signature.php @@ -186,7 +186,7 @@ protected static function check_legacy_key_pair_for( $user_id ) { */ public static function generate_signature( $user_id, $http_method, $url, $date, $digest = null ) { $user = Users::get_by_id( $user_id ); - $key = self::get_private_key_for( $user->get__id() ); + $key = self::get_private_key_for( $user_id ); $url_parts = \wp_parse_url( $url ); diff --git a/includes/collection/class-users.php b/includes/collection/class-users.php index ab078860..d369a990 100644 --- a/includes/collection/class-users.php +++ b/includes/collection/class-users.php @@ -46,23 +46,9 @@ public static function get_by_id( $user_id ) { $user = null; if ( self::BLOG_USER_ID === $user_id ) { - $args = array( - 'role' => 'activitypub_blog', - 'orderby' => 'user_nicename', - 'order' => 'ASC', - ); - - $users = get_users( $args ); - $user = current( $users ); + $user = self::get_blog(); } elseif ( self::APPLICATION_USER_ID === $user_id ) { - $args = array( - 'role' => 'activitypub_application', - 'orderby' => 'user_nicename', - 'order' => 'ASC', - ); - - $users = get_users( $args ); - $user = current( $users ); + $user = self::get_application(); } elseif ( $user_id > 0 ) { $user = get_user_by( 'id', $user_id ); } @@ -289,9 +275,41 @@ public static function get_collection() { $return = array(); foreach ( $users as $user ) { - $return[] = User::from_wp_user( $user->ID ); + $return[] = User::transform( $user )->to_actor(); } return $return; } + + public static function get_blog() { + $users = get_users( + array( + 'role' => 'activitypub_blog', + 'orderby' => 'user_nicename', + 'order' => 'ASC', + ) + ); + + if ( ! empty( $users ) ) { + return current( $users ); + } + + return null; + } + + public static function get_application() { + $users = get_users( + array( + 'role' => 'activitypub_application', + 'orderby' => 'user_nicename', + 'order' => 'ASC', + ) + ); + + if ( ! empty( $users ) ) { + return current( $users ); + } + + return null; + } } diff --git a/includes/rest/class-server.php b/includes/rest/class-server.php index 13e70736..da5ea82f 100644 --- a/includes/rest/class-server.php +++ b/includes/rest/class-server.php @@ -5,7 +5,7 @@ use WP_Error; use WP_REST_Response; use Activitypub\Signature; -use Activitypub\Model\Application_User; +use Activitypub\Activity\Actor; /** * ActivityPub Server REST-Class diff --git a/includes/transformer/class-comment.php b/includes/transformer/class-comment.php index 209a7ab3..33bb077b 100644 --- a/includes/transformer/class-comment.php +++ b/includes/transformer/class-comment.php @@ -6,7 +6,7 @@ use Activitypub\Webfinger; use Activitypub\Comment as Comment_Utils; -use Activitypub\Model\Blog_User; +use Activitypub\Activity\Actor; use Activitypub\Collection\Users; use Activitypub\Transformer\Base; @@ -89,12 +89,14 @@ public function to_object() { * @return string The User-URL. */ protected function get_attributed_to() { + $user_id = $this->wp_object->user_id; + if ( is_single_user() ) { - $user = new Blog_User(); - return $user->get_url(); + $user_id = Users::BLOG_USER_ID; } - return Users::get_by_id( $this->wp_object->user_id )->get_url(); + $user = Users::get_by_id( $user_id ); + return $user->get_url(); } /** diff --git a/includes/transformer/class-post.php b/includes/transformer/class-post.php index d21099ee..cbf9e95a 100644 --- a/includes/transformer/class-post.php +++ b/includes/transformer/class-post.php @@ -3,7 +3,7 @@ use WP_Post; use Activitypub\Shortcodes; -use Activitypub\Model\Blog_User; +use Activitypub\Activity\Actor; use Activitypub\Transformer\Base; use Activitypub\Collection\Users; use Activitypub\Activity\Base_Object; @@ -116,19 +116,14 @@ public function get_url() { * @return string The User-URL. */ protected function get_attributed_to() { - $blog_user = new Blog_User(); + $user_id = $this->wp_object->post_author; if ( is_single_user() ) { - return $blog_user->get_url(); + $user_id = Users::BLOG_USER_ID; } - $user = Users::get_by_id( $this->wp_object->post_author ); - - if ( $user && ! is_wp_error( $user ) ) { - return $user->get_url(); - } - - return $blog_user->get_url(); + $user = Users::get_by_id( $user_id ); + return $user->get_url(); } /** diff --git a/includes/transformer/class-user.php b/includes/transformer/class-user.php index b06140e9..5403a503 100644 --- a/includes/transformer/class-user.php +++ b/includes/transformer/class-user.php @@ -286,6 +286,8 @@ public function get_manually_approves_followers() { } private function is_application() { + return false; + $roles = $this->wp_object->roles; if ( \in_array( 'activitypub_application', $roles, true ) ) { @@ -296,6 +298,8 @@ private function is_application() { } private function is_blog() { + return false; + $roles = $this->wp_object->roles; if ( \in_array( 'activitypub_blog', $roles, true ) ) { diff --git a/templates/settings.php b/templates/settings.php index 2da88a7e..dcdd6875 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -49,7 +49,7 @@

diff --git a/templates/welcome.php b/templates/welcome.php index a2663286..3832c419 100644 --- a/templates/welcome.php +++ b/templates/welcome.php @@ -19,7 +19,7 @@

diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f4468fbc..d9d30a78 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -30,4 +30,4 @@ function _manually_load_plugin() { require $_tests_dir . '/includes/bootstrap.php'; require __DIR__ . '/class-activitypub-testcase-cache-http.php'; -\Activitypub\Migration::add_default_settings(); +\Activitypub\Setup::init(); diff --git a/tests/test-class-activitypub-activity-dispatcher.php b/tests/test-class-activitypub-activity-dispatcher.php index c42d3912..e3f3ef42 100644 --- a/tests/test-class-activitypub-activity-dispatcher.php +++ b/tests/test-class-activitypub-activity-dispatcher.php @@ -120,7 +120,7 @@ public function test_dispatch_announce() { $this->assertSame( 1, $pre_http_request->get_call_count() ); - $user = new \Activitypub\Model\Blog_User(); + $user = new \Activitypub\Activity\Actor(); $json = json_decode( $first_call_args[1]['body'] ); $this->assertEquals( 'Announce', $json->type ); @@ -168,7 +168,7 @@ function ( $value, $type ) { $this->assertSame( 1, $pre_http_request->get_call_count() ); - $user = new \Activitypub\Model\Blog_User(); + $user = new \Activitypub\Activity\Actor(); $json = json_decode( $first_call_args[1]['body'] ); $this->assertEquals( 'Create', $json->type ); diff --git a/tests/test-class-activitypub-users-collection.php b/tests/test-class-activitypub-users-collection.php index a5fd60c8..899819ff 100644 --- a/tests/test-class-activitypub-users-collection.php +++ b/tests/test-class-activitypub-users-collection.php @@ -18,24 +18,24 @@ public function test_get_by_various( $resource, $expected ) { public function the_resource_provider() { return array( - array( 'http://example.org/?author=1', 'Activitypub\Model\User' ), - array( 'https://example.org/?author=1', 'Activitypub\Model\User' ), + array( 'http://example.org/?author=1', 'Activitypub\Activity\Actor' ), + array( 'https://example.org/?author=1', 'Activitypub\Activity\Actor' ), array( 'http://example.org/?author=7', 'WP_Error' ), - array( 'acct:admin@example.org', 'Activitypub\Model\User' ), - array( 'acct:blog@example.org', 'Activitypub\Model\Blog_User' ), - array( 'acct:*@example.org', 'Activitypub\Model\Blog_User' ), - array( 'acct:_@example.org', 'Activitypub\Model\Blog_User' ), + array( 'acct:admin@example.org', 'Activitypub\Activity\Actor' ), + array( 'acct:blog@example.org', 'Activitypub\Activity\Actor' ), + array( 'acct:*@example.org', 'Activitypub\Activity\Actor' ), + array( 'acct:_@example.org', 'Activitypub\Activity\Actor' ), array( 'acct:aksd@example.org', 'WP_Error' ), - array( 'admin@example.org', 'Activitypub\Model\User' ), - array( 'acct:application@example.org', 'Activitypub\Model\Application_User' ), - array( 'http://example.org/@admin', 'Activitypub\Model\User' ), - array( 'http://example.org/@blog', 'Activitypub\Model\Blog_User' ), - array( 'https://example.org/@blog', 'Activitypub\Model\Blog_User' ), - array( 'http://example.org/@blog/', 'Activitypub\Model\Blog_User' ), - array( 'http://example.org/', 'Activitypub\Model\Blog_User' ), - array( 'http://example.org', 'Activitypub\Model\Blog_User' ), - array( 'https://example.org/', 'Activitypub\Model\Blog_User' ), - array( 'https://example.org', 'Activitypub\Model\Blog_User' ), + array( 'admin@example.org', 'Activitypub\Activity\Actor' ), + array( 'acct:application@example.org', 'Activitypub\Activity\Actor' ), + array( 'http://example.org/@admin', 'Activitypub\Activity\Actor' ), + array( 'http://example.org/@blog', 'Activitypub\Activity\Actor' ), + array( 'https://example.org/@blog', 'Activitypub\Activity\Actor' ), + array( 'http://example.org/@blog/', 'Activitypub\Activity\Actor' ), + array( 'http://example.org/', 'Activitypub\Activity\Actor' ), + array( 'http://example.org', 'Activitypub\Activity\Actor' ), + array( 'https://example.org/', 'Activitypub\Activity\Actor' ), + array( 'https://example.org', 'Activitypub\Activity\Actor' ), array( 'http://example.org/@blog/s', 'WP_Error' ), array( 'http://example.org/@blogs/', 'WP_Error' ), );