X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FDiaspora.php;h=70fd0f1f8d9acb06f8d66d6bb21f922c7fa7a140;hb=47a3d8e6ce8461a457dee46d43d5ad14166f8013;hp=ea0b2b6749ab9a6b83c2749a5ad26e0c6335c156;hpb=7dadc7f6dc0b1e68bfa5937b3a3fa3fd9cdcacd1;p=friendica.git diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index ea0b2b6749..70fd0f1f8d 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -41,6 +41,7 @@ use Friendica\Model\Mail; use Friendica\Model\Post; use Friendica\Model\Tag; use Friendica\Model\User; +use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\Probe; use Friendica\Util\Crypto; use Friendica\Util\DateTimeFormat; @@ -56,6 +57,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 +454,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 (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 * @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 +475,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 +483,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 (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 * @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 +525,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 +542,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 +556,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 +572,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); @@ -837,8 +842,7 @@ class Diaspora // It is deactivated by now, due to side effects. See issue https://github.com/friendica/friendica/pull/4033 // It is not removed by now. Possibly the code is needed? //if (!$is_comment && $contact["rel"] == Contact::FOLLOWER && in_array($importer["page-flags"], array(User::PAGE_FLAGS_FREELOVE))) { - // DBA::update( - // 'contact', + // Contact::update( // array('rel' => Contact::FRIEND, 'writable' => true), // array('id' => $contact["id"], 'uid' => $contact["uid"]) // ); @@ -992,8 +996,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); } } @@ -1002,13 +1006,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); @@ -1029,7 +1033,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); } /** @@ -1056,7 +1060,7 @@ class Diaspora Logger::info("Fetch post from ".$source_url); - $envelope = DI::httpClient()->fetch($source_url); + $envelope = DI::httpClient()->fetch($source_url, HttpClientAccept::MAGIC); if ($envelope) { Logger::info("Envelope was fetched."); $x = self::verifyMagicEnvelope($envelope); @@ -1137,7 +1141,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]); @@ -1171,11 +1175,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) { @@ -1442,17 +1446,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 (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 * @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); @@ -1513,7 +1517,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; @@ -1535,7 +1539,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; @@ -1699,15 +1703,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 (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 * @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); @@ -1760,7 +1765,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"]; @@ -1886,14 +1891,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 (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @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); @@ -1938,7 +1944,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"]; @@ -2123,8 +2129,7 @@ class Diaspora private static function receiveRequestMakeFriend(array $importer, array $contact) { if ($contact["rel"] == Contact::SHARING) { - DBA::update( - 'contact', + Contact::update( ['rel' => Contact::FRIEND, 'writable' => true], ['id' => $contact["id"], 'uid' => $importer["uid"]] ); @@ -2292,12 +2297,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) { @@ -2378,15 +2383,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 (self::PUSHED, self::FETCHED, self::FORCED_FETCH) * * @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); @@ -2440,7 +2446,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 @@ -2611,24 +2617,34 @@ 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 (self::PUSHED, self::FETCHED, self::FORCED_FETCH) + * * @return boolean Is the message wanted? */ - private static function isSolicitedMessage(string $url, int $uriid, string $author, string $body) + 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::info('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', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'url' => $item['uri'], 'author' => $author]); return true; } - $taglist = Tag::getByURIId($uriid, [Tag::HASHTAG]); - $tags = array_column($taglist, 'name'); - return Relay::isSolicitedPost($tags, $body, $contact['id'], $url, Protocol::DIASPORA); + $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; + } } /** @@ -2654,15 +2670,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 (self::PUSHED, self::FETCHED, self::FORCED_FETCH) + * * @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); @@ -2740,9 +2757,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; @@ -2754,7 +2771,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, $author, $body, $direction)) { DBA::delete('item-uri', ['uri' => $datarray['uri']]); return false; } @@ -4084,10 +4101,10 @@ class Diaspora 'author-id' => $author, 'owner-id' => $author, 'body' => $post, - 'allow_cid' => $owner['allow_cid'], - 'allow_gid' => $owner['allow_gid'], - 'deny_cid' => $owner['deny_cid'], - 'deny_gid' => $owner['deny_gid'], + 'allow_cid' => $owner['allow_cid'] ?? '', + 'allow_gid' => $owner['allow_gid']?? '', + 'deny_cid' => $owner['deny_cid'] ?? '', + 'deny_gid' => $owner['deny_gid'] ?? '', ]; if (!empty($item['allow_cid'] . $item['allow_gid'] . $item['deny_cid'] . $item['deny_gid'])) {