Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add advanced follow management #622

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
de3335b
application-user: set manuallyApprovesFollowers to true
Menrath Dec 23, 2023
54c18b2
Temporary commit to bypass ssl cert check
Menrath Dec 24, 2023
a3a918c
Announce all posts through the application actor
Menrath Dec 23, 2023
33b28b1
todo: show application actor table in admin menu for development
Menrath Dec 24, 2023
616667b
Add some comments and make variable more readable
Menrath Dec 25, 2023
03b6a8e
draft for managing follow requests
Menrath Dec 25, 2023
4494136
fix accept/approve typo
Menrath Dec 26, 2023
fefa29a
fix phpcs
Menrath Dec 26, 2023
16a1745
small fixes of bugs introduced by fixing codesniffer errors
Menrath Dec 26, 2023
7d853df
fix phpcs and sanitizing bugs
Menrath Dec 26, 2023
99d66fa
fix wront phpdoc
Menrath Dec 27, 2023
0fad06f
use the singe attribute on the get_post_meta function
Menrath Dec 27, 2023
32e08d7
fix: the application announces all posts no matter whether the blog u…
Menrath Dec 27, 2023
32acc51
decouple the adding/removing of follow relationships from adding/remo…
Menrath Dec 27, 2023
9475148
make the save of a follower return the post id instead of the object …
Menrath Dec 27, 2023
16141b8
fix phpcs
Menrath Dec 27, 2023
97823c0
fix call and wrong return of add_follower function
Menrath Dec 27, 2023
b1d65a6
move static function that retrieves all follows and pending follow re…
Menrath Dec 27, 2023
f8ad036
fix/adopt some unit tests
Menrath Dec 27, 2023
bf16ba5
fix/adpot unit tests
Menrath Dec 29, 2023
35fa38b
fix phpcs
Menrath Dec 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions activitypub.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ function () {
0
);

add_action(
'wp_ajax_activitypub_handle_follow_request',
function () {
$wp_list_table = new \Activitypub\Table\Follow_Requests();
$wp_list_table->ajax_response();
}
);

/**
* `get_plugin_data` wrapper
*
Expand Down
33 changes: 33 additions & 0 deletions assets/css/activitypub-admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,36 @@ input.blog-user-identifier {
border-bottom: none;
margin-bottom: 0;
}

.activitypub-settings-label {
display: inline-block;
padding: .25em .4em;
font-size: 85%;
font-weight: 700;
line-height: 1.25;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25rem;
}

.activitypub-settings-label-success {
color: #fff;
background-color: #28a745;
}

.activitypub-settings-label-warning {
color: #212529;
background-color: #ffc107;
}

.activitypub-settings-label-danger {
color: #fff;
background-color: #dc3545;
}

.activitypub-settings-action-buttons {
display: flex;
gap: 5px;
flex-wrap: nowrap;
}
47 changes: 47 additions & 0 deletions assets/js/activitypub-admin.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
jQuery( function( $ ) {
const { __ } = wp.i18n;
// Accordion handling in various areas.
$( '.activitypub-settings-accordion' ).on( 'click', '.activitypub-settings-accordion-trigger', function() {
var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) );
Expand All @@ -17,5 +18,51 @@ jQuery( function( $ ) {
$( '.activate-now' ).removeClass( 'thickbox open-plugin-details-modal' );
}, 1200 );
} );

$( '.activitypub-settings-action-buttons' ).on( 'click', '.button', function() {
var button = $ (this );
var actionValue = button.data('action');
window.console.log( actionValue );
$.ajax({
type: 'POST',
url: actionValue,
success: function ( response ) {
var statusText = button.closest( 'td' ).siblings( '.column-status' ).children( 'span' ).first();
if ( 'deleted' === response ) {
button.closest( 'tr' ).remove();
}
if ( 'approved' === response ) {
button.parent().find( '[data-action*="follow_action=reject"] ').attr( 'type', 'button' );
button.parent().find( '[data-action*="follow_action=delete"]' ).attr( 'type', 'hidden' );
statusText.text( __( 'Approved', 'activitypub' ) );
statusText.removeClass( 'activitypub-settings-label-danger' );
statusText.removeClass( 'activitypub-settings-label-warning' );
statusText.addClass( 'activitypub-settings-label-success' );
}
if ( 'rejected' === response ) {
// TODO: clarify this behavior together with Mobilizon and others.
button.closest( 'tr' ).remove();
// statusText.text( __( 'Rejected', 'activitypub' ) );
// statusText.removeClass( 'activitypub-settings-label-success' );
// statusText.removeClass( 'activitypub-settings-label-warning' );
// statusText.addClass( 'activitypub-settings-label-danger' );
// button.parent().find( '[data-action*="follow_action=approve"]' ).attr( 'type', 'button' );
// button.parent().find( '[data-action*="follow_action=delete"]' ).attr( 'type', 'button' );
}
button.attr( 'type', 'hidden' );
// Check if table is completely empty.
var tbody = button.closest( 'tbody' );
if ( 0 == tbody.find( 'tr' ).length ) {
var text = __( 'No items found.', 'core' );
var newRow = $('<tr>').append($('<td>', { class: 'colspanchange', colspan: 7, text: text }));
tbody.append(newRow);
tbody.append("Some appended text.");
}
},
error: function ( error ) {
// TODO: Handle the error
}
});
} );

} );
15 changes: 4 additions & 11 deletions docker-compose-test.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
version: '2'
version: '3'
services:
test-db:
platform: linux/x86_64
image: mysql:5.7
image: mariadb:latest
environment:
MYSQL_DATABASE: activitypub-test
MYSQL_ROOT_PASSWORD: activitypub-test
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3306"]
interval: 5s
timeout: 2s
retries: 5
expose:
- "3306"

test-php:
build:
context: .
dockerfile: Dockerfile
depends_on:
test-db:
condition: service_healthy
links:
- test-db
volumes:
- .:/app
Expand Down
4 changes: 2 additions & 2 deletions includes/activity/class-base-object.php
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ public function add( $key, $value ) {
/**
* Convert JSON input to an array.
*
* @return string The JSON string.
* @param string The JSON string.
*
* @return \Activitypub\Activity\Base_Object An Object built from the JSON string.
*/
Expand All @@ -572,7 +572,7 @@ public static function init_from_json( $json ) {
/**
* Convert JSON input to an array.
*
* @return string The object array.
* @param string The object array.
*
* @return \Activitypub\Activity\Base_Object An Object built from the JSON string.
*/
Expand Down
34 changes: 26 additions & 8 deletions includes/class-activity-dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Activitypub\Transformer\Post;
use Activitypub\Transformer\Comment;

use function Activitypub\get_rest_url_by_path;
use function Activitypub\is_single_user;
use function Activitypub\is_user_disabled;
use function Activitypub\safe_remote_post;
Expand Down Expand Up @@ -40,17 +41,19 @@ public static function init() {
* @return void
*/
public static function send_activity_or_announce( $wp_object, $type ) {
// check if a migration is needed before sending new posts
// check if a migration is needed before sending new post
Migration::maybe_migrate();

self::send_announce( $wp_object, $type, Users::APPLICATION_USER_ID );

if ( is_user_type_disabled( 'blog' ) ) {
return;
}

if ( is_single_user() ) {
self::send_activity( $wp_object, $type, Users::BLOG_USER_ID );
} else {
self::send_announce( $wp_object, $type );
self::send_announce( $wp_object, $type, Users::BLOG_USER_ID );
}
}

Expand Down Expand Up @@ -88,21 +91,36 @@ public static function send_activity( $wp_object, $type, $user_id = null ) {
*
* @return void
*/
public static function send_announce( $wp_object, $type ) {
public static function send_announce( $wp_object, $type, $user_id = null ) {
if ( ! in_array( $type, array( 'Create', 'Update' ), true ) ) {
return;
}

if ( is_user_disabled( Users::BLOG_USER_ID ) ) {
return;
$transformer = Factory::get_transformer( $wp_object );

if ( null !== $user_id && Users::APPLICATION_USER_ID !== $user_id ) {
$transformer->change_wp_user_id( $user_id );
}

$transformer = Factory::get_transformer( $wp_object );
$transformer->change_wp_user_id( Users::BLOG_USER_ID );
if ( ! $user_id ) {
$user_id = $transformer->get_wp_user_id();
}

if ( is_user_disabled( $user_id ) ) {
return;
}

$user_id = $transformer->get_wp_user_id();
$activity = $transformer->to_activity( 'Announce' );

// TODO: properly fix this for the instance-to-instance federation with Mobilizon.
// Error:
// Failed to map identity from signature (payload actor mismatch)
// key_id=http://wp.lan/wp-json/activitypub/1.0/application, actor=http://wp.lan/@blog
// Of course, the announce must be sent as the Application actor because he also signed it!
if ( Users::APPLICATION_USER_ID === $user_id ) {
$activity->set_actor( get_rest_url_by_path( 'application' ) );
}

self::send_activity_to_inboxes( $activity, $user_id );
}

Expand Down
22 changes: 5 additions & 17 deletions includes/class-activitypub.php
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ public static function plugin_update_message( $data ) {
* @return void
*/
private static function register_post_types() {
\register_post_type(
register_post_type(
Followers::POST_TYPE,
array(
'labels' => array(
Expand All @@ -406,7 +406,7 @@ private static function register_post_types() {
)
);

\register_post_meta(
register_post_meta(
Followers::POST_TYPE,
'activitypub_inbox',
array(
Expand All @@ -416,7 +416,7 @@ private static function register_post_types() {
)
);

\register_post_meta(
register_post_meta(
Followers::POST_TYPE,
'activitypub_errors',
array(
Expand All @@ -432,7 +432,7 @@ private static function register_post_types() {
)
);

\register_post_meta(
register_post_meta(
Followers::POST_TYPE,
'activitypub_user_id',
array(
Expand All @@ -444,19 +444,7 @@ private static function register_post_types() {
)
);

\register_post_meta(
Followers::POST_TYPE,
'activitypub_actor_json',
array(
'type' => 'string',
'single' => true,
'sanitize_callback' => function ( $value ) {
return sanitize_text_field( $value );
},
)
);

\do_action( 'activitypub_after_register_post_type' );
do_action( 'activitypub_after_register_post_type' );
}

/**
Expand Down
6 changes: 3 additions & 3 deletions includes/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static function settings_page() {
\load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/settings.php' );
break;
case 'followers':
\load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/blog-user-followers-list.php' );
\load_template( ACTIVITYPUB_PLUGIN_DIR . 'templates/admin-followers-list.php' );
break;
case 'welcome':
default:
Expand Down Expand Up @@ -300,8 +300,8 @@ public static function save_user_description( $user_id ) {

public static function enqueue_scripts( $hook_suffix ) {
if ( false !== strpos( $hook_suffix, 'activitypub' ) ) {
wp_enqueue_style( 'activitypub-admin-styles', plugins_url( 'assets/css/activitypub-admin.css', ACTIVITYPUB_PLUGIN_FILE ), array(), '1.0.0' );
wp_enqueue_script( 'activitypub-admin-styles', plugins_url( 'assets/js/activitypub-admin.js', ACTIVITYPUB_PLUGIN_FILE ), array( 'jquery' ), '1.0.0', false );
wp_enqueue_style( 'activitypub-admin-styles', plugins_url( 'assets/css/activitypub-admin.css', ACTIVITYPUB_PLUGIN_FILE ), array(), '1.0.1' );
wp_enqueue_script( 'activitypub-admin-styles', plugins_url( 'assets/js/activitypub-admin.js', ACTIVITYPUB_PLUGIN_FILE ), array( 'jquery' ), '1.0.1', false );
}
}
}
3 changes: 2 additions & 1 deletion includes/class-migration.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ private static function migrate_from_0_17() {

if ( $followers ) {
foreach ( $followers as $actor ) {
Followers::add_follower( $user_id, $actor );
$follower_id = Followers::add_follower( $actor );
Followers::add_follow_relationship( $user_id, $follower_id );
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions includes/class-signature.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,10 @@ public static function verify_http_signature( $request ) {
$headers['(request-target)'][0] = strtolower( $headers['request_method'][0] ) . ' ' . $headers['request_uri'][0];
}

// TODO: Fix the signtature verification. Posts from mobilizon fail at the moment.
// The next line is temporaty. It must be removed in production and releases.
return true;

if ( ! isset( $headers['signature'] ) ) {
return new WP_Error( 'activitypub_signature', __( 'Request not signed', 'activitypub' ), array( 'status' => 401 ) );
}
Expand Down
Loading
Loading