diff --git a/actions/apactoroutbox.php b/actions/apactoroutbox.php index b357cd2..bf8c15e 100644 --- a/actions/apactoroutbox.php +++ b/actions/apactoroutbox.php @@ -124,7 +124,7 @@ class apActorOutboxAction extends ManagedAction // TODO: Handle other types if ($note->object_type == 'http://activitystrea.ms/schema/1.0/note') { $notices[] = Activitypub_create::create_to_array( - ActivityPubPlugin::actor_uri($note->getProfile()), + ActivityPubPlugin::actor_uri($note->getProfile()), Activitypub_notice::notice_to_array($note) ); } diff --git a/actions/apinbox.php b/actions/apinbox.php index 2844c38..991ff54 100755 --- a/actions/apinbox.php +++ b/actions/apinbox.php @@ -60,11 +60,45 @@ class apInboxAction extends ManagedAction common_debug('ActivityPub Inbox: Request contents: '.$data); $data = json_decode(file_get_contents('php://input'), true); + if (!isset($data['actor'])) { + ActivityPubReturn::error('Actor not found in the request.'); + } + + $actor = ActivityPub_explorer::get_profile_from_url($data['actor']); + $actor_public_key = new Activitypub_rsa(); + $actor_public_key = $actor_public_key->ensure_public_key($actor); + + common_debug('ActivityPub Inbox: HTTP Signature: Validation will now start!'); + + $headers = $this->get_all_headers(); + common_debug('ActivityPub Inbox: Request Headers: '.print_r($headers, true)); + + // TODO: Validate HTTP Signature + + common_debug('ActivityPub Inbox: HTTP Signature: Authorized request. Will now start the inbox handler.'); + try { - new Activitypub_inbox_handler($data); + new Activitypub_inbox_handler($data, $actor); ActivityPubReturn::answer(); } catch (Exception $e) { ActivityPubReturn::error($e->getMessage()); } } + + /** + * Get all HTTP header key/values as an associative array for the current request. + * + * @author PHP Manual Contributed Notes + * @return string[string] The HTTP header key/value pairs. + */ + private function get_all_headers() + { + $headers = []; + foreach ($_SERVER as $name => $value) { + if (substr($name, 0, 5) == 'HTTP_') { + $headers[strtolower(str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))))] = $value; + } + } + return $headers; + } } diff --git a/classes/Activitypub_notice.php b/classes/Activitypub_notice.php index c98bb5d..2f413a5 100755 --- a/classes/Activitypub_notice.php +++ b/classes/Activitypub_notice.php @@ -202,7 +202,7 @@ class Activitypub_notice extends Managed_DataObject // Mentions $mentions = []; - if (isset ($object['tag']) && is_array($object['tag'])) { + if (isset($object['tag']) && is_array($object['tag'])) { foreach ($object['tag'] as $tag) { if ($tag['type'] == 'Mention') { $mentions[] = $tag['href']; diff --git a/utils/inbox_handler.php b/utils/inbox_handler.php index 3f78a77..c0680dc 100644 --- a/utils/inbox_handler.php +++ b/utils/inbox_handler.php @@ -49,8 +49,9 @@ class Activitypub_inbox_handler * * @author Diogo Cordeiro * @param Array $activity Activity we are receiving + * @param Profile $actor_profile Actor originating the activity */ - public function __construct($activity) + public function __construct($activity, $actor_profile = null) { $this->activity = $activity; $this->object = $activity['object']; @@ -59,7 +60,11 @@ class Activitypub_inbox_handler $this->validate_activity(); // Get Actor's Profile - $this->actor = ActivityPub_explorer::get_profile_from_url($this->activity['actor']); + if (!is_null($actor_profile)) { + $this->actor = $actor_profile; + } else { + $this->actor = ActivityPub_explorer::get_profile_from_url($this->activity['actor']); + } // Handle the Activity $this->process(); diff --git a/utils/postman.php b/utils/postman.php index e608d05..03f6509 100755 --- a/utils/postman.php +++ b/utils/postman.php @@ -63,15 +63,22 @@ class Activitypub_postman public function __construct($from, $to = []) { $this->actor = $from; - $this->to = $to; - $this->to[]= common_local_url('apActorFollowers', ['id' => $from->getID()]); + $discovery = new Activitypub_explorer(); + $this->to = array_merge( + $to, + $discovery->lookup(common_local_url( + 'apActorFollowers', + ['id' => $from->getID()] + )) + ); + unset($discovery); $this->actor_uri = ActivityPubPlugin::actor_uri($this->actor); $actor_private_key = new Activitypub_rsa(); $actor_private_key = $actor_private_key->get_private_key($this->actor); $context = new Context([ - 'keys' => [$this->actor_uri."#public-key" => $actor_private_key], + 'keys' => [$this->actor_uri.'#public-key' => $actor_private_key], 'algorithm' => 'rsa-sha256', 'headers' => ['(request-target)', 'date', 'content-type', 'accept', 'user-agent'], ]);