]> git.mxchange.org Git - friendica.git/commitdiff
Don't transmit to archived inboxes
authorMichael <heluecht@pirati.ca>
Mon, 23 Nov 2020 19:25:22 +0000 (19:25 +0000)
committerMichael <heluecht@pirati.ca>
Mon, 23 Nov 2020 19:25:22 +0000 (19:25 +0000)
src/Model/APContact.php
src/Protocol/ActivityPub/Receiver.php
src/Protocol/ActivityPub/Transmitter.php
src/Util/HTTPSignature.php
src/Worker/APDelivery.php
src/Worker/Delivery.php
static/dbstructure.config.php

index 6a8e5b3ae1c78e39433c1d25543fab4a02718616..56832cba6fb179bb2ad9f383f7248761b5ba01b1 100644 (file)
@@ -32,6 +32,7 @@ use Friendica\Protocol\ActivityNamespace;
 use Friendica\Protocol\ActivityPub;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
+use Friendica\Util\HTTPSignature;
 use Friendica\Util\JsonLD;
 use Friendica\Util\Network;
 
@@ -148,6 +149,7 @@ class APContact
 
                $data = ActivityPub::fetchContent($url);
                if (empty($data)) {
+                       self::markForArchival($fetched_contact ?: []);
                        return $fetched_contact;
                }
 
@@ -350,10 +352,54 @@ class APContact
                return $apcontact;
        }
 
+       /**
+        * Mark the given AP Contact as "to archive"
+        *
+        * @param array $apcontact
+        * @return void
+        */
+       public static function markForArchival(array $apcontact)
+       {
+               if (!empty($apcontact['inbox'])) {
+                       Logger::info('Set inbox status to failure', ['inbox' => $apcontact['inbox']]);
+                       HTTPSignature::setInboxStatus($apcontact['inbox'], false);
+               }
+
+               if (!empty($apcontact['sharedinbox'])) {
+                       // Check if there are any vital inboxes
+                       $vital = DBA::exists('apcontact', ["`sharedinbox` = ? AnD `inbox` IN (SELECT `url` FROM `inbox-status` WHERE `success` > `failure`)",
+                               $apcontact['sharedinbox']]);
+                       if (!$vital) {
+                               // If all known personal inboxes are failing then set their shared inbox to failure as well
+                               Logger::info('Set shared inbox status to failure', ['sharedinbox' => $apcontact['sharedinbox']]);
+                               HTTPSignature::setInboxStatus($apcontact['sharedinbox'], false, true);
+                       }
+               }
+       }
+
+       /**
+        * Unmark the given AP Contact as "to archive"
+        *
+        * @param array $apcontact
+        * @return void
+        */
+       public static function unmarkForArchival(array $apcontact)
+       {
+               if (!empty($apcontact['inbox'])) {
+                       Logger::info('Set inbox status to success', ['inbox' => $apcontact['inbox']]);
+                       HTTPSignature::setInboxStatus($apcontact['inbox'], true);
+               }
+               if (!empty($apcontact['sharedinbox'])) {
+                       Logger::info('Set shared inbox status to success', ['sharedinbox' => $apcontact['sharedinbox']]);
+                       HTTPSignature::setInboxStatus($apcontact['sharedinbox'], true, true);
+               }
+       }
+
        /**
         * Unarchive inboxes
         *
-        * @param string $url inbox url
+        * @param string  $url    inbox url
+        * @param boolean $shared Shared Inbox
         */
        private static function unarchiveInbox($url, $shared)
        {
@@ -361,15 +407,6 @@ class APContact
                        return;
                }
 
-               $now = DateTimeFormat::utcNow();
-
-               $fields = ['archive' => false, 'success' => $now, 'shared' => $shared];
-
-               if (!DBA::exists('inbox-status', ['url' => $url])) {
-                       $fields = array_merge($fields, ['url' => $url, 'created' => $now]);
-                       DBA::replace('inbox-status', $fields);
-               } else {
-                       DBA::update('inbox-status', $fields, ['url' => $url]);
-               }
+               HTTPSignature::setInboxStatus($url, true, $shared);
        }
 }
index 3c0f4862e6d212475771012f3a4d62ce23b30847..d1426ff5aef2400b9871e577674f636ba4a9fa9b 100644 (file)
@@ -104,6 +104,8 @@ class Receiver
                        return;
                }
 
+               APContact::unMarkForArchival($apcontact);
+
                $http_signer = HTTPSignature::getSigner($body, $header);
                if (empty($http_signer)) {
                        Logger::warning('Invalid HTTP signature, message will be discarded.');
@@ -233,6 +235,7 @@ class Receiver
 
                $profile = APContact::getByURL($object_id);
                if (!empty($profile['type'])) {
+                       APContact::unMarkForArchival($profile);
                        return 'as:' . $profile['type'];
                }
 
index 4c2977ec7f849915053f32eb8775966418e4a653..7f5f51c38aedcde640271d4f8bfba59250606102 100644 (file)
@@ -670,7 +670,7 @@ class Transmitter
         *
         * @return boolean "true" if inbox is archived
         */
-       private static function archivedInbox($url)
+       public static function archivedInbox($url)
        {
                return DBA::exists('inbox-status', ['url' => $url, 'archive' => true]);
        }
index c5507adf3faef85631f4f25eaee1c5dbf40e66f1..5b7bb02a3ec9252ec1082355da352c18a04ad929 100644 (file)
@@ -314,14 +314,15 @@ class HTTPSignature
         *
         * @param string  $url     The URL of the inbox
         * @param boolean $success Transmission status
+        * @param boolean $shared  The inbox is a shared inbox
         */
-       static private function setInboxStatus($url, $success)
+       static public function setInboxStatus($url, $success, $shared = false)
        {
                $now = DateTimeFormat::utcNow();
 
                $status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
                if (!DBA::isResult($status)) {
-                       DBA::insert('inbox-status', ['url' => $url, 'created' => $now]);
+                       DBA::insert('inbox-status', ['url' => $url, 'created' => $now, 'shared' => $shared]);
                        $status = DBA::selectFirst('inbox-status', [], ['url' => $url]);
                }
 
index 92767a10589b2fa5d020e1fc89eff353d257b65c..a25977372a3a2edd3168c0d2d2fe427d5c7c6123 100644 (file)
@@ -42,7 +42,16 @@ class APDelivery
         */
        public static function execute($cmd, $target_id, $inbox, $uid)
        {
-               Logger::log('Invoked: ' . $cmd . ': ' . $target_id . ' to ' . $inbox, Logger::DEBUG);
+               if (ActivityPub\Transmitter::archivedInbox($inbox)) {
+                       Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $target_id, 'uid' => $uid]);
+                       if (in_array($cmd, [Delivery::POST])) {
+                               $item = Item::selectFirst(['uri-id'], ['id' => $target_id]);
+                               Post\DeliveryData::incrementQueueFailed($item['uri-id'] ?? 0);
+                       }
+                       return;
+               }
+
+               Logger::info('Invoked', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $target_id, 'uid' => $uid]);
 
                $success = true;
 
index 44041957fc428472e56a1df7366e8a566f25fd36..8e49ee4715cce9b5a5c103f015a4e4f90f4ab7c7 100644 (file)
@@ -193,9 +193,9 @@ class Delivery
                        return;
                }
 
-               // We don't deliver our items to blocked or pending contacts, and not to ourselves either
+               // We don't deliver our items to blocked, archived or pending contacts, and not to ourselves either
                $contact = DBA::selectFirst('contact', [],
-                       ['id' => $contact_id, 'blocked' => false, 'pending' => false, 'self' => false]
+                       ['id' => $contact_id, 'archive' => false, 'blocked' => false, 'pending' => false, 'self' => false]
                );
                if (!DBA::isResult($contact)) {
                        self::setFailedQueue($cmd, $target_item);
index caec82625f0b68bb0cf3fc97c49c196a899bd960..3239c8e7cae47068a3cfd0ef1a3365c74db4bb05 100644 (file)
@@ -55,7 +55,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1378);
+       define('DB_UPDATE_VERSION', 1379);
 }
 
 return [
@@ -395,6 +395,7 @@ return [
                        "alias" => ["alias(190)"],
                        "followers" => ["followers(190)"],
                        "baseurl" => ["baseurl(190)"],
+                       "sharedinbox" => ["sharedinbox(190)"],
                        "gsid" => ["gsid"]
                ]
        ],
@@ -1081,7 +1082,7 @@ return [
                "comment" => "photo storage",
                "fields" => [
                        "id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
-                       "uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid"], "comment" => "Owner User id"],
+                       "uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "foreign" => ["user" => "uid", "on delete" => "restrict"], "comment" => "Owner User id"],
                        "contact-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id", "on delete" => "restrict"], "comment" => "contact.id"],
                        "guid" => ["type" => "char(16)", "not null" => "1", "default" => "", "comment" => "A unique identifier for this photo"],
                        "resource-id" => ["type" => "char(32)", "not null" => "1", "default" => "", "comment" => ""],