Sign outbound activities

This commit is contained in:
Jeremy Dormitzer 2018-10-06 08:01:50 -04:00
parent 76abc08dd4
commit 9c371b4720
5 changed files with 52 additions and 19 deletions

View File

@ -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
) );
}
?>

View File

@ -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 );
}
?>

View File

@ -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 ) {

View File

@ -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;
}

View File

@ -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();