]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/Diaspora.php
Merge pull request #8835 from tobiasd/20200701-lng
[friendica.git] / src / Protocol / Diaspora.php
index 3cdf21b57ca66ad7c744ee14345bc4e4289ee20e..b579f92df05e85b39edb817d84c205b44a748818 100644 (file)
@@ -252,24 +252,27 @@ class Diaspora
         * One of the parameters is a contact array.
         * This is done to avoid duplicates.
         *
-        * @param array $parent   The parent post
+        * @param array $item     Item that is about to be delivered
         * @param array $contacts The previously fetched contacts
         *
         * @return array of relay servers
         * @throws \Exception
         */
-       public static function participantsForThread(array $parent, array $contacts)
+       public static function participantsForThread(array $item, array $contacts)
        {
-               if (!in_array($parent['private'], [Item::PUBLIC, Item::UNLISTED])) {
+               if (!in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]) || in_array($item["verb"], [Activity::FOLLOW, Activity::TAG])) {
+                       Logger::info('Item is private or a participation request. It will not be relayed', ['guid' => $item['guid'], 'private' => $item['private'], 'verb' => $item['verb']]);
                        return $contacts;
                }
 
-               $items = Item::select(['author-id'], ['parent' => $parent['id']], ['group_by' => ['author-id']]);
+               $items = Item::select(['author-id', 'author-link', 'parent-author-link', 'parent-guid', 'guid'],
+                       ['parent' => $item['parent'], 'gravity' => [GRAVITY_COMMENT, GRAVITY_ACTIVITY]]);
                while ($item = DBA::fetch($items)) {
                        $contact = DBA::selectFirst('contact', ['id', 'url', 'name', 'protocol', 'batch', 'network'],
                                ['id' => $item['author-id']]);
-                       if (!DBA::isResult($contact)) {
-                               // Shouldn't happen
+                       if (!DBA::isResult($contact) || empty($contact['batch']) ||
+                               ($contact['network'] != Protocol::DIASPORA) ||
+                               Strings::compareLink($item['parent-author-link'], $item['author-link'])) {
                                continue;
                        }
 
@@ -281,7 +284,7 @@ class Diaspora
                        }
 
                        if (!$exists) {
-                               Logger::info('Add participant to receiver list', ['item' => $parent['guid'], 'participant' => $contact['url']]);
+                               Logger::info('Add participant to receiver list', ['parent' => $item['parent-guid'], 'item' => $item['guid'], 'participant' => $contact['url']]);
                                $contacts[] = $contact;
                        }
                }
@@ -290,37 +293,6 @@ class Diaspora
                return $contacts;
        }
 
-       /**
-        * repairs a signature that was double encoded
-        *
-        * The function is unused at the moment. It was copied from the old implementation.
-        *
-        * @param string  $signature The signature
-        * @param string  $handle    The handle of the signature owner
-        * @param integer $level     This value is only set inside this function to avoid endless loops
-        *
-        * @return string the repaired signature
-        * @throws \Exception
-        */
-       private static function repairSignature($signature, $handle = "", $level = 1)
-       {
-               if ($signature == "") {
-                       return ($signature);
-               }
-
-               if (base64_encode(base64_decode(base64_decode($signature))) == base64_decode($signature)) {
-                       $signature = base64_decode($signature);
-                       Logger::log("Repaired double encoded signature from Diaspora/Hubzilla handle ".$handle." - level ".$level, Logger::DEBUG);
-
-                       // Do a recursive call to be able to fix even multiple levels
-                       if ($level < 10) {
-                               $signature = self::repairSignature($signature, $handle, ++$level);
-                       }
-               }
-
-               return($signature);
-       }
-
        /**
         * verify the envelope and return the verified data
         *
@@ -539,7 +511,7 @@ class Diaspora
                $basedom = XML::parseString($xml);
 
                if (!is_object($basedom)) {
-                       Logger::log("XML is not parseable.");
+                       Logger::notice('XML is not parseable.');
                        return false;
                }
                $children = $basedom->children('https://joindiaspora.com/protocol');
@@ -553,7 +525,7 @@ class Diaspora
                } else {
                        // This happens with posts from a relais
                        if (empty($privKey)) {
-                               Logger::log("This is no private post in the old format", Logger::DEBUG);
+                               Logger::info('This is no private post in the old format');
                                return false;
                        }
 
@@ -572,7 +544,7 @@ class Diaspora
 
                        $decrypted = self::aesDecrypt($outer_key, $outer_iv, $ciphertext);
 
-                       Logger::log('decrypted: '.$decrypted, Logger::DEBUG);
+                       Logger::info('decrypted', ['data' => $decrypted]);
                        $idom = XML::parseString($decrypted);
 
                        $inner_iv = base64_decode($idom->iv);
@@ -721,7 +693,7 @@ class Diaspora
 
                $type = $fields->getName();
 
-               Logger::log("Received message type ".$type." from ".$sender." for user ".$importer["uid"], Logger::DEBUG);
+               Logger::info('Received message', ['type' => $type, 'sender' => $sender, 'user' => $importer["uid"]]);
 
                switch ($type) {
                        case "account_migration":
@@ -813,7 +785,7 @@ class Diaspora
                $data = XML::parseString($msg["message"]);
 
                if (!is_object($data)) {
-                       Logger::log("No valid XML ".$msg["message"], Logger::DEBUG);
+                       Logger::info('No valid XML', ['message' => $msg['message']]);
                        return false;
                }
 
@@ -925,7 +897,7 @@ class Diaspora
                if (isset($parent_author_signature)) {
                        $key = self::key($msg["author"]);
                        if (empty($key)) {
-                               Logger::log("No key found for parent author ".$msg["author"], Logger::DEBUG);
+                               Logger::info('No key found for parent', ['author' => $msg["author"]]);
                                return false;
                        }
 
@@ -937,7 +909,7 @@ class Diaspora
 
                $key = self::key($fields->author);
                if (empty($key)) {
-                       Logger::log("No key found for author ".$fields->author, Logger::DEBUG);
+                       Logger::info('No key found', ['author' => $fields->author]);
                        return false;
                }
 
@@ -991,7 +963,7 @@ class Diaspora
                }
 
                if (DBA::isResult($person)) {
-                       Logger::debug("In cache " . print_r($person, true));
+                       Logger::debug('In cache', ['person' => $person]);
 
                        if (is_null($update)) {
                                // update record occasionally so it doesn't get stale
@@ -1105,7 +1077,7 @@ class Diaspora
         */
        public static function urlFromContactGuid($fcontact_guid)
        {
-               Logger::log("fcontact guid is ".$fcontact_guid, Logger::DEBUG);
+               Logger::info('fcontact', ['guid' => $fcontact_guid]);
 
                $r = q(
                        "SELECT `url` FROM `fcontact` WHERE `url` != '' AND `network` = '%s' AND `guid` = '%s'",
@@ -1514,7 +1486,7 @@ class Diaspora
        private static function parentItem($uid, $guid, $author, array $contact)
        {
                $fields = ['id', 'parent', 'body', 'wall', 'uri', 'guid', 'private', 'origin',
-                       'author-name', 'author-link', 'author-avatar',
+                       'author-name', 'author-link', 'author-avatar', 'gravity',
                        'owner-name', 'owner-link', 'owner-avatar'];
                $condition = ['uid' => $uid, 'guid' => $guid];
                $item = Item::selectFirst($fields, $condition);
@@ -2161,8 +2133,8 @@ class Diaspora
                $datarray["changed"] = $datarray["created"] = $datarray["edited"] = DateTimeFormat::utcNow();
 
                // like on comments have the comment as parent. So we need to fetch the toplevel parent
-               if ($parent_item["id"] != $parent_item["parent"]) {
-                       $toplevel = Item::selectFirst(['origin'], ['id' => $parent_item["parent"]]);
+               if ($parent_item['gravity'] != GRAVITY_PARENT) {
+                       $toplevel = Item::selectFirst(['origin'], ['id' => $parent_item['parent']]);
                        $origin = $toplevel["origin"];
                } else {
                        $origin = $parent_item["origin"];
@@ -2281,6 +2253,10 @@ class Diaspora
                        return false;
                }
 
+               if (!$parent_item['origin']) {
+                       Logger::info('Not our origin. Participation is ignored', ['parent_guid' => $parent_guid, 'guid' => $guid, 'author' => $author]);
+               }
+
                if (!in_array($parent_item['private'], [Item::PUBLIC, Item::UNLISTED])) {
                        Logger::info('Item is not public, participation is ignored', ['parent_guid' => $parent_guid, 'guid' => $guid, 'author' => $author]);
                        return false;
@@ -2325,9 +2301,21 @@ 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', 'verb', 'self'], ['parent' => $parent_item['id']]);
+               $comments = Item::select(['id', 'uri-id', 'parent-author-network', 'author-network', 'verb'],
+                       ['parent' => $parent_item['id'], 'gravity' => [GRAVITY_COMMENT, GRAVITY_ACTIVITY]]);
                while ($comment = Item::fetch($comments)) {
-                       if ($comment['id'] == $comment['parent']) {
+                       if (in_array($comment['verb'], [Activity::FOLLOW, Activity::TAG])) {
+                               Logger::info('participation messages are not relayed', ['item' => $comment['id']]);
+                               continue;
+                       }
+
+                       if ($comment['author-network'] == Protocol::ACTIVITYPUB) {
+                               Logger::info('Comments from ActivityPub authors are not relayed', ['item' => $comment['id']]);
+                               continue;
+                       }
+
+                       if ($comment['parent-author-network'] == Protocol::ACTIVITYPUB) {
+                               Logger::info('Comments to comments from ActivityPub authors are not relayed', ['item' => $comment['id']]);
                                continue;
                        }
 
@@ -2787,13 +2775,13 @@ class Diaspora
 
                /// @todo Copy tag data from original post
 
-               $prefix = share_header(
+               $prefix = BBCode::getShareOpeningTag(
                        $original_item["author-name"],
                        $original_item["author-link"],
                        $original_item["author-avatar"],
-                       $original_item["guid"],
+                       $orig_url,
                        $original_item["created"],
-                       $orig_url
+                       $original_item["guid"]
                );
 
                if (!empty($original_item['title'])) {
@@ -2883,7 +2871,7 @@ class Diaspora
                        }
 
                        // Fetch the parent item
-                       $parent = Item::selectFirst(['author-link'], ['id' => $item["parent"]]);
+                       $parent = Item::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"])) {
@@ -2893,7 +2881,7 @@ class Diaspora
 
                        Item::markForDeletion(['id' => $item['id']]);
 
-                       Logger::log("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item["parent"], Logger::DEBUG);
+                       Logger::log("Deleted target ".$target_guid." (".$item["id"].") from user ".$item["uid"]." parent: ".$item['parent'], Logger::DEBUG);
                }
 
                return true;
@@ -3131,7 +3119,9 @@ class Diaspora
                $json = json_encode(["iv" => $b_iv, "key" => $b_aes_key]);
 
                $encrypted_key_bundle = "";
-               openssl_public_encrypt($json, $encrypted_key_bundle, $pubkey);
+               if (!@openssl_public_encrypt($json, $encrypted_key_bundle, $pubkey)) {
+                       return false;
+               }
 
                $json_object = json_encode(
                        ["aes_key" => base64_encode($encrypted_key_bundle),
@@ -3406,7 +3396,7 @@ class Diaspora
                                "profile" => $profile,
                                "signature" => $signature];
 
-               Logger::log("Send account migration ".print_r($message, true), Logger::DEBUG);
+               Logger::info('Send account migration', ['msg' => $message]);
 
                return self::buildAndTransmit($owner, $contact, "account_migration", $message);
        }
@@ -3450,7 +3440,7 @@ class Diaspora
                                "following" => "true",
                                "sharing" => "true"];
 
-               Logger::log("Send share ".print_r($message, true), Logger::DEBUG);
+               Logger::info('Send share', ['msg' => $message]);
 
                return self::buildAndTransmit($owner, $contact, "contact", $message);
        }
@@ -3471,7 +3461,7 @@ class Diaspora
                                "following" => "false",
                                "sharing" => "false"];
 
-               Logger::log("Send unshare ".print_r($message, true), Logger::DEBUG);
+               Logger::info('Send unshare', ['msg' => $message]);
 
                return self::buildAndTransmit($owner, $contact, "contact", $message);
        }
@@ -3666,8 +3656,8 @@ class Diaspora
 
                        if ($item['author-link'] != $item['owner-link']) {
                                require_once 'mod/share.php';
-                               $body = share_header($item['author-name'], $item['author-link'], $item['author-avatar'],
-                                       "", $item['created'], $item['plink']) . $body . '[/share]';
+                               $body = BBCode::getShareOpeningTag($item['author-name'], $item['author-link'], $item['author-avatar'],
+                                       $item['plink'], $item['created']) . $body . '[/share]';
                        }
 
                        // convert to markdown
@@ -3860,9 +3850,9 @@ class Diaspora
                        return $result;
                }
 
-               $toplevel_item = Item::selectFirst(['guid', 'author-id', 'author-link'], ['id' => $item["parent"], 'parent' => $item["parent"]]);
+               $toplevel_item = Item::selectFirst(['guid', 'author-id', 'author-link'], ['id' => $item['parent'], 'parent' => $item['parent']]);
                if (!DBA::isResult($toplevel_item)) {
-                       Logger::error('Missing parent conversation item', ['parent' => $item["parent"]]);
+                       Logger::error('Missing parent conversation item', ['parent' => $item['parent']]);
                        return false;
                }
 
@@ -4033,7 +4023,7 @@ class Diaspora
 
                $message["parent_author_signature"] = self::signature($owner, $message);
 
-               Logger::log("Relayed data ".print_r($message, true), Logger::DEBUG);
+               Logger::info('Relayed data', ['msg' => $message]);
 
                return self::buildAndTransmit($owner, $contact, $type, $message, $public_batch, $item["guid"]);
        }
@@ -4056,7 +4046,7 @@ class Diaspora
 
                $msg_type = "retraction";
 
-               if ($item['id'] == $item['parent']) {
+               if ($item['gravity'] == GRAVITY_PARENT) {
                        $target_type = "Post";
                } elseif (in_array($item["verb"], [Activity::LIKE, Activity::DISLIKE])) {
                        $target_type = "Like";
@@ -4068,7 +4058,7 @@ class Diaspora
                                "target_guid" => $item['guid'],
                                "target_type" => $target_type];
 
-               Logger::log("Got message ".print_r($message, true), Logger::DEBUG);
+               Logger::info('Got message', ['msg' => $message]);
 
                return self::buildAndTransmit($owner, $contact, $msg_type, $message, $public_batch, $item["guid"]);
        }
@@ -4309,7 +4299,7 @@ class Diaspora
        {
                $owner = User::getOwnerDataById($uid);
                if (empty($owner)) {
-                       Logger::log("No owner post, so not storing signature", Logger::DEBUG);
+                       Logger::info('No owner post, so not storing signature');
                        return false;
                }
 
@@ -4340,7 +4330,7 @@ class Diaspora
        {
                $owner = User::getOwnerDataById($uid);
                if (empty($owner)) {
-                       Logger::log("No owner post, so not storing signature", Logger::DEBUG);
+                       Logger::info('No owner post, so not storing signature');
                        return false;
                }