Skip to content
11 changes: 11 additions & 0 deletions includes/class-post-types.php
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,17 @@ public static function register_post_post_type() {
'sanitize_callback' => 'absint',
)
);

\register_post_meta(
Posts::POST_TYPE,
'_activitypub_user_id',
array(
'type' => 'integer',
'single' => true,
'description' => 'The ID of the local user that received the activity.',
'sanitize_callback' => 'absint',
)
);
}

/**
Expand Down
12 changes: 10 additions & 2 deletions includes/collection/class-posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ class Posts {
* Add an object to the collection.
*
* @param array $activity The activity object data.
* @param int $user_id The local user ID.
*
* @return \WP_Post|\WP_Error The object post or WP_Error on failure.
*/
public static function add( $activity ) {
public static function add( $activity, $user_id ) {
$activity_object = $activity['object'];
$actor = Remote_Actors::fetch_by_uri( object_to_uri( $activity_object['attributedTo'] ) );

Expand All @@ -47,6 +48,7 @@ public static function add( $activity ) {
}

\add_post_meta( $post_id, '_activitypub_remote_actor_id', $actor->ID );
\add_post_meta( $post_id, '_activitypub_user_id', $user_id );

self::add_taxonomies( $post_id, $activity_object );

Expand Down Expand Up @@ -97,10 +99,11 @@ public static function get_by_guid( $guid ) {
* Update an object in the collection.
*
* @param array $activity The activity object data.
* @param int $user_id The local user ID.
*
* @return \WP_Post|\WP_Error The updated object post or WP_Error on failure.
*/
public static function update( $activity ) {
public static function update( $activity, $user_id ) {
$post = self::get_by_guid( $activity['object']['id'] );
if ( \is_wp_error( $post ) ) {
return $post;
Expand All @@ -114,6 +117,11 @@ public static function update( $activity ) {
return $post_id;
}

$post_meta = \get_post_meta( $post_id, '_activitypub_user_id', false );
if ( \is_array( $post_meta ) && ! \in_array( (string) $user_id, $post_meta, true ) ) {
\add_post_meta( $post_id, '_activitypub_user_id', $user_id );
}

self::add_taxonomies( $post_id, $activity['object'] );

return \get_post( $post_id );
Expand Down
6 changes: 4 additions & 2 deletions includes/handler/class-create.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ public static function handle_create( $activity, $user_id, $activity_object = nu
$result = false;
} elseif ( is_activity_reply( $activity ) ) { // Check for replies.
$result = self::create_interaction( $activity, $user_id, $activity_object );
} else { // Handle non-interaction objects.
} elseif ( \get_option( 'activitypub_create_posts', false ) ) { // Handle non-interaction objects.
$result = self::create_post( $activity, $user_id, $activity_object );
} else {
$result = false;
}

if ( false === $result ) {
Expand Down Expand Up @@ -124,7 +126,7 @@ public static function create_post( $activity, $user_id, $activity_object = null
return false;
}

return Posts::add( $activity );
return Posts::add( $activity, $user_id );
}

/**
Expand Down
4 changes: 2 additions & 2 deletions includes/handler/class-update.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ public static function update_object( $activity, $user_id, $activity_object ) {
} elseif ( ! empty( $comment_data['comment_ID'] ) ) {
$result = \get_comment( $comment_data['comment_ID'] );
}
} else {
$result = Posts::update( $activity );
} elseif ( \get_option( 'activitypub_create_posts', false ) ) {
$result = Posts::update( $activity, $user_id );

if ( \is_wp_error( $result ) && 'activitypub_post_not_found' === $result->get_error_code() ) {
$updated = false;
Expand Down
10 changes: 10 additions & 0 deletions includes/wp-admin/class-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,16 @@ public static function register_settings() {
)
);

\register_setting(
'activitypub_advanced',
'activitypub_create_posts',
array(
'type' => 'boolean',
'description' => 'Allow creating posts via ActivityPub.',
'default' => false,
)
);

\register_setting(
'activitypub_advanced',
'activitypub_shared_inbox',
Expand Down
10 changes: 5 additions & 5 deletions tests/phpunit/tests/includes/collection/class-test-posts.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function test_add() {
),
);

$result = Posts::add( $activity );
$result = Posts::add( $activity, 1 );

$this->assertInstanceOf( '\WP_Post', $result );
$this->assertEquals( 'Test Object', $result->post_title );
Expand All @@ -118,7 +118,7 @@ public function test_update() {
),
);

$original_post = Posts::add( $activity );
$original_post = Posts::add( $activity, 1 );
$this->assertInstanceOf( '\WP_Post', $original_post );

// Now update it.
Expand All @@ -131,7 +131,7 @@ public function test_update() {
),
);

$updated_post = Posts::update( $update_activity );
$updated_post = Posts::update( $update_activity, 1 );

$this->assertInstanceOf( '\WP_Post', $updated_post );
$this->assertEquals( 'Updated Title', $updated_post->post_title );
Expand All @@ -154,7 +154,7 @@ public function test_update_nonexistent() {
),
);

$result = Posts::update( $activity );
$result = Posts::update( $activity, 1 );

$this->assertInstanceOf( '\WP_Error', $result );
}
Expand All @@ -176,7 +176,7 @@ public function test_get_by_guid() {
),
);

$post = Posts::add( $activity );
$post = Posts::add( $activity, 1 );
$this->assertInstanceOf( '\WP_Post', $post );

// Test retrieval.
Expand Down
5 changes: 4 additions & 1 deletion tests/phpunit/tests/includes/handler/class-test-create.php
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ function ( $response, $parsed_args, $url ) {
),
);

\update_option( 'activitypub_create_posts', true );

Create::handle_create( $activity, $this->user_id );

// Verify the object was created with sanitized content.
Expand All @@ -356,7 +358,8 @@ function ( $response, $parsed_args, $url ) {
$this->assertStringContainsString( 'Safe content', $created_object->post_content );

// Clean up filter.
remove_all_filters( 'pre_http_request' );
\remove_all_filters( 'pre_http_request' );
\delete_option( 'activitypub_create_posts' );
}

/**
Expand Down
3 changes: 3 additions & 0 deletions tests/phpunit/tests/includes/handler/class-test-update.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class Test_Update extends \WP_UnitTestCase {
* Test that the activitypub_inbox_create fallback is triggered.
*/
public function test_activitypub_inbox_create_fallback() {
\update_option( 'activitypub_create_posts', true );

$called = false;
$test_actor = 'https://example.com/users/fallback';
$activity = array(
Expand Down Expand Up @@ -55,6 +57,7 @@ function ( $activity_data ) use ( &$called, $test_actor ) {

// Clean up by removing the action.
\remove_all_actions( 'activitypub_inbox_create' );
\delete_option( 'activitypub_create_posts' );
}

/**
Expand Down