Sign outbound activities
This commit is contained in:
parent
76abc08dd4
commit
9c371b4720
@ -19,10 +19,31 @@ function persist_key( $actor_id, $public_key, $private_key ) {
|
||||
);
|
||||
}
|
||||
|
||||
function sign_data( $data, $actor_id ) {
|
||||
xdebug_break();
|
||||
$secret_key = get_private_key( $actor_id );
|
||||
$sig = null;
|
||||
openssl_sign( $data, $sig, $secret_key );
|
||||
if ( ! $sig ) {
|
||||
return new \WP_Error(
|
||||
'pgp_error',
|
||||
__( 'Unable to sign data', 'pterotype' )
|
||||
);
|
||||
}
|
||||
return $sig;
|
||||
}
|
||||
|
||||
function get_public_key( $actor_id ) {
|
||||
global $wpdb;
|
||||
return $wpdb->get_var( $wpdb->prepare(
|
||||
'SELECT public_key FROM pterotype_keys WHERE actor_id = %d', $actor_id
|
||||
) );
|
||||
}
|
||||
|
||||
function get_private_key( $actor_id ) {
|
||||
global $wpdb;
|
||||
return $wpdb->get_var( $wpdb->prepare(
|
||||
'SELECT private_key FROM pterotype_keys WHERE actor_id = %d', $actor_id
|
||||
) );
|
||||
}
|
||||
?>
|
||||
|
@ -2,13 +2,16 @@
|
||||
namespace deliver;
|
||||
|
||||
require_once plugin_dir_path( __FILE__ ) . 'activities.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . 'actors.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . '../pgp.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . '../util.php';
|
||||
|
||||
// TODO look at inReplyTo, object, target, and tag objects
|
||||
// and deliver to their audience as well. Recurse through these
|
||||
// objects up to some limit
|
||||
|
||||
function deliver_activity( $activity ) {
|
||||
function deliver_activity( $actor_slug, $activity ) {
|
||||
$actor_id = \actors\get_actor_id( $actor_slug );
|
||||
$activity = \util\dereference_object( $activity );
|
||||
$recipients = array();
|
||||
foreach ( array( 'to', 'bto', 'cc', 'bcc', 'audience' ) as $field ) {
|
||||
@ -22,7 +25,7 @@ function deliver_activity( $activity ) {
|
||||
$recipients = remove_actor_inbox_from_recipients( $actor, $recipients );
|
||||
}
|
||||
$activity = \activities\strip_private_fields( $activity );
|
||||
post_activity_to_inboxes( $activity, $recipients );
|
||||
post_activity_to_inboxes( $actor_id, $activity, $recipients );
|
||||
}
|
||||
|
||||
function remove_actor_inbox_from_recipients( $actor, $recipients ) {
|
||||
@ -52,11 +55,11 @@ function get_recipient_urls( $object, $depth, $acc ) {
|
||||
if ( $depth === 30 ) {
|
||||
return $acc;
|
||||
}
|
||||
if ( array_key_exists( 'type', $object ) ) {
|
||||
if ( is_array( $object ) && array_key_exists( 'type', $object ) ) {
|
||||
// It's an Actor, Link, or Collection
|
||||
switch ( $object['type'] ) {
|
||||
case Collection:
|
||||
case OrderedCollection:
|
||||
case 'Collection':
|
||||
case 'OrderedCollection':
|
||||
$items = array();
|
||||
if ( array_key_exists( 'items', $object ) ) {
|
||||
$items = $object['items'];
|
||||
@ -71,13 +74,13 @@ function get_recipient_urls( $object, $depth, $acc ) {
|
||||
);
|
||||
}
|
||||
return $recipients;
|
||||
case Link:
|
||||
case 'Link':
|
||||
if ( array_key_exists( 'href', $object ) ) {
|
||||
$response = \util\get_object_from_url( $object['href'] );
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return array();
|
||||
}
|
||||
return get_recipient_urls( $link_target, $depth + 1, $acc );
|
||||
return get_recipient_urls( $response, $depth + 1, $acc );
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@ -106,7 +109,7 @@ function get_recipient_urls( $object, $depth, $acc ) {
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return array();
|
||||
}
|
||||
return get_recipient_urls( $response_body, $depth + 1, $acc );
|
||||
return get_recipient_urls( $response, $depth + 1, $acc );
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@ -114,19 +117,23 @@ function get_recipient_urls( $object, $depth, $acc ) {
|
||||
}
|
||||
}
|
||||
|
||||
function post_activity_to_inboxes( $activity, $recipients ) {
|
||||
function post_activity_to_inboxes( $actor_id, $activity, $recipients ) {
|
||||
foreach ( $recipients as $inbox ) {
|
||||
if ( \util\is_local_url( $inbox ) ) {
|
||||
$request = \WP_REST_Request::from_url( $inbox );
|
||||
$request->set_method('POST');
|
||||
$request->set_body( $activity );
|
||||
$request->add_header( 'Content-Type', 'application/ld+json' );
|
||||
$request->add_header( 'Signature', signature_header( $inbox, $actor_id ) );
|
||||
$server = rest_get_server();
|
||||
$server->dispatch( $request );
|
||||
} else {
|
||||
$args = array(
|
||||
'body' => $activity,
|
||||
'headers' => array( 'Content-Type' => 'application/ld+json' )
|
||||
'headers' => array(
|
||||
'Content-Type' => 'application/ld+json',
|
||||
'Signature' => get_signing_string( $inbox, $actor_id ),
|
||||
)
|
||||
);
|
||||
wp_remote_post( $inbox, $args );
|
||||
}
|
||||
@ -139,10 +146,10 @@ function get_signing_string( $inbox_url ) {
|
||||
$parsed = parse_url( $inbox_url );
|
||||
return "(request-target): post $parsed[path]
|
||||
host: $parsed[host]
|
||||
date: $now_str"
|
||||
date: $now_str";
|
||||
}
|
||||
|
||||
function signature_header( $inbox_url, $actor_id ) {
|
||||
// TODO
|
||||
return \pgp\sign_data( get_signing_string( $inbox_url ), $actor_id );
|
||||
}
|
||||
?>
|
||||
|
@ -32,7 +32,7 @@ function handle_activity( $actor_slug, $activity ) {
|
||||
array( 'status' => 400 )
|
||||
);
|
||||
}
|
||||
forward_activity( $activity );
|
||||
forward_activity( $actor_slug, $activity );
|
||||
$activity = persist_activity( $actor_slug, $activity );
|
||||
if ( is_wp_error( $activity ) ) {
|
||||
return $activity;
|
||||
@ -70,7 +70,7 @@ function handle_activity( $actor_slug, $activity ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
function forward_activity( $activity ) {
|
||||
function forward_activity( $actor_slug, $activity ) {
|
||||
if ( !array_key_exists( 'id', $activity ) ) {
|
||||
return;
|
||||
}
|
||||
@ -88,7 +88,7 @@ function forward_activity( $activity ) {
|
||||
if ( count( $collections ) === 0 ) {
|
||||
return;
|
||||
}
|
||||
\deliver\deliver_activity( $activity );
|
||||
\deliver\deliver_activity( $actor_slug, $activity );
|
||||
}
|
||||
|
||||
function references_local_object( $object, $depth ) {
|
||||
|
@ -25,7 +25,6 @@ require_once plugin_dir_path( __FILE__ ) . 'activities/undo.php';
|
||||
require_once plugin_dir_path( __FILE__ ) . '../util.php';
|
||||
|
||||
function handle_activity( $actor_slug, $activity ) {
|
||||
xdebug_break();
|
||||
// TODO handle authentication/authorization
|
||||
$activity = \util\dereference_object( $activity );
|
||||
if ( is_wp_error( $activity ) ) {
|
||||
@ -118,7 +117,7 @@ function handle_activity( $actor_slug, $activity ) {
|
||||
if ( is_wp_error( $activity ) ) {
|
||||
return $activity;
|
||||
}
|
||||
deliver_activity( $activity );
|
||||
deliver_activity( $actor_slug, $activity );
|
||||
$res = new \WP_REST_Response();
|
||||
$res->set_status(201);
|
||||
$res->header( 'Location', $activity['id'] );
|
||||
@ -157,8 +156,8 @@ function get_outbox( $actor_slug ) {
|
||||
) );
|
||||
}
|
||||
|
||||
function deliver_activity( $activity ) {
|
||||
\deliver\deliver_activity( $activity );
|
||||
function deliver_activity( $actor_slug, $activity ) {
|
||||
\deliver\deliver_activity( $actor_slug, $activity );
|
||||
$activity = \activities\strip_private_fields( $activity );
|
||||
return $activity;
|
||||
}
|
||||
|
@ -58,6 +58,12 @@ function get_object_from_url_helper( $url, $depth ) {
|
||||
function retrieve_local_object( $url ) {
|
||||
$server = rest_get_server();
|
||||
$request = \WP_REST_Request::from_url( $url );
|
||||
if ( ! $request ) {
|
||||
return new \WP_Error(
|
||||
'not_local_url',
|
||||
__( 'Expected a local URL', 'pterotype' )
|
||||
);
|
||||
}
|
||||
$response = $server->dispatch( $request );
|
||||
if ( $response->is_error() ) {
|
||||
return $response->as_error();
|
||||
|
Loading…
Reference in New Issue
Block a user