X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FDiaspora.php;h=00da7d3915d2dd68d0f7c6013af0472c5f4b3c8e;hb=e7884b14092b5f5f2c5656d622a625006bffb165;hp=35b07c9a0505ccc16bdffb9c61ac0892f179cea2;hpb=e4228c6218db70d600641430f4895f76cc049c5b;p=friendica.git diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 35b07c9a05..00da7d3915 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -1,6 +1,6 @@ $item['parent'], 'gravity' => [GRAVITY_COMMENT, GRAVITY_ACTIVITY]]); - while ($item = DBA::fetch($items)) { + while ($item = Post::fetch($items)) { $contact = DBA::selectFirst('contact', ['id', 'url', 'name', 'protocol', 'batch', 'network'], ['id' => $item['author-id']]); if (!DBA::isResult($contact) || empty($contact['batch']) || @@ -537,7 +537,7 @@ class Diaspora return self::receiveConversation($importer, $msg, $fields); case "like": - return self::receiveLike($importer, $sender, $fields); + return self::receiveLike($importer, $sender, $fields, $fetched); case "message": if (!$private) { @@ -551,7 +551,7 @@ class Diaspora Logger::log('Message with type ' . $type . ' is not private, quitting.'); return false; } - return self::receiveParticipation($importer, $fields); + return self::receiveParticipation($importer, $fields, $fetched); case "photo": // Not implemented return self::receivePhoto($importer, $fields); @@ -567,7 +567,7 @@ class Diaspora return self::receiveProfile($importer, $fields); case "reshare": - return self::receiveReshare($importer, $fields, $msg["message"]); + return self::receiveReshare($importer, $fields, $msg["message"], $fetched); case "retraction": return self::receiveRetraction($importer, $sender, $fields); @@ -931,7 +931,7 @@ class Diaspora */ private static function messageExists($uid, $guid) { - $item = Item::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]); + $item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]); if (DBA::isResult($item)) { Logger::log("message ".$guid." already exists for user ".$uid); return $item["id"]; @@ -1066,7 +1066,7 @@ class Diaspora * 'key' => The public key of the author * @throws \Exception */ - private static function message($guid, $server, $level = 0) + public static function message($guid, $server, $level = 0) { if ($level > 5) { return false; @@ -1151,7 +1151,7 @@ class Diaspora $guid = urldecode($matches[2]); - $item = Item::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]); + $item = Post::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]); if (DBA::isResult($item)) { Logger::info('Found', ['id' => $item['id']]); return $item['id']; @@ -1161,7 +1161,7 @@ class Diaspora $ret = self::storeByGuid($guid, $matches[1], $uid); Logger::info('Result', ['ret' => $ret]); - $item = Item::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]); + $item = Post::selectFirst(['id'], ['guid' => $guid, 'uid' => $uid]); if (DBA::isResult($item)) { Logger::info('Found', ['id' => $item['id']]); return $item['id']; @@ -1188,7 +1188,7 @@ class Diaspora 'author-name', 'author-link', 'author-avatar', 'gravity', 'owner-name', 'owner-link', 'owner-avatar']; $condition = ['uid' => $uid, 'guid' => $guid]; - $item = Item::selectFirst($fields, $condition); + $item = Post::selectFirst($fields, $condition); if (!DBA::isResult($item)) { $person = FContact::getByURL($author); @@ -1202,7 +1202,7 @@ class Diaspora if ($result) { Logger::log("Fetched missing item ".$guid." - result: ".$result, Logger::DEBUG); - $item = Item::selectFirst($fields, $condition); + $item = Post::selectFirst($fields, $condition); } } @@ -1265,7 +1265,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function plink($addr, $guid, $parent_guid = '') + private static function plink(string $addr, string $guid, string $parent_guid = '') { $contact = Contact::getByURL($addr); if (empty($contact)) { @@ -1410,7 +1410,7 @@ class Diaspora */ private static function getUriFromGuid($author, $guid, $onlyfound = false) { - $item = Item::selectFirst(['uri'], ['guid' => $guid]); + $item = Post::selectFirst(['uri'], ['guid' => $guid]); if (DBA::isResult($item)) { return $item["uri"]; } elseif (!$onlyfound) { @@ -1426,25 +1426,6 @@ class Diaspora return ""; } - /** - * Fetch the guid from our database with a given uri - * - * @param string $uri Message uri - * @param string $uid Author handle - * - * @return string The post guid - * @throws \Exception - */ - private static function getGuidFromUri($uri, $uid) - { - $item = Item::selectFirst(['guid'], ['uri' => $uri, 'uid' => $uid]); - if (DBA::isResult($item)) { - return $item["guid"]; - } else { - return false; - } - } - /** * Store the mentions in the tag table * @@ -1517,6 +1498,10 @@ class Diaspora return false; } + if (!empty($contact['gsid'])) { + GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); + } + $message_id = self::messageExists($importer["uid"], $guid); if ($message_id) { return true; @@ -1550,11 +1535,11 @@ class Diaspora // Will be overwritten for sharing accounts in Item::insert if ($fetched) { - $datarray["post-type"] = Item::PT_FETCHED; + $datarray["post-reason"] = Item::PR_FETCHED; } elseif ($datarray["uid"] == 0) { - $datarray["post-type"] = Item::PT_GLOBAL; + $datarray["post-reason"] = Item::PR_GLOBAL; } else { - $datarray["post-type"] = Item::PT_COMMENT; + $datarray["post-reason"] = Item::PR_COMMENT; } $datarray["guid"] = $guid; @@ -1567,9 +1552,11 @@ class Diaspora $datarray['thr-parent'] = $thr_parent ?: $toplevel_parent_item['uri']; $datarray["object-type"] = Activity\ObjectType::COMMENT; + $datarray["post-type"] = Item::PT_NOTE; $datarray["protocol"] = Conversation::PARCEL_DIASPORA; $datarray["source"] = $xml; + $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; @@ -1700,6 +1687,10 @@ class Diaspora return false; } + if (!empty($contact['gsid'])) { + GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); + } + $conversation = DBA::selectFirst('conv', [], ['uid' => $importer["uid"], 'guid' => $guid]); if (!DBA::isResult($conversation)) { $r = q( @@ -1740,7 +1731,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveLike(array $importer, $sender, $data) + private static function receiveLike(array $importer, $sender, $data, bool $fetched) { $author = Strings::escapeTags(XML::unescape($data->author)); $guid = Strings::escapeTags(XML::unescape($data->guid)); @@ -1759,6 +1750,10 @@ class Diaspora return false; } + if (!empty($contact['gsid'])) { + GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); + } + $message_id = self::messageExists($importer["uid"], $guid); if ($message_id) { return true; @@ -1789,6 +1784,7 @@ class Diaspora $datarray = []; $datarray["protocol"] = Conversation::PARCEL_DIASPORA; + $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; $datarray["uid"] = $importer["uid"]; $datarray["contact-id"] = $author_contact["cid"]; @@ -1813,7 +1809,7 @@ class Diaspora // like on comments have the comment as parent. So we need to fetch the toplevel parent if ($toplevel_parent_item['gravity'] != GRAVITY_PARENT) { - $toplevel = Item::selectFirst(['origin'], ['id' => $toplevel_parent_item['parent']]); + $toplevel = Post::selectFirst(['origin'], ['id' => $toplevel_parent_item['parent']]); $origin = $toplevel["origin"]; } else { $origin = $toplevel_parent_item["origin"]; @@ -1868,6 +1864,10 @@ class Diaspora return false; } + if (!empty($contact['gsid'])) { + GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); + } + $conversation = null; $condition = ['uid' => $importer["uid"], 'guid' => $conversation_guid]; @@ -1917,7 +1917,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveParticipation(array $importer, $data) + private static function receiveParticipation(array $importer, $data, bool $fetched) { $author = strtolower(Strings::escapeTags(XML::unescape($data->author))); $guid = Strings::escapeTags(XML::unescape($data->guid)); @@ -1928,6 +1928,10 @@ class Diaspora return false; } + if (!empty($contact['gsid'])) { + GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); + } + if (self::messageExists($importer["uid"], $guid)) { return true; } @@ -1958,6 +1962,7 @@ class Diaspora $datarray = []; $datarray["protocol"] = Conversation::PARCEL_DIASPORA; + $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; $datarray["uid"] = $importer["uid"]; $datarray["contact-id"] = $author_contact["cid"]; @@ -1990,9 +1995,9 @@ class Diaspora Logger::info('Participation stored', ['id' => $message_id, 'guid' => $guid, 'parent_guid' => $parent_guid, 'author' => $author]); // Send all existing comments and likes to the requesting server - $comments = Item::select(['id', 'uri-id', 'parent-author-network', 'author-network', 'verb'], + $comments = Post::select(['id', 'uri-id', 'parent-author-network', 'author-network', 'verb'], ['parent' => $toplevel_parent_item['id'], 'gravity' => [GRAVITY_COMMENT, GRAVITY_ACTIVITY]]); - while ($comment = Item::fetch($comments)) { + while ($comment = Post::fetch($comments)) { if (in_array($comment['verb'], [Activity::FOLLOW, Activity::TAG])) { Logger::info('participation messages are not relayed', ['item' => $comment['id']]); continue; @@ -2282,7 +2287,7 @@ class Diaspora $fields = ['body', 'title', 'app', 'created', 'object-type', 'uri', 'guid', 'author-name', 'author-link', 'author-avatar', 'plink', 'uri-id']; $condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => [Item::PUBLIC, Item::UNLISTED]]; - $item = Item::selectFirst($fields, $condition); + $item = Post::selectFirst($fields, $condition); if (DBA::isResult($item)) { Logger::log("reshared message ".$guid." already exists on system."); @@ -2297,9 +2302,6 @@ class Diaspora $item["body"] = self::replacePeopleGuid($item["body"], $item["author-link"]); - // Add OEmbed and other information to the body - $item["body"] = PageInfo::searchAndAppendToBody($item["body"], false, true); - return $item; } else { return $item; @@ -2326,7 +2328,7 @@ class Diaspora $fields = ['body', 'title', 'app', 'created', 'object-type', 'uri', 'guid', 'author-name', 'author-link', 'author-avatar', 'plink', 'uri-id']; $condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => [Item::PUBLIC, Item::UNLISTED]]; - $item = Item::selectFirst($fields, $condition); + $item = Post::selectFirst($fields, $condition); if (DBA::isResult($item)) { // If it is a reshared post from another network then reformat to avoid display problems with two share elements @@ -2352,7 +2354,7 @@ class Diaspora */ private static function addReshareActivity($item, $parent_message_id, $guid, $author) { - $parent = Item::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]); + $parent = Post::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]); $datarray = []; @@ -2375,6 +2377,8 @@ class Diaspora $datarray['object-type'] = Activity\ObjectType::NOTE; $datarray['protocol'] = $item['protocol']; + $datarray['source'] = $item['source']; + $datarray['direction'] = $item['direction']; $datarray['plink'] = self::plink($author, $datarray['guid']); $datarray['private'] = $item['private']; @@ -2406,7 +2410,7 @@ class Diaspora * @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws \ImagickException */ - private static function receiveReshare(array $importer, $data, $xml) + private static function receiveReshare(array $importer, $data, $xml, bool $fetched) { $author = Strings::escapeTags(XML::unescape($data->author)); $guid = Strings::escapeTags(XML::unescape($data->guid)); @@ -2421,6 +2425,10 @@ class Diaspora return false; } + if (!empty($contact['gsid'])) { + GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); + } + $message_id = self::messageExists($importer["uid"], $guid); if ($message_id) { return true; @@ -2431,6 +2439,10 @@ class Diaspora return false; } + if (empty($original_item['plink'])) { + $original_item['plink'] = self::plink($root_author, $root_guid); + } + $datarray = []; $datarray["uid"] = $importer["uid"]; @@ -2452,6 +2464,7 @@ class Diaspora $datarray["protocol"] = Conversation::PARCEL_DIASPORA; $datarray["source"] = $xml; + $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; /// @todo Copy tag data from original post @@ -2472,7 +2485,6 @@ class Diaspora Tag::storeFromBody($datarray['uri-id'], $datarray["body"]); - Post\Media::copy($original_item['uri-id'], $datarray['uri-id']); $datarray["app"] = $original_item["app"]; $datarray["plink"] = self::plink($author, $guid); @@ -2535,7 +2547,7 @@ class Diaspora } // Fetch items that are about to be deleted - $fields = ['uid', 'id', 'parent', 'author-link', 'file']; + $fields = ['uid', 'id', 'parent', 'author-link', 'uri-id']; // When we receive a public retraction, we delete every item that we find. if ($importer['uid'] == 0) { @@ -2544,20 +2556,20 @@ class Diaspora $condition = ['guid' => $target_guid, 'deleted' => false, 'uid' => $importer['uid']]; } - $r = Item::select($fields, $condition); + $r = Post::select($fields, $condition); if (!DBA::isResult($r)) { Logger::log("Target guid ".$target_guid." was not found on this system for user ".$importer['uid']."."); return false; } - while ($item = Item::fetch($r)) { - if (strstr($item['file'], '[')) { + while ($item = Post::fetch($r)) { + if (DBA::exists('post-category', ['uri-id' => $item['uri-id'], 'uid' => $item['uid'], 'type' => Post\Category::FILE])) { Logger::log("Target guid " . $target_guid . " for user " . $item['uid'] . " is filed. So it won't be deleted.", Logger::DEBUG); continue; } // Fetch the parent item - $parent = Item::selectFirst(['author-link'], ['id' => $item['parent']]); + $parent = Post::selectFirst(['author-link'], ['id' => $item['parent']]); // Only delete it if the parent author really fits if (!Strings::compareLink($parent["author-link"], $contact["url"]) && !Strings::compareLink($item["author-link"], $contact["url"])) { @@ -2569,6 +2581,7 @@ class Diaspora Logger::log("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item['parent'], Logger::DEBUG); } + DBA::close($r); return true; } @@ -2687,6 +2700,10 @@ class Diaspora return false; } + if (!empty($contact['gsid'])) { + GServer::setProtocol($contact['gsid'], Post\DeliveryData::DIASPORA); + } + $message_id = self::messageExists($importer["uid"], $guid); if ($message_id) { return true; @@ -2711,18 +2728,13 @@ class Diaspora if ($data->photo) { foreach ($data->photo as $photo) { self::storePhotoAsMedia($datarray['uri-id'], $photo); - $body = "[img]".XML::unescape($photo->remote_photo_path). - XML::unescape($photo->remote_photo_name)."[/img]\n".$body; } $datarray["object-type"] = Activity\ObjectType::IMAGE; + $datarray["post-type"] = Item::PT_IMAGE; } else { $datarray["object-type"] = Activity\ObjectType::NOTE; - - // Add OEmbed and other information to the body - if (!self::isHubzilla($contact["url"])) { - $body = PageInfo::searchAndAppendToBody($body, false, true); - } + $datarray["post-type"] = Item::PT_NOTE; } /// @todo enable support for polls @@ -2749,11 +2761,12 @@ class Diaspora $datarray["protocol"] = Conversation::PARCEL_DIASPORA; $datarray["source"] = $xml; + $datarray["direction"] = $fetched ? Conversation::PULL : Conversation::PUSH; if ($fetched) { - $datarray["post-type"] = Item::PT_FETCHED; + $datarray["post-reason"] = Item::PR_FETCHED; } elseif ($datarray["uid"] == 0) { - $datarray["post-type"] = Item::PT_GLOBAL; + $datarray["post-reason"] = Item::PR_GLOBAL; } $datarray["body"] = self::replacePeopleGuid($body, $contact["url"]); @@ -2857,9 +2870,9 @@ class Diaspora return false; } - $aes_key = openssl_random_pseudo_bytes(32); + $aes_key = random_bytes(32); $b_aes_key = base64_encode($aes_key); - $iv = openssl_random_pseudo_bytes(16); + $iv = random_bytes(16); $b_iv = base64_encode($iv); $ciphertext = self::aesEncrypt($aes_key, $iv, $msg); @@ -3106,17 +3119,7 @@ class Diaspora return; } - // Fetch some user id to have a valid handle to transmit the participation. - // In fact it doesn't matter which user sends this - but it is needed by the protocol. - // If the item belongs to a user, we take this user id. - if ($item['uid'] == 0) { - $condition = ['verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false]; - $first_user = DBA::selectFirst('user', ['uid'], $condition); - $owner = User::getOwnerDataById($first_user['uid']); - } else { - $owner = User::getOwnerDataById($item['uid']); - } - + $owner = User::getOwnerDataById($item['uid']); $author = self::myHandle($owner); $message = ["author" => $author, @@ -3252,7 +3255,7 @@ class Diaspora if (!empty($reshared['guid']) && $complete) { $condition = ['guid' => $reshared['guid'], 'network' => [Protocol::DFRN, Protocol::DIASPORA]]; - $item = Item::selectFirst(['contact-id'], $condition); + $item = Post::selectFirst(['contact-id'], $condition); if (DBA::isResult($item)) { $ret = []; $ret["root_handle"] = self::handleFromContact($item["contact-id"]); @@ -3403,7 +3406,7 @@ class Diaspora $type = "reshare"; } else { $title = $item["title"]; - $body = $item["body"]; + $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); // Fetch the title from an attached link - if there is one if (empty($item["title"]) && DI::pConfig()->get($owner['uid'], 'system', 'attach_link_title')) { @@ -3529,7 +3532,7 @@ class Diaspora */ private static function constructLike(array $item, array $owner) { - $parent = Item::selectFirst(['guid', 'uri', 'thr-parent'], ['uri' => $item["thr-parent"]]); + $parent = Post::selectFirst(['guid', 'uri', 'thr-parent'], ['uri' => $item["thr-parent"]]); if (!DBA::isResult($parent)) { return false; } @@ -3561,7 +3564,7 @@ class Diaspora */ private static function constructAttend(array $item, array $owner) { - $parent = Item::selectFirst(['guid'], ['uri' => $item['thr-parent']]); + $parent = Post::selectFirst(['guid'], ['uri' => $item['thr-parent']]); if (!DBA::isResult($parent)) { return false; } @@ -3606,7 +3609,7 @@ class Diaspora return $result; } - $toplevel_item = Item::selectFirst(['guid', 'author-id', 'author-link'], ['id' => $item['parent'], 'parent' => $item['parent']]); + $toplevel_item = Post::selectFirst(['guid', 'author-id', 'author-link', 'gravity'], ['id' => $item['parent'], 'parent' => $item['parent']]); if (!DBA::isResult($toplevel_item)) { Logger::error('Missing parent conversation item', ['parent' => $item['parent']]); return false; @@ -3614,10 +3617,10 @@ class Diaspora $thread_parent_item = $toplevel_item; if ($item['thr-parent'] != $item['parent-uri']) { - $thread_parent_item = Item::selectFirst(['guid', 'author-id', 'author-link'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]); + $thread_parent_item = Post::selectFirst(['guid', 'author-id', 'author-link', 'gravity'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]); } - $body = $item["body"]; + $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); // The replied to autor mention is prepended for clarity if: // - Item replied isn't yours @@ -3625,6 +3628,7 @@ class Diaspora // - Implicit mentions are enabled if ( $item['author-id'] != $thread_parent_item['author-id'] + && ($thread_parent_item['gravity'] != GRAVITY_PARENT) && (empty($item['uid']) || !Feature::isEnabled($item['uid'], 'explicit_mentions')) && !DI::config()->get('system', 'disable_implicit_mentions') ) { @@ -3689,51 +3693,6 @@ class Diaspora return self::buildAndTransmit($owner, $contact, $type, $message, $public_batch, $item["guid"]); } - /** - * Creates a message from a signature record entry - * - * @param array $item The item that will be exported - * @return array The message - */ - private static function messageFromSignature(array $item) - { - // Split the signed text - $signed_parts = explode(";", $item['signed_text']); - - if ($item["deleted"]) { - $message = ["author" => $item['signer'], - "target_guid" => $signed_parts[0], - "target_type" => $signed_parts[1]]; - } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) { - $message = ["author" => $signed_parts[4], - "guid" => $signed_parts[1], - "parent_guid" => $signed_parts[3], - "parent_type" => $signed_parts[2], - "positive" => $signed_parts[0], - "author_signature" => $item['signature'], - "parent_author_signature" => ""]; - } else { - // Remove the comment guid - $guid = array_shift($signed_parts); - - // Remove the parent guid - $parent_guid = array_shift($signed_parts); - - // Remove the handle - $handle = array_pop($signed_parts); - - $message = [ - "author" => $handle, - "guid" => $guid, - "parent_guid" => $parent_guid, - "text" => implode(";", $signed_parts), - "author_signature" => $item['signature'], - "parent_author_signature" => "" - ]; - } - return $message; - } - /** * Relays messages (like, comment, retraction) to other servers if we are the thread owner * @@ -4090,7 +4049,7 @@ class Diaspora return false; } - $parent = Item::selectFirst(['parent-uri'], ['uri' => $item['thr-parent']]); + $parent = Post::selectFirst(['parent-uri'], ['uri' => $item['thr-parent']]); if (!DBA::isResult($parent)) { return; }