From 64237502504e0834885e495763f0ad60fdc98019 Mon Sep 17 00:00:00 2001 From: Diogo Cordeiro Date: Fri, 11 Oct 2019 17:08:37 +0100 Subject: [PATCH] [ActivityPub] Slightly increase robustness on exception handling Also ported Activitypub_rsa to PHP7 Minor indentation fixes --- plugins/ActivityPub/actions/apinbox.php | 52 ++++-- .../classes/Activitypub_profile.php | 152 ++++++++++-------- .../ActivityPub/classes/Activitypub_rsa.php | 51 +++--- plugins/ActivityPub/lib/explorer.php | 51 +++--- 4 files changed, 178 insertions(+), 128 deletions(-) diff --git a/plugins/ActivityPub/actions/apinbox.php b/plugins/ActivityPub/actions/apinbox.php index e7f8663b9d..04c4341e5e 100644 --- a/plugins/ActivityPub/actions/apinbox.php +++ b/plugins/ActivityPub/actions/apinbox.php @@ -37,7 +37,7 @@ defined('GNUSOCIAL') || die(); class apInboxAction extends ManagedAction { protected $needLogin = false; - protected $canPost = true; + protected $canPost = true; /** * Handle the Inbox request @@ -57,15 +57,33 @@ class apInboxAction extends ManagedAction common_debug('ActivityPub Inbox: Received a POST request.'); $body = $data = file_get_contents('php://input'); - common_debug('ActivityPub Inbox: Request contents: '.$data); + 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']); - $aprofile = Activitypub_profile::from_profile($actor); + try { + $actor = Activitypub_explorer::get_profile_from_url($data['actor']); + } catch (HTTP_Request2_Exception $e) { + ActivityPubReturn::error('Failed to retrieve remote actor information.'); + } catch (NoProfileException $e) { + // Assert: This won't happen. + common_log(LOG_ERR, 'PLEASE REPORT THIS: ActivityPub Inbox Handler failed with NoProfileException while retrieving remote actor information: ' . $e->getMessage()); + ActivityPubReturn::error('An unknown error has occurred. This was logged, please alert the sysadmin.'); + } catch (ServerException $e) { + ActivityPubReturn::error('Could not store this remote actor.'); + } catch (Exception $e) { + ActivityPubReturn::error('Invalid actor.'); + } + try { + $aprofile = Activitypub_profile::from_profile($actor); + } catch (Exception $e) { + // Assert: This won't happen. + common_log(LOG_ERR, 'PLEASE REPORT THIS: ActivityPub Inbox Handler failed while retrieving AProfile from Profile: ' . $e->getMessage()); + ActivityPubReturn::error('An unknown error has occurred. This was logged, please alert the sysadmin.'); + } $actor_public_key = new Activitypub_rsa(); $actor_public_key = $actor_public_key->ensure_public_key($actor); @@ -73,7 +91,7 @@ class apInboxAction extends ManagedAction 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)); + common_debug('ActivityPub Inbox: Request Headers: ' . print_r($headers, true)); if (!isset($headers['signature'])) { common_debug('ActivityPub Inbox: HTTP Signature: Missing Signature header.'); @@ -82,25 +100,33 @@ class apInboxAction extends ManagedAction // Extract the signature properties $signatureData = HTTPSignature::parseSignatureHeader($headers['signature']); - common_debug('ActivityPub Inbox: HTTP Signature Data: '.print_r($signatureData, true)); + common_debug('ActivityPub Inbox: HTTP Signature Data: ' . print_r($signatureData, true)); if (isset($signatureData['error'])) { - common_debug('ActivityPub Inbox: HTTP Signature: '.json_encode($signatureData, true)); + common_debug('ActivityPub Inbox: HTTP Signature: ' . json_encode($signatureData, true)); ActivityPubReturn::error(json_encode($signatureData, true), 400); } list($verified, $headers) = HTTPSignature::verify($actor_public_key, $signatureData, $headers, $path, $body); - // If the signature fails verification the first time, update profile as it might have change public key - if($verified !== 1) { - $res = Activitypub_explorer::get_remote_user_activity($aprofile->getUri()); - $actor = Activitypub_profile::update_profile($aprofile, $res); + // If the signature fails verification the first time, update profile as it might have changed public key + if ($verified !== 1) { + try { + $res = Activitypub_explorer::get_remote_user_activity($aprofile->getUri()); + } catch (Exception $e) { + ActivityPubReturn::error('Invalid remote actor.'); + } + try { + $actor = Activitypub_profile::update_profile($aprofile, $res); + } catch (Exception $e) { + ActivityPubReturn::error('Failed to updated remote actor information.'); + } $actor_public_key = new Activitypub_rsa(); $actor_public_key = $actor_public_key->ensure_public_key($actor); - list($verified, $headers) = HTTPSignature::verify($actor_public_key, $signatureData, $headers, $path, $body); + list($verified, /*$headers*/) = HTTPSignature::verify($actor_public_key, $signatureData, $headers, $path, $body); } // If it still failed despite profile update - if($verified !== 1) { + if ($verified !== 1) { common_debug('ActivityPub Inbox: HTTP Signature: Invalid signature.'); ActivityPubReturn::error('Invalid signature.'); } diff --git a/plugins/ActivityPub/classes/Activitypub_profile.php b/plugins/ActivityPub/classes/Activitypub_profile.php index 61c77f5e2b..b73d4bc131 100644 --- a/plugins/ActivityPub/classes/Activitypub_profile.php +++ b/plugins/ActivityPub/classes/Activitypub_profile.php @@ -53,8 +53,8 @@ class Activitypub_profile extends Managed_DataObject /** * Return table definition for Schema setup and DB_DataObject usage. * - * @author Diogo Cordeiro * @return array array of column definitions + * @author Diogo Cordeiro */ public static function schemaDef() { @@ -81,6 +81,7 @@ class Activitypub_profile extends Managed_DataObject * @return array array to be used in a response * @throws InvalidUrlException * @throws ServerException + * @throws Exception * @author Diogo Cordeiro */ public static function profile_to_array($profile) @@ -91,38 +92,38 @@ class Activitypub_profile extends Managed_DataObject $public_key = $rsa->ensure_public_key($profile); unset($rsa); $res = [ - '@context' => [ + '@context' => [ 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1', [ 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' ] ], - 'id' => $uri, - 'type' => 'Person', - 'following' => common_local_url('apActorFollowing', ['id' => $id]), - 'followers' => common_local_url('apActorFollowers', ['id' => $id]), - 'liked' => common_local_url('apActorLiked', ['id' => $id]), - 'inbox' => common_local_url('apInbox', ['id' => $id]), - 'outbox' => common_local_url('apActorOutbox', ['id' => $id]), + 'id' => $uri, + 'type' => 'Person', + 'following' => common_local_url('apActorFollowing', ['id' => $id]), + 'followers' => common_local_url('apActorFollowers', ['id' => $id]), + 'liked' => common_local_url('apActorLiked', ['id' => $id]), + 'inbox' => common_local_url('apInbox', ['id' => $id]), + 'outbox' => common_local_url('apActorOutbox', ['id' => $id]), 'preferredUsername' => $profile->getNickname(), - 'name' => $profile->getBestName(), - 'summary' => ($desc = $profile->getDescription()) == null ? "" : $desc, - 'url' => $profile->getUrl(), + 'name' => $profile->getBestName(), + 'summary' => ($desc = $profile->getDescription()) == null ? "" : $desc, + 'url' => $profile->getUrl(), 'manuallyApprovesFollowers' => false, 'publicKey' => [ - 'id' => $uri."#public-key", + 'id' => $uri . "#public-key", 'owner' => $uri, 'publicKeyPem' => $public_key ], 'tag' => [], 'attachment' => [], 'icon' => [ - 'type' => 'Image', + 'type' => 'Image', 'mediaType' => 'image/png', - 'height' => AVATAR_PROFILE_SIZE, - 'width' => AVATAR_PROFILE_SIZE, - 'url' => $profile->avatarUrl(AVATAR_PROFILE_SIZE) + 'height' => AVATAR_PROFILE_SIZE, + 'width' => AVATAR_PROFILE_SIZE, + 'url' => $profile->avatarUrl(AVATAR_PROFILE_SIZE) ] ]; @@ -140,9 +141,9 @@ class Activitypub_profile extends Managed_DataObject /** * Insert the current object variables into the database * + * @throws ServerException * @author Diogo Cordeiro * @access public - * @throws ServerException */ public function do_insert() { @@ -151,11 +152,11 @@ class Activitypub_profile extends Managed_DataObject $profile->created = $this->created = $this->modified = common_sql_now(); $fields = [ - 'uri' => 'profileurl', - 'nickname' => 'nickname', - 'fullname' => 'fullname', - 'bio' => 'bio' - ]; + 'uri' => 'profileurl', + 'nickname' => 'nickname', + 'fullname' => 'fullname', + 'bio' => 'bio' + ]; foreach ($fields as $af => $pf) { $profile->$pf = $this->$af; @@ -179,7 +180,7 @@ class Activitypub_profile extends Managed_DataObject /** * Fetch the locally stored profile for this Activitypub_profile * - * @return Profile + * @return get_called_class * @throws NoProfileException if it was not found * @author Diogo Cordeiro */ @@ -195,10 +196,10 @@ class Activitypub_profile extends Managed_DataObject /** * Generates an Activitypub_profile from a Profile * - * @author Diogo Cordeiro * @param Profile $profile * @return Activitypub_profile * @throws Exception if no Activitypub_profile exists for given Profile + * @author Diogo Cordeiro */ public static function from_profile(Profile $profile) { @@ -211,16 +212,16 @@ class Activitypub_profile extends Managed_DataObject // create one! $aprofile = self::create_from_local_profile($profile); } else { - throw new Exception('No Activitypub_profile for Profile ID: '.$profile_id. ', this is a local user.'); + throw new Exception('No Activitypub_profile for Profile ID: ' . $profile_id . ', this is a local user.'); } } $fields = [ - 'uri' => 'profileurl', - 'nickname' => 'nickname', - 'fullname' => 'fullname', - 'bio' => 'bio' - ]; + 'uri' => 'profileurl', + 'nickname' => 'nickname', + 'fullname' => 'fullname', + 'bio' => 'bio' + ]; foreach ($fields as $af => $pf) { $aprofile->$af = $profile->$pf; @@ -229,7 +230,8 @@ class Activitypub_profile extends Managed_DataObject return $aprofile; } - public static function from_profile_collection(array $profiles): array { + public static function from_profile_collection(array $profiles): array + { $ap_profiles = []; foreach ($profiles as $profile) { @@ -251,6 +253,8 @@ class Activitypub_profile extends Managed_DataObject * @param Profile $profile * @return Activitypub_profile * @throws HTTP_Request2_Exception + * @throws Exception + * @throws Exception * @author Diogo Cordeiro */ private static function create_from_local_profile(Profile $profile) @@ -266,13 +270,13 @@ class Activitypub_profile extends Managed_DataObject $aprofile->created = $aprofile->modified = common_sql_now(); - $aprofile = new Activitypub_profile; - $aprofile->profile_id = $profile->getID(); - $aprofile->uri = $url; - $aprofile->nickname = $profile->getNickname(); - $aprofile->fullname = $profile->getFullname(); - $aprofile->bio = substr($profile->getDescription(), 0, 1000); - $aprofile->inboxuri = $inboxes["inbox"]; + $aprofile = new Activitypub_profile; + $aprofile->profile_id = $profile->getID(); + $aprofile->uri = $url; + $aprofile->nickname = $profile->getNickname(); + $aprofile->fullname = $profile->getFullname(); + $aprofile->bio = substr($profile->getDescription(), 0, 1000); + $aprofile->inboxuri = $inboxes["inbox"]; $aprofile->sharedInboxuri = $inboxes["sharedInbox"]; $aprofile->insert(); @@ -283,8 +287,8 @@ class Activitypub_profile extends Managed_DataObject /** * Returns sharedInbox if possible, inbox otherwise * - * @author Diogo Cordeiro * @return string Inbox URL + * @author Diogo Cordeiro */ public function get_inbox() { @@ -298,8 +302,8 @@ class Activitypub_profile extends Managed_DataObject /** * Getter for uri property * - * @author Diogo Cordeiro * @return string URI + * @author Diogo Cordeiro */ public function getUri() { @@ -309,8 +313,8 @@ class Activitypub_profile extends Managed_DataObject /** * Getter for url property * - * @author Diogo Cordeiro * @return string URL + * @author Diogo Cordeiro */ public function getUrl() { @@ -320,8 +324,8 @@ class Activitypub_profile extends Managed_DataObject /** * Getter for id property * - * @author Diogo Cordeiro * @return int + * @author Diogo Cordeiro */ public function getID() { @@ -352,11 +356,11 @@ class Activitypub_profile extends Managed_DataObject * This should never return null -- you will either get an object or * an exception will be thrown. * - * @author GNU social - * @author Diogo Cordeiro * @param string $addr WebFinger address * @return Activitypub_profile * @throws Exception on error conditions + * @author Diogo Cordeiro + * @author GNU social */ public static function ensure_webfinger($addr) { @@ -402,7 +406,7 @@ class Activitypub_profile extends Managed_DataObject // If there's an Hcard, let's grab its info if (array_key_exists('hcard', $hints)) { if (!array_key_exists('profileurl', $hints) || - $hints['hcard'] != $hints['profileurl']) { + $hints['hcard'] != $hints['profileurl']) { $hcardHints = DiscoveryHints::fromHcardUrl($hints['hcard']); $hints = array_merge($hcardHints, $hints); } @@ -441,17 +445,17 @@ class Activitypub_profile extends Managed_DataObject * @param Activitypub_profile $aprofile * @param array $res remote response * @return Profile remote Profile object - * @throws Exception + * @throws NoProfileException * @author Diogo Cordeiro */ public static function update_profile($aprofile, $res) { // ActivityPub Profile - $aprofile->uri = $res['id']; - $aprofile->nickname = $res['preferredUsername']; - $aprofile->fullname = isset($res['name']) ? $res['name'] : null; - $aprofile->bio = isset($res['summary']) ? substr(strip_tags($res['summary']), 0, 1000) : null; - $aprofile->inboxuri = $res['inbox']; + $aprofile->uri = $res['id']; + $aprofile->nickname = $res['preferredUsername']; + $aprofile->fullname = isset($res['name']) ? $res['name'] : null; + $aprofile->bio = isset($res['summary']) ? substr(strip_tags($res['summary']), 0, 1000) : null; + $aprofile->inboxuri = $res['inbox']; $aprofile->sharedInboxuri = isset($res['endpoints']['sharedInbox']) ? $res['endpoints']['sharedInbox'] : $res['inbox']; $profile = $aprofile->local_profile(); @@ -459,11 +463,11 @@ class Activitypub_profile extends Managed_DataObject $profile->modified = $aprofile->modified = common_sql_now(); $fields = [ - 'uri' => 'profileurl', - 'nickname' => 'nickname', - 'fullname' => 'fullname', - 'bio' => 'bio' - ]; + 'uri' => 'profileurl', + 'nickname' => 'nickname', + 'fullname' => 'fullname', + 'bio' => 'bio' + ]; foreach ($fields as $af => $pf) { $profile->$pf = $aprofile->$af; @@ -482,7 +486,7 @@ class Activitypub_profile extends Managed_DataObject Activitypub_explorer::update_avatar($profile, $res['icon']['url']); } catch (Exception $e) { // Let the exception go, it isn't a serious issue - common_debug('An error ocurred while grabbing remote avatar'.$e->getMessage()); + common_debug('An error ocurred while grabbing remote avatar' . $e->getMessage()); } } @@ -497,7 +501,8 @@ class Activitypub_profile extends Managed_DataObject * @return int number of subscribers * @author Bruno Casteleiro */ - public static function subscriberCount(Profile $profile): int { + public static function subscriberCount(Profile $profile): int + { $cnt = self::cacheGet(sprintf('activitypub_profile:subscriberCount:%d', $profile->id)); if ($cnt !== false && is_int($cnt)) { @@ -523,7 +528,8 @@ class Activitypub_profile extends Managed_DataObject * @return int number of subscriptions * @author Bruno Casteleiro */ - public static function subscriptionCount(Profile $profile): int { + public static function subscriptionCount(Profile $profile): int + { $cnt = self::cacheGet(sprintf('activitypub_profile:subscriptionCount:%d', $profile->id)); if ($cnt !== false && is_int($cnt)) { @@ -541,19 +547,21 @@ class Activitypub_profile extends Managed_DataObject return $cnt; } - public static function updateSubscriberCount(Profile $profile, $adder) { + public static function updateSubscriberCount(Profile $profile, $adder) + { $cnt = self::cacheGet(sprintf('activitypub_profile:subscriberCount:%d', $profile->id)); if ($cnt !== false && is_int($cnt)) { - self::cacheSet(sprintf('activitypub_profile:subscriberCount:%d', $profile->id), $cnt+$adder); + self::cacheSet(sprintf('activitypub_profile:subscriberCount:%d', $profile->id), $cnt + $adder); } } - public static function updateSubscriptionCount(Profile $profile, $adder) { + public static function updateSubscriptionCount(Profile $profile, $adder) + { $cnt = self::cacheGet(sprintf('activitypub_profile:subscriptionCount:%d', $profile->id)); if ($cnt !== false && is_int($cnt)) { - self::cacheSet(sprintf('activitypub_profile:subscriptionCount:%d', $profile->id), $cnt+$adder); + self::cacheSet(sprintf('activitypub_profile:subscriptionCount:%d', $profile->id), $cnt + $adder); } } @@ -567,7 +575,8 @@ class Activitypub_profile extends Managed_DataObject * @return array subscriber profile objects * @author Bruno Casteleiro */ - public static function getSubscribers(Profile $profile, $offset = 0, $limit = null): array { + public static function getSubscribers(Profile $profile, $offset = 0, $limit = null): array + { $cache = false; if ($offset + $limit <= Subscription::CACHE_WINDOW) { $subs = self::cacheGet(sprintf('activitypub_profile:subscriberCollection:%d', $profile->id)); @@ -612,7 +621,8 @@ class Activitypub_profile extends Managed_DataObject * @return array subscribed profile objects * @author Bruno Casteleiro */ - public static function getSubscribed(Profile $profile, $offset = 0, $limit = null): array { + public static function getSubscribed(Profile $profile, $offset = 0, $limit = null): array + { $cache = false; if ($offset + $limit <= Subscription::CACHE_WINDOW) { $subs = self::cacheGet(sprintf('activitypub_profile:subscribedCollection:%d', $profile->id)); @@ -641,7 +651,7 @@ class Activitypub_profile extends Managed_DataObject } if ($cache) { - self::cacheSet(sprintf('activitypub_profile:subscribedCollection:%d', $profile->id), $profiles); + self::cacheSet(sprintf('activitypub_profile:subscribedCollection:%d', $profile->id), $profiles); } return $profiles; @@ -654,9 +664,11 @@ class Activitypub_profile extends Managed_DataObject * @param Profile $actor subscriber profile object * @param Profile $other subscribed profile object * @return void + * @throws Exception * @author Bruno Casteleiro */ - public static function subscribeCacheUpdate(Profile $actor, Profile $other) { + public static function subscribeCacheUpdate(Profile $actor, Profile $other) + { self::blow('activitypub_profile:subscribedCollection:%d', $actor->getID()); self::blow('activitypub_profile:subscriberCollection:%d', $other->id); self::updateSubscriptionCount($actor, +1); @@ -670,9 +682,11 @@ class Activitypub_profile extends Managed_DataObject * @param Profile $actor subscriber profile object * @param Profile $other subscribed profile object * @return void + * @throws Exception * @author Bruno Casteleiro */ - public static function unsubscribeCacheUpdate(Profile $actor, Profile $other) { + public static function unsubscribeCacheUpdate(Profile $actor, Profile $other) + { self::blow('activitypub_profile:subscribedCollection:%d', $actor->getID()); self::blow('activitypub_profile:subscriberCollection:%d', $other->id); self::updateSubscriptionCount($actor, -1); diff --git a/plugins/ActivityPub/classes/Activitypub_rsa.php b/plugins/ActivityPub/classes/Activitypub_rsa.php index b93ee23f3f..d9770dbb3b 100644 --- a/plugins/ActivityPub/classes/Activitypub_rsa.php +++ b/plugins/ActivityPub/classes/Activitypub_rsa.php @@ -46,27 +46,35 @@ class Activitypub_rsa extends Managed_DataObject /** * Return table definition for Schema setup and DB_DataObject usage. * - * @author Diogo Cordeiro * @return array array of column definitions + * @author Diogo Cordeiro */ public static function schemaDef() { return [ - 'fields' => [ - 'profile_id' => ['type' => 'int', 'not null' => true], - 'private_key' => ['type' => 'text'], - 'public_key' => ['type' => 'text', 'not null' => true], - 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'], - 'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'], - ], - 'primary key' => ['profile_id'], - 'foreign keys' => [ - 'activitypub_profile_profile_id_fkey' => ['profile', ['profile_id' => 'id']], - ], + 'fields' => [ + 'profile_id' => ['type' => 'int', 'not null' => true], + 'private_key' => ['type' => 'text'], + 'public_key' => ['type' => 'text', 'not null' => true], + 'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'], + 'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'], + ], + 'primary key' => ['profile_id'], + 'foreign keys' => [ + 'activitypub_profile_profile_id_fkey' => ['profile', ['profile_id' => 'id']], + ], ]; } - public function get_private_key($profile) + /** + * Private key getter + * + * @param Profile $profile + * @return string + * @throws ServerException + * @throws Exception + */ + public function get_private_key(Profile $profile): string { $this->profile_id = $profile->getID(); $apRSA = self::getKV('profile_id', $this->profile_id); @@ -90,9 +98,10 @@ class Activitypub_rsa extends Managed_DataObject * @param bool $fetch * @return string The public key * @throws ServerException It should never occur, but if so, we break everything! + * @throws Exception * @author Diogo Cordeiro */ - public function ensure_public_key($profile, $fetch = true) + public function ensure_public_key(Profile $profile, bool $fetch = true): string { $this->profile_id = $profile->getID(); $apRSA = self::getKV('profile_id', $this->profile_id); @@ -119,11 +128,11 @@ class Activitypub_rsa extends Managed_DataObject /** * Insert the current object variables into the database. * + * @throws ServerException * @author Diogo Cordeiro * @access public - * @throws ServerException */ - public function store_keys() + public function store_keys(): void { $this->created = $this->modified = common_sql_now(); $ok = $this->insert(); @@ -135,14 +144,14 @@ class Activitypub_rsa extends Managed_DataObject /** * Generates a pair of RSA keys. * - * @author PHP Manual Contributed Notes * @param string $private_key in/out * @param string $public_key in/out + * @author PHP Manual Contributed Notes */ - public static function generate_keys(&$private_key, &$public_key) + public static function generate_keys(string &$private_key, string &$public_key): void { $config = [ - 'digest_alg' => 'sha512', + 'digest_alg' => 'sha512', 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA, ]; @@ -162,12 +171,12 @@ class Activitypub_rsa extends Managed_DataObject /** * Update public key. * - * @param Profile $profile + * @param Profile|Activitypub_profile $profile * @param string $public_key * @throws Exception * @author Diogo Cordeiro */ - public static function update_public_key($profile, $public_key) + public static function update_public_key($profile, string $public_key): void { // Public Key $apRSA = new Activitypub_rsa(); diff --git a/plugins/ActivityPub/lib/explorer.php b/plugins/ActivityPub/lib/explorer.php index f4d2abee85..62ff446163 100644 --- a/plugins/ActivityPub/lib/explorer.php +++ b/plugins/ActivityPub/lib/explorer.php @@ -46,13 +46,13 @@ class Activitypub_explorer /** * Shortcut function to get a single profile from its URL. * - * @param string $url - * @param bool $grab_online whether to try online grabbing, defaults to true + * @param string $url + * @param bool $grab_online whether to try online grabbing, defaults to true * @return Profile - * @throws HTTP_Request2_Exception - * @throws NoProfileException - * @throws Exception - * @throws ServerException + * @throws HTTP_Request2_Exception Network issues + * @throws NoProfileException This won't happen + * @throws Exception Invalid request + * @throws ServerException Error storing remote actor * @author Diogo Cordeiro */ public static function get_profile_from_url($url, $grab_online = true) @@ -71,8 +71,8 @@ class Activitypub_explorer * This function cleans the $this->discovered_actor_profiles array * so that there is no erroneous data * - * @param string $url User's url - * @param bool $grab_online whether to try online grabbing, defaults to true + * @param string $url User's url + * @param bool $grab_online whether to try online grabbing, defaults to true * @return array of Profile objects * @throws HTTP_Request2_Exception * @throws NoProfileException @@ -97,8 +97,8 @@ class Activitypub_explorer * This is a recursive function that will accumulate the results on * $discovered_actor_profiles array * - * @param string $url User's url - * @param bool $grab_online whether to try online grabbing, defaults to true + * @param string $url User's url + * @param bool $grab_online whether to try online grabbing, defaults to true * @return array of Profile objects * @throws HTTP_Request2_Exception * @throws NoProfileException @@ -122,7 +122,7 @@ class Activitypub_explorer /** * This ensures that we are using a valid ActivityPub URI * - * @param string $url + * @param string $url * @return bool success state (related to the response) * @throws Exception (If the HTTP request fails) * @author Diogo Cordeiro @@ -146,8 +146,8 @@ class Activitypub_explorer * Get a local user profile from its URL and joins it on * $this->discovered_actor_profiles * - * @param string $uri Actor's uri - * @param bool $online + * @param string $uri Actor's uri + * @param bool $online * @return bool success state * @throws NoProfileException * @throws Exception @@ -171,6 +171,7 @@ class Activitypub_explorer // Is this a known filthy little mudblood? $aprofile = self::get_aprofile_by_url($uri); if ($aprofile instanceof Activitypub_profile) { + // Assert: This AProfile has a Profile, no try catch. $profile = $aprofile->local_profile(); common_debug('ActivityPub Explorer: Found a local Aprofile for ' . $uri); // We found something! @@ -184,7 +185,7 @@ class Activitypub_explorer $ACTIVITYPUB_BASE_ACTOR_URI_length = strlen(ACTIVITYPUB_BASE_ACTOR_URI); if (substr($uri, 0, $ACTIVITYPUB_BASE_ACTOR_URI_length) == ACTIVITYPUB_BASE_ACTOR_URI) { try { - $profile = Profile::getByID(intval(substr($uri, $ACTIVITYPUB_BASE_ACTOR_URI_length))); + $profile = Profile::getByID((int)substr($uri, $ACTIVITYPUB_BASE_ACTOR_URI_length)); common_debug('ActivityPub Explorer: Found a Profile for ' . $uri); // We found something! $this->discovered_actor_profiles[] = $profile; @@ -210,7 +211,7 @@ class Activitypub_explorer * Get a remote user(s) profile(s) from its URL and joins it on * $this->discovered_actor_profiles * - * @param string $url User's url + * @param string $url User's url * @return bool success state * @throws HTTP_Request2_Exception * @throws NoProfileException @@ -247,7 +248,7 @@ class Activitypub_explorer /** * Save remote user profile in local instance * - * @param array $res remote response + * @param array $res remote response * @return Profile remote Profile object * @throws NoProfileException * @throws ServerException @@ -290,8 +291,8 @@ class Activitypub_explorer /** * Download and update given avatar image * - * @param Profile $profile - * @param string $url + * @param Profile $profile + * @param string $url * @return Avatar The Avatar we have on disk. * @throws Exception in various failure cases * @author GNU social @@ -357,7 +358,7 @@ class Activitypub_explorer * Validates a remote response in order to determine whether this * response is a valid profile or not * - * @param array $res remote response + * @param array $res remote response * @return bool success state * @author Diogo Cordeiro */ @@ -376,7 +377,7 @@ class Activitypub_explorer * potential ActivityPub remote profiles, as so it is important to use * this hacky workaround (at least for now) * - * @param string $v URL + * @param string $v URL * @return bool|Activitypub_profile false if fails | Aprofile object if successful * @author Diogo Cordeiro */ @@ -399,7 +400,7 @@ class Activitypub_explorer /** * Given a valid actor profile url returns its inboxes * - * @param string $url of Actor profile + * @param string $url of Actor profile * @return bool|array false if fails | array with inbox and shared inbox if successful * @throws HTTP_Request2_Exception * @throws Exception @@ -426,7 +427,7 @@ class Activitypub_explorer /** * Allows the Explorer to transverse a collection of persons. * - * @param string $url + * @param string $url * @return bool * @throws HTTP_Request2_Exception * @throws NoProfileException @@ -461,9 +462,9 @@ class Activitypub_explorer * Get a remote user array from its URL (this function is only used for * profile updating and shall not be used for anything else) * - * @param string $url User's url - * @return mixed - * @throws Exception + * @param string $url User's url + * @return array + * @throws Exception Either network issues or unsupported Activity format * @author Diogo Cordeiro */ public static function get_remote_user_activity($url)