From 5a16a424ac6f6e016d8ccfd60a2c2b333b71ca1f Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 12 Mar 2022 07:08:10 +0000 Subject: [PATCH 1/6] Issue 11309: improved check for wanted posts --- src/Module/Diaspora/Receive.php | 2 +- src/Protocol/Diaspora.php | 125 ++++++++++++++++++-------------- 2 files changed, 71 insertions(+), 56 deletions(-) diff --git a/src/Module/Diaspora/Receive.php b/src/Module/Diaspora/Receive.php index fd8c201d4..3b1049361 100644 --- a/src/Module/Diaspora/Receive.php +++ b/src/Module/Diaspora/Receive.php @@ -78,7 +78,7 @@ class Receive extends BaseModule $this->logger->info('Diaspora: Dispatching.'); - Diaspora::dispatchPublic($msg); + Diaspora::dispatchPublic($msg, Diaspora::PUSHED); } /** diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 331a3bd9f..7b2b03f55 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -56,6 +56,10 @@ use SimpleXMLElement; */ class Diaspora { + const PUSHED = 0; + const FETCHED = 1; + const FORCED_FETCH = 2; + /** * Return a list of participating contacts for a thread * @@ -449,14 +453,14 @@ class Diaspora /** * Dispatches public messages and find the fitting receivers * - * @param array $msg The post that will be dispatched - * @param bool $fetched The message had been fetched (default "false") + * @param array $msg The post that will be dispatched + * @param int $direction Indicates if the message had been fetched or pushed * * @return int The message id of the generated message, "true" or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function dispatchPublic($msg, bool $fetched = false) + public static function dispatchPublic($msg, int $direction) { $enabled = intval(DI::config()->get("system", "diaspora_enabled")); if (!$enabled) { @@ -470,7 +474,7 @@ class Diaspora } $importer = ["uid" => 0, "page-flags" => User::PAGE_FLAGS_FREELOVE]; - $success = self::dispatch($importer, $msg, $fields, $fetched); + $success = self::dispatch($importer, $msg, $fields, $direction); return $success; } @@ -478,16 +482,16 @@ class Diaspora /** * Dispatches the different message types to the different functions * - * @param array $importer Array of the importer user - * @param array $msg The post that will be dispatched - * @param SimpleXMLElement $fields SimpleXML object that contains the message - * @param bool $fetched The message had been fetched (default "false") + * @param array $importer Array of the importer user + * @param array $msg The post that will be dispatched + * @param SimpleXMLElement $fields SimpleXML object that contains the message + * @param int $direction Indicates if the message had been fetched or pushed * * @return int The message id of the generated message, "true" or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - public static function dispatch(array $importer, $msg, SimpleXMLElement $fields = null, bool $fetched = false) + public static function dispatch(array $importer, $msg, SimpleXMLElement $fields = null, int $direction = self::PUSHED) { // The sender is the handle of the contact that sent the message. // This will often be different with relayed messages (for example "like" and "comment") @@ -520,7 +524,7 @@ class Diaspora return self::receiveAccountDeletion($fields); case "comment": - return self::receiveComment($importer, $sender, $fields, $msg["message"], $fetched); + return self::receiveComment($importer, $sender, $fields, $msg["message"], $direction); case "contact": if (!$private) { @@ -537,7 +541,7 @@ class Diaspora return self::receiveConversation($importer, $msg, $fields); case "like": - return self::receiveLike($importer, $sender, $fields, $fetched); + return self::receiveLike($importer, $sender, $fields, $direction); case "message": if (!$private) { @@ -551,7 +555,7 @@ class Diaspora Logger::notice('Message with type ' . $type . ' is not private, quitting.'); return false; } - return self::receiveParticipation($importer, $fields, $fetched); + return self::receiveParticipation($importer, $fields, $direction); case "photo": // Not implemented return self::receivePhoto($importer, $fields); @@ -567,13 +571,13 @@ class Diaspora return self::receiveProfile($importer, $fields); case "reshare": - return self::receiveReshare($importer, $fields, $msg["message"], $fetched); + return self::receiveReshare($importer, $fields, $msg["message"], $direction); case "retraction": return self::receiveRetraction($importer, $sender, $fields); case "status_message": - return self::receiveStatusMessage($importer, $fields, $msg["message"], $fetched); + return self::receiveStatusMessage($importer, $fields, $msg["message"], $direction); default: Logger::notice("Unknown message type ".$type); @@ -991,8 +995,8 @@ class Diaspora */ private static function fetchGuidSub($match, $item) { - if (!self::storeByGuid($match[1], $item["author-link"])) { - self::storeByGuid($match[1], $item["owner-link"]); + if (!self::storeByGuid($match[1], $item["author-link"], true)) { + self::storeByGuid($match[1], $item["owner-link"], true); } } @@ -1001,13 +1005,13 @@ class Diaspora * * @param string $guid the message guid * @param string $server The server address - * @param int $uid The user id of the user + * @param bool $force Forced fetch * * @return int the message id of the stored message or false * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function storeByGuid($guid, $server, $uid = 0) + private static function storeByGuid($guid, $server, $force) { $serverparts = parse_url($server); @@ -1028,7 +1032,7 @@ class Diaspora Logger::info("Successfully fetched item ".$guid." from ".$server); // Now call the dispatcher - return self::dispatchPublic($msg, true); + return self::dispatchPublic($msg, $force ? self::FORCED_FETCH : self::FETCHED); } /** @@ -1136,7 +1140,7 @@ class Diaspora } Logger::info('Fetch GUID from origin', ['guid' => $guid, 'server' => $matches[1]]); - $ret = self::storeByGuid($guid, $matches[1], $uid); + $ret = self::storeByGuid($guid, $matches[1], true); Logger::info('Result', ['ret' => $ret]); $item = Post::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]); @@ -1170,11 +1174,11 @@ class Diaspora if (!DBA::isResult($item)) { $person = FContact::getByURL($author); - $result = self::storeByGuid($guid, $person["url"], $uid); + $result = self::storeByGuid($guid, $person["url"], false); // We don't have an url for items that arrived at the public dispatcher if (!$result && !empty($contact["url"])) { - $result = self::storeByGuid($guid, $contact["url"], $uid); + $result = self::storeByGuid($guid, $contact["url"], false); } if ($result) { @@ -1441,17 +1445,17 @@ class Diaspora /** * Processes an incoming comment * - * @param array $importer Array of the importer user - * @param string $sender The sender of the message - * @param object $data The message object - * @param string $xml The original XML of the message - * @param bool $fetched The message had been fetched and not pushed + * @param array $importer Array of the importer user + * @param string $sender The sender of the message + * @param object $data The message object + * @param string $xml The original XML of the message + * @param int $direction Indicates if the message had been fetched or pushed * * @return int The message id of the generated comment or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveComment(array $importer, $sender, $data, $xml, bool $fetched) + private static function receiveComment(array $importer, $sender, $data, $xml, int $direction) { $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); @@ -1512,7 +1516,7 @@ class Diaspora $datarray["owner-id"] = Contact::getIdForURL($contact["url"], 0); // Will be overwritten for sharing accounts in Item::insert - if ($fetched) { + if (in_array($direction, [self::FETCHED, self::FORCED_FETCH])) { $datarray["post-reason"] = Item::PR_FETCHED; } elseif ($datarray["uid"] == 0) { $datarray["post-reason"] = Item::PR_GLOBAL; @@ -1534,7 +1538,7 @@ class Diaspora $datarray["protocol"] = Conversation::PARCEL_DIASPORA; $datarray["source"] = $xml; - $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; + $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; @@ -1698,15 +1702,16 @@ class Diaspora /** * Processes "like" messages * - * @param array $importer Array of the importer user - * @param string $sender The sender of the message - * @param object $data The message object + * @param array $importer Array of the importer user + * @param string $sender The sender of the message + * @param object $data The message object + * @param int $direction Indicates if the message had been fetched or pushed * * @return int The message id of the generated like or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveLike(array $importer, $sender, $data, bool $fetched) + private static function receiveLike(array $importer, $sender, $data, int $direction) { $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); @@ -1759,7 +1764,7 @@ class Diaspora $datarray = []; $datarray["protocol"] = Conversation::PARCEL_DIASPORA; - $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; + $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; $datarray["uid"] = $importer["uid"]; $datarray["contact-id"] = $author_contact["cid"]; @@ -1885,14 +1890,15 @@ class Diaspora /** * Processes participations - unsupported by now * - * @param array $importer Array of the importer user - * @param object $data The message object + * @param array $importer Array of the importer user + * @param object $data The message object + * @param int $direction Indicates if the message had been fetched or pushed * * @return bool success * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveParticipation(array $importer, $data, bool $fetched) + private static function receiveParticipation(array $importer, $data, int $direction) { $author = strtolower(XML::unescape($data->author)); $guid = XML::unescape($data->guid); @@ -1937,7 +1943,7 @@ class Diaspora $datarray = []; $datarray["protocol"] = Conversation::PARCEL_DIASPORA; - $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; + $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; $datarray["uid"] = $importer["uid"]; $datarray["contact-id"] = $author_contact["cid"]; @@ -2290,12 +2296,12 @@ class Diaspora $server = "https://".substr($orig_author, strpos($orig_author, "@") + 1); Logger::notice("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server); - $stored = self::storeByGuid($guid, $server); + $stored = self::storeByGuid($guid, $server, true); if (!$stored) { $server = "http://".substr($orig_author, strpos($orig_author, "@") + 1); Logger::notice("2nd try: reshared message ".$guid." will be fetched without SSL from the server ".$server); - $stored = self::storeByGuid($guid, $server); + $stored = self::storeByGuid($guid, $server, true); } if ($stored) { @@ -2376,15 +2382,16 @@ class Diaspora /** * Processes a reshare message * - * @param array $importer Array of the importer user - * @param object $data The message object - * @param string $xml The original XML of the message + * @param array $importer Array of the importer user + * @param object $data The message object + * @param string $xml The original XML of the message + * @param int $direction Indicates if the message had been fetched or pushed * * @return int the message id * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveReshare(array $importer, $data, $xml, bool $fetched) + private static function receiveReshare(array $importer, $data, $xml, int $direction) { $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); @@ -2438,7 +2445,7 @@ class Diaspora $datarray["protocol"] = Conversation::PARCEL_DIASPORA; $datarray["source"] = $xml; - $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; + $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; /// @todo Copy tag data from original post @@ -2613,9 +2620,11 @@ class Diaspora * @param integer $uriid * @param string $author * @param string $body + * @param int $direction Indicates if the message had been fetched or pushed + * * @return boolean Is the message wanted? */ - private static function isSolicitedMessage(string $url, int $uriid, string $author, string $body) + private static function isSolicitedMessage(string $url, int $uriid, string $author, string $body, int $direction) { $contact = Contact::getByURL($author); if (DBA::exists('contact', ["`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)", @@ -2624,6 +2633,11 @@ class Diaspora return true; } + if ($direction == self::FORCED_FETCH) { + Logger::debug('Post is a forced fetch - accepted', ['url' => $url, 'author' => $author]); + return true; + } + $tags = array_column(Tag::getByURIId($uriid, [Tag::HASHTAG]), 'name'); return Relay::isSolicitedPost($tags, $body, $contact['id'], $url, Protocol::DIASPORA); } @@ -2651,15 +2665,16 @@ class Diaspora /** * Receives status messages * - * @param array $importer Array of the importer user - * @param SimpleXMLElement $data The message object - * @param string $xml The original XML of the message - * @param bool $fetched The message had been fetched and not pushed + * @param array $importer Array of the importer user + * @param SimpleXMLElement $data The message object + * @param string $xml The original XML of the message + * @param int $direction Indicates if the message had been fetched or pushed + * * @return int The message id of the newly created item * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml, bool $fetched) + private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml, int $direction) { $author = XML::unescape($data->author); $guid = XML::unescape($data->guid); @@ -2737,9 +2752,9 @@ class Diaspora $datarray["protocol"] = Conversation::PARCEL_DIASPORA; $datarray["source"] = $xml; - $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; + $datarray["direction"] = in_array($direction, [self::FETCHED, self::FORCED_FETCH]) ? Conversation::PULL : Conversation::PUSH; - if ($fetched) { + if (in_array($direction, [self::FETCHED, self::FORCED_FETCH])) { $datarray["post-reason"] = Item::PR_FETCHED; } elseif ($datarray["uid"] == 0) { $datarray["post-reason"] = Item::PR_GLOBAL; @@ -2751,7 +2766,7 @@ class Diaspora self::storeMentions($datarray['uri-id'], $text); Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray["body"]); - if (!$fetched && !self::isSolicitedMessage($datarray["uri"], $datarray['uri-id'], $author, $body)) { + if (!self::isSolicitedMessage($datarray["uri"], $datarray['uri-id'], $author, $body, $direction)) { DBA::delete('item-uri', ['uri' => $datarray['uri']]); return false; } From c1bb1cf0fc987d49108ad2ea121bb21c7a784cd4 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 12 Mar 2022 07:34:30 +0000 Subject: [PATCH 2/6] Improved logging --- src/Protocol/ActivityPub/Processor.php | 13 ++++++++---- src/Protocol/DFRN.php | 28 +++++++++++++++++++------- src/Protocol/Diaspora.php | 9 +++++++-- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 2e2d18b39..3778a0aa8 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -192,8 +192,8 @@ class Processor /** * Update an existing event * - * @param int $event_id - * @param array $activity + * @param int $event_id + * @param array $activity */ private static function updateEvent(int $event_id, array $activity) { @@ -593,7 +593,7 @@ class Processor Logger::debug('Message is private - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri']]); return true; } - + if (!empty($activity['from-relay'])) { // We check relay posts at another place. When it arrived here, the message is already checked. Logger::debug('Message is a relay post that is already checked - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri']]); @@ -616,7 +616,12 @@ class Processor } $tags = array_column(Tag::getByURIId($item['uri-id'], [Tag::HASHTAG]), 'name'); - return Relay::isSolicitedPost($tags, $item['body'], $item['author-id'], $item['uri'], Protocol::ACTIVITYPUB); + if (Relay::isSolicitedPost($tags, $item['body'], $item['author-id'], $item['uri'], Protocol::ACTIVITYPUB)) { + Logger::debug('Post is accepted because of the relay settings', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri']]); + return true; + } else { + return false; + } } /** diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index a20d54fb6..db7eadac9 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1769,9 +1769,10 @@ class DFRN * Checks if an incoming message is wanted * * @param array $item + * @param array $imporer * @return boolean Is the message wanted? */ - private static function isSolicitedMessage(array $item) + private static function isSolicitedMessage(array $item, array $importer) { if (DBA::exists('contact', ["`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)", Strings::normaliseLink($item["author-link"]), 0, Contact::FRIEND, Contact::SHARING])) { @@ -1779,8 +1780,23 @@ class DFRN return true; } + if ($importer['importer_uid'] != 0) { + Logger::debug('Message is directed to a user - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'importer' => $importer['importer_uid']]); + return true; + } + + if ($item['uri'] != $item['thr-parent']) { + Logger::debug('Message is no parent - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri']]); + return true; + } + $tags = array_column(Tag::getByURIId($item['uri-id'], [Tag::HASHTAG]), 'name'); - return Relay::isSolicitedPost($tags, $item['body'], $item['author-id'], $item['uri'], Protocol::DFRN); + if (Relay::isSolicitedPost($tags, $item['body'], $item['author-id'], $item['uri'], Protocol::DFRN)) { + Logger::debug('Post is accepted because of the relay settings', ['uri' => $item['uri'], 'author' => $item["author-link"]]); + return true; + } else { + return false; + } } /** @@ -1981,11 +1997,9 @@ class DFRN } // Check if the message is wanted - if (($importer['importer_uid'] == 0) && ($item['uri'] == $item['thr-parent'])) { - if (!self::isSolicitedMessage($item)) { - DBA::delete('item-uri', ['uri' => $item['uri']]); - return 403; - } + if (!self::isSolicitedMessage($item, $importer)) { + DBA::delete('item-uri', ['uri' => $item['uri']]); + return 403; } // Get the type of the item (Top level post, reply or remote reply) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 7b2b03f55..7ca01f996 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -2639,7 +2639,12 @@ class Diaspora } $tags = array_column(Tag::getByURIId($uriid, [Tag::HASHTAG]), 'name'); - return Relay::isSolicitedPost($tags, $body, $contact['id'], $url, Protocol::DIASPORA); + if (Relay::isSolicitedPost($tags, $body, $contact['id'], $url, Protocol::DIASPORA)) { + Logger::debug('Post is accepted because of the relay settings', ['url' => $url, 'author' => $author]); + return true; + } else { + return false; + } } /** @@ -2669,7 +2674,7 @@ class Diaspora * @param SimpleXMLElement $data The message object * @param string $xml The original XML of the message * @param int $direction Indicates if the message had been fetched or pushed - * + * * @return int The message id of the newly created item * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException From 56cd98b38bace314c1b38661edf8b26d1345a2d1 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 12 Mar 2022 07:48:31 +0000 Subject: [PATCH 3/6] Further improved logging --- src/Protocol/DFRN.php | 4 ++-- src/Protocol/Diaspora.php | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index db7eadac9..0fb739457 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1776,7 +1776,7 @@ class DFRN { if (DBA::exists('contact', ["`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)", Strings::normaliseLink($item["author-link"]), 0, Contact::FRIEND, Contact::SHARING])) { - Logger::debug('Author has got followers - accepted', ['uri' => $item['uri'], 'author' => $item["author-link"]]); + Logger::debug('Author has got followers - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'author' => $item["author-link"]]); return true; } @@ -1792,7 +1792,7 @@ class DFRN $tags = array_column(Tag::getByURIId($item['uri-id'], [Tag::HASHTAG]), 'name'); if (Relay::isSolicitedPost($tags, $item['body'], $item['author-id'], $item['uri'], Protocol::DFRN)) { - Logger::debug('Post is accepted because of the relay settings', ['uri' => $item['uri'], 'author' => $item["author-link"]]); + Logger::debug('Post is accepted because of the relay settings', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'author' => $item["author-link"]]); return true; } else { return false; diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 7ca01f996..ad4ed65f6 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -2616,31 +2616,30 @@ class Diaspora /** * Checks if an incoming message is wanted * - * @param string $url - * @param integer $uriid + * @param array $item * @param string $author * @param string $body * @param int $direction Indicates if the message had been fetched or pushed * * @return boolean Is the message wanted? */ - private static function isSolicitedMessage(string $url, int $uriid, string $author, string $body, int $direction) + private static function isSolicitedMessage(array $item, string $author, string $body, int $direction) { $contact = Contact::getByURL($author); if (DBA::exists('contact', ["`nurl` = ? AND `uid` != ? AND `rel` IN (?, ?)", $contact['nurl'], 0, Contact::FRIEND, Contact::SHARING])) { - Logger::debug('Author has got followers - accepted', ['url' => $url, 'author' => $author]); + Logger::debug('Author has got followers - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'author' => $author]); return true; } if ($direction == self::FORCED_FETCH) { - Logger::debug('Post is a forced fetch - accepted', ['url' => $url, 'author' => $author]); + Logger::debug('Post is a forced fetch - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'author' => $author]); return true; } - $tags = array_column(Tag::getByURIId($uriid, [Tag::HASHTAG]), 'name'); - if (Relay::isSolicitedPost($tags, $body, $contact['id'], $url, Protocol::DIASPORA)) { - Logger::debug('Post is accepted because of the relay settings', ['url' => $url, 'author' => $author]); + $tags = array_column(Tag::getByURIId($item['uri-id'], [Tag::HASHTAG]), 'name'); + if (Relay::isSolicitedPost($tags, $body, $contact['id'], $item['uri'], Protocol::DIASPORA)) { + Logger::debug('Post is accepted because of the relay settings', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'author' => $author]); return true; } else { return false; @@ -2771,7 +2770,7 @@ class Diaspora self::storeMentions($datarray['uri-id'], $text); Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray["body"]); - if (!self::isSolicitedMessage($datarray["uri"], $datarray['uri-id'], $author, $body, $direction)) { + if (!self::isSolicitedMessage($datarray, $author, $body, $direction)) { DBA::delete('item-uri', ['uri' => $datarray['uri']]); return false; } From 8c778ca02e4daa3936842f0e9eccc055fec80221 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 12 Mar 2022 11:17:33 +0000 Subject: [PATCH 4/6] Improved completion check for AP --- src/Module/Debug/ActivityPubConversion.php | 4 ++++ src/Protocol/ActivityPub/Processor.php | 15 ++++++++------- src/Protocol/ActivityPub/Receiver.php | 14 +++++++++++++- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/Module/Debug/ActivityPubConversion.php b/src/Module/Debug/ActivityPubConversion.php index 5de4b93b7..ec7fee3f4 100644 --- a/src/Module/Debug/ActivityPubConversion.php +++ b/src/Module/Debug/ActivityPubConversion.php @@ -114,6 +114,10 @@ class ActivityPubConversion extends BaseModule $object_data['thread-completion'] = $activity['thread-completion']; } + if (!empty($activity['completion-mode'])) { + $object_data['completion-mode'] = $activity['completion-mode']; + } + $results[] = [ 'title' => DI::l10n()->t('Object data'), 'content' => visible_whitespace(var_export($object_data, true)) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 3778a0aa8..ae9dd4c79 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -235,7 +235,7 @@ class Processor if (empty($activity['directmessage']) && ($activity['id'] != $activity['reply-to-id']) && !Post::exists(['uri' => $activity['reply-to-id']])) { Logger::notice('Parent not found. Try to refetch it.', ['parent' => $activity['reply-to-id']]); - self::fetchMissingActivity($activity['reply-to-id'], $activity); + self::fetchMissingActivity($activity['reply-to-id'], $activity, '', Receiver::COMPLETION_AUTO); } $item['diaspora_signed_text'] = $activity['diaspora:comment'] ?? ''; @@ -600,11 +600,9 @@ class Processor return true; } - if (!empty($activity['thread-completion'])) { - // The thread completion mode means that the post is fetched intentionally. - // This can have several causes, in doubt we keep the message. - // This can possibly be improved in the future. - Logger::debug('Message is in completion mode - accepted', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri']]); + if (in_array($activity['completion-mode'] ?? Receiver::COMPLETION_NONE, [Receiver::COMPLETION_MANUAL, Receiver::COMPLETION_ANNOUCE])) { + // Manual completions and completions caused by reshares are allowed without any further checks. + Logger::debug('Message is in completion mode - accepted', ['mode' => $activity['completion-mode'], 'uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri']]); return true; } @@ -903,7 +901,7 @@ class Processor * @return string fetched message URL * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function fetchMissingActivity(string $url, array $child = [], string $relay_actor = '') + public static function fetchMissingActivity(string $url, array $child = [], string $relay_actor = '', int $completion = Receiver::COMPLETION_MANUAL) { if (!empty($child['receiver'])) { $uid = ActivityPub\Receiver::getFirstUserFromReceivers($child['receiver']); @@ -967,10 +965,13 @@ class Processor if (!empty($relay_actor)) { $ldactivity['thread-completion'] = $ldactivity['from-relay'] = Contact::getIdForURL($relay_actor); + $ldactivity['completion-mode'] = Receiver::COMPLETION_RELAY; } elseif (!empty($child['thread-completion'])) { $ldactivity['thread-completion'] = $child['thread-completion']; + $ldactivity['completion-mode'] = $child['completion-mode'] ?? Receiver::COMPLETION_NONE; } else { $ldactivity['thread-completion'] = Contact::getIdForURL($actor); + $ldactivity['completion-mode'] = $completion; } if (!empty($child['type'])) { diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index 32994a9d5..98d40137a 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -68,6 +68,12 @@ class Receiver const TARGET_ANSWER = 6; const TARGET_GLOBAL = 7; + const COMPLETION_NONE = 0; + const COMPLETION_ANNOUCE = 1; + const COMPLETION_RELAY = 2; + const COMPLETION_MANUAL = 3; + const COMPLETION_AUTO = 4; + /** * Checks incoming message from the inbox * @@ -190,7 +196,7 @@ class Receiver return; } - $id = Processor::fetchMissingActivity($object_id, [], $actor); + $id = Processor::fetchMissingActivity($object_id, [], $actor, self::COMPLETION_RELAY); if (empty($id)) { Logger::notice('Relayed message had not been fetched', ['id' => $object_id]); return; @@ -529,6 +535,11 @@ 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']; + } + if (!empty($activity['thread-children-type'])) { $object_data['thread-children-type'] = $activity['thread-children-type']; } @@ -555,6 +566,7 @@ class Receiver case 'as:Announce': if (in_array($object_data['object_type'], self::CONTENT_TYPES)) { $object_data['thread-completion'] = Contact::getIdForURL($actor); + $object_data['completion-mode'] = self::COMPLETION_ANNOUCE; $item = ActivityPub\Processor::createItem($object_data); if (empty($item)) { From fb13890341bb9af2d695e10292edbc401561fee3 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 12 Mar 2022 15:27:56 +0000 Subject: [PATCH 5/6] Added parameter values --- src/Protocol/Diaspora.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index ad4ed65f6..9f7781d13 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -454,7 +454,7 @@ class Diaspora * Dispatches public messages and find the fitting receivers * * @param array $msg The post that will be dispatched - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return int The message id of the generated message, "true" or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException @@ -485,7 +485,7 @@ class Diaspora * @param array $importer Array of the importer user * @param array $msg The post that will be dispatched * @param SimpleXMLElement $fields SimpleXML object that contains the message - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return int The message id of the generated message, "true" or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException @@ -1449,7 +1449,7 @@ class Diaspora * @param string $sender The sender of the message * @param object $data The message object * @param string $xml The original XML of the message - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return int The message id of the generated comment or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException @@ -1705,7 +1705,7 @@ class Diaspora * @param array $importer Array of the importer user * @param string $sender The sender of the message * @param object $data The message object - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return int The message id of the generated like or "false" if there was an error * @throws \Friendica\Network\HTTPException\InternalServerErrorException @@ -1892,7 +1892,7 @@ class Diaspora * * @param array $importer Array of the importer user * @param object $data The message object - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return bool success * @throws \Friendica\Network\HTTPException\InternalServerErrorException @@ -2385,7 +2385,7 @@ class Diaspora * @param array $importer Array of the importer user * @param object $data The message object * @param string $xml The original XML of the message - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return int the message id * @throws \Friendica\Network\HTTPException\InternalServerErrorException @@ -2619,7 +2619,7 @@ class Diaspora * @param array $item * @param string $author * @param string $body - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return boolean Is the message wanted? */ @@ -2672,7 +2672,7 @@ class Diaspora * @param array $importer Array of the importer user * @param SimpleXMLElement $data The message object * @param string $xml The original XML of the message - * @param int $direction Indicates if the message had been fetched or pushed + * @param int $direction Indicates if the message had been fetched or pushed (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @return int The message id of the newly created item * @throws \Friendica\Network\HTTPException\InternalServerErrorException From 314bf92eadca7edef72cdc94669c5f961a802666 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 12 Mar 2022 17:29:46 +0000 Subject: [PATCH 6/6] Added Documentation --- src/Protocol/ActivityPub/Processor.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index ae9dd4c79..9aeb301cf 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -898,6 +898,7 @@ class Processor * @param string $url message URL * @param array $child activity array with the child of this message * @param string $relay_actor Relay actor + * @param int $completion Completion mode, see Receiver::COMPLETION_* * @return string fetched message URL * @throws \Friendica\Network\HTTPException\InternalServerErrorException */