X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=src%2FProtocol%2FActivityPub%2FReceiver.php;h=66653579ea7f6739b0250dfbe373699f9cf7ed94;hb=78343599571fb42eb75ef63af13909fa34e50998;hp=5eae464e0542b5bfb6e18e59b8dd00991fade6af;hpb=4c5e9f206ebd24cd7188b897d9c01a08ef081ef1;p=friendica.git diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 5eae464e05..66653579ea 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -273,6 +273,8 @@ class Receiver public static function prepareObjectData(array $activity, int $uid, bool $push, bool &$trust_source): array { $id = JsonLD::fetchElement($activity, '@id'); + $object_id = JsonLD::fetchElement($activity, 'as:object', '@id'); + if (!empty($id) && !$trust_source) { $fetch_uid = $uid ?: self::getBestUserForActivity($activity); @@ -283,7 +285,13 @@ class Receiver if ($fetched_id == $id) { Logger::info('Activity had been fetched successfully', ['id' => $id]); $trust_source = true; - $activity = $object; + if ($id != $object_id) { + $activity = $object; + } else { + Logger::info('Fetched data is the object instead of the activity', ['id' => $id]); + unset($object['@context']); + $activity['as:object'] = $object; + } } else { Logger::info('Activity id is not equal', ['id' => $id, 'fetched' => $fetched_id]); } @@ -363,6 +371,10 @@ class Receiver $object_data['object_object'] = JsonLD::fetchElement($activity['as:object'], 'as:object'); $object_data['object_type'] = JsonLD::fetchElement($activity['as:object'], '@type'); $object_data['push'] = $push; + if ($type == 'as:Delete') { + $apcontact = APContact::getByURL($object_data['object_id'], true); + $trust_source = ($apcontact['type'] == 'Tombstone'); + } } elseif (in_array($type, ['as:Create', 'as:Update', 'as:Announce', 'as:Invite']) || strpos($type, '#emojiReaction')) { // Fetch the content only on activities where this matters // We can receive "#emojiReaction" when fetching content from Hubzilla systems @@ -417,6 +429,10 @@ class Receiver if (($type == 'as:Undo') && !empty($object_data['object_object'])) { $object_data['object_object_type'] = self::fetchObjectType([], $object_data['object_object'], $fetch_uid); } + + if (($type == 'as:Delete') && in_array($object_data['object_type'], array_merge(['as:Tombstone'], self::CONTENT_TYPES))) { + $trust_source = Processor::isActivityGone($object_data['object_id']); + } } $object_data = self::addActivityFields($object_data, $activity); @@ -437,17 +453,18 @@ class Receiver $object_data['receiver'] = array_replace($object_data['receiver'] ?? [], $receivers); $object_data['reception_type'] = array_replace($object_data['reception_type'] ?? [], $reception_types); - $author = $object_data['author'] ?? $actor; - if (!empty($author) && !empty($object_data['id'])) { - $author_host = parse_url($author, PHP_URL_HOST); - $id_host = parse_url($object_data['id'], PHP_URL_HOST); - if ($author_host == $id_host) { - Logger::info('Valid hosts', ['type' => $type, 'host' => $id_host]); - } else { - Logger::notice('Differing hosts on author and id', ['type' => $type, 'author' => $author_host, 'id' => $id_host]); - $trust_source = false; - } - } +// This check here interferes with Hubzilla posts where the author host differs from the host the post was created +// $author = $object_data['author'] ?? $actor; +// if (!empty($author) && !empty($object_data['id'])) { +// $author_host = parse_url($author, PHP_URL_HOST); +// $id_host = parse_url($object_data['id'], PHP_URL_HOST); +// if ($author_host == $id_host) { +// Logger::info('Valid hosts', ['type' => $type, 'host' => $id_host]); +// } else { +// Logger::notice('Differing hosts on author and id', ['type' => $type, 'author' => $author_host, 'id' => $id_host]); +// $trust_source = false; +// } +// } Logger::info('Processing ' . $object_data['type'] . ' ' . $object_data['object_type'] . ' ' . $object_data['id']); @@ -529,11 +546,6 @@ class Receiver $type = $object_data['type']; } - if (!$trust_source) { - Logger::info('Activity trust could not be achieved.', ['id' => $object_data['object_id'], 'type' => $type, 'signer' => $signer, 'actor' => $actor, 'attributedTo' => $attributed_to]); - return; - } - if (!empty($body) && empty($object_data['raw'])) { $object_data['raw'] = $body; } @@ -542,7 +554,7 @@ class Receiver if (!empty($activity['thread-completion'])) { $object_data['thread-completion'] = $activity['thread-completion']; } - + if (!empty($activity['completion-mode'])) { $object_data['completion-mode'] = $activity['completion-mode']; } @@ -551,10 +563,6 @@ class Receiver $object_data['thread-children-type'] = $activity['thread-children-type']; } - if (!empty($activity['recursion-depth'])) { - $object_data['recursion-depth'] = $activity['recursion-depth']; - } - // Internal flag for posts that arrived via relay if (!empty($activity['from-relay'])) { $object_data['from-relay'] = $activity['from-relay']; @@ -564,7 +572,18 @@ class Receiver $object_data['object_activity'] = $activity; } - $object_data = Queue::add($object_data, $type, $uid, $http_signer, $push); + if ($trust_source || DI::config()->get('debug', 'ap_inbox_store_untrusted')) { + $object_data = Queue::add($object_data, $type, $uid, $http_signer, $push, $trust_source); + } + + if (!$trust_source) { + Logger::info('Activity trust could not be achieved.', ['id' => $object_data['object_id'], 'type' => $type, 'signer' => $signer, 'actor' => $actor, 'attributedTo' => $attributed_to]); + return; + } + + if (!empty($activity['recursion-depth'])) { + $object_data['recursion-depth'] = $activity['recursion-depth']; + } if (in_array('as:Question', [$object_data['object_type'] ?? '', $object_data['object_object_type'] ?? ''])) { self::storeUnhandledActivity(false, $type, $object_data, $activity, $body, $uid, $trust_source, $push, $signer); @@ -572,13 +591,20 @@ class Receiver if (!self::routeActivities($object_data, $type, $push)) { self::storeUnhandledActivity(true, $type, $object_data, $activity, $body, $uid, $trust_source, $push, $signer); - //if (!DI::config()->get('debug', 'ap_log_unknown')) { - // Queue::remove($object_data); - //} + Queue::remove($object_data); } } - public static function routeActivities($object_data, $type, $push) + /** + * Route activities + * + * @param array $object_data + * @param string $type + * @param boolean $push + * + * @return boolean Could the activity be routed? + */ + public static function routeActivities(array $object_data, string $type, bool $push): bool { $activity = $object_data['object_activity'] ?? []; @@ -625,7 +651,7 @@ class Receiver $item = ActivityPub\Processor::createItem($object_data); if (empty($item)) { - return; + return false; } $item['post-reason'] = Item::PR_ANNOUNCEMENT; @@ -643,7 +669,7 @@ class Receiver $announce_object_data['raw'] = $object_data['raw']; } ActivityPub\Processor::createActivity($announce_object_data, Activity::ANNOUNCE); - } else echo "\n***************************\n"; + } } else { return false; } @@ -715,7 +741,7 @@ class Receiver case 'as:Remove': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { - ActivityPub\Processor::removeFromFeaturedCollection($object_data); + ActivityPub\Processor::removeFromFeaturedCollection($object_data); } elseif ($object_data['object_type'] == '') { // The object type couldn't be determined. We don't have it and we can't fetch it. We ignore this activity. Queue::remove($object_data); @@ -805,7 +831,7 @@ class Receiver return false; } break; - + default: Logger::info('Unknown activity: ' . $type . ' ' . $object_data['object_type']); return false; @@ -829,8 +855,12 @@ class Receiver */ private static function storeUnhandledActivity(bool $unknown, string $type, array $object_data, array $activity, string $body = '', int $uid = null, bool $trust_source = false, bool $push = false, array $signer = []) { + if (!DI::config()->get('debug', 'ap_log_unknown')) { + return; + } + $file = ($unknown ? 'unknown-' : 'unhandled-') . str_replace(':', '-', $type) . '-'; - + if (!empty($object_data['object_type'])) { $file .= str_replace(':', '-', $object_data['object_type']) . '-'; } @@ -1818,29 +1848,6 @@ class Receiver unset($object_data['receiver'][-1]); unset($object_data['reception_type'][-1]); - // Common object data: - - // Unhandled - // @context, type, actor, signature, mediaType, duration, replies, icon - - // Also missing: (Defined in the standard, but currently unused) - // audience, preview, endTime, startTime, image - - // Data in Notes: - - // Unhandled - // contentMap, announcement_count, announcements, context_id, likes, like_count - // inReplyToStatusId, shares, quoteUrl, statusnetConversationId - - // Data in video: - - // To-Do? - // category, licence, language, commentsEnabled - - // Unhandled - // views, waitTranscoding, state, support, subtitleLanguage - // likes, dislikes, shares, comments - return $object_data; } }