]> git.mxchange.org Git - friendica.git/commitdiff
AP: Transmitting and receiving with non AP contacts
authorMichael <heluecht@pirati.ca>
Sat, 20 Oct 2018 07:53:45 +0000 (07:53 +0000)
committerMichael <heluecht@pirati.ca>
Sat, 20 Oct 2018 07:53:45 +0000 (07:53 +0000)
boot.php
config/dbstructure.json
src/Protocol/ActivityPub/Receiver.php
src/Protocol/ActivityPub/Transmitter.php
src/Worker/Notifier.php

index acbc737658c2a8d4aef307aee52092abc74c7008..5d4b7c147ee6890741ceeb17d46154eb2f281427 100644 (file)
--- a/boot.php
+++ b/boot.php
@@ -41,7 +41,7 @@ define('FRIENDICA_PLATFORM',     'Friendica');
 define('FRIENDICA_CODENAME',     'The Tazmans Flax-lily');
 define('FRIENDICA_VERSION',      '2018.12-dev');
 define('DFRN_PROTOCOL_VERSION',  '2.23');
-define('DB_UPDATE_VERSION',      1288);
+define('DB_UPDATE_VERSION',      1289);
 define('NEW_UPDATE_ROUTINE_VERSION', 1170);
 
 /**
index da1da7a66b1a295242db1cf7aaa4ff2af39765c2..43fce1d2f90a7c4abad5ebaa2af3622d6572ae15 100644 (file)
@@ -40,6 +40,7 @@
                "indexes": {
                        "PRIMARY": ["url"],
                        "addr": ["addr(32)"],
+                       "alias": ["alias(190)"],
                        "url": ["followers(190)"]
                }
        },
index a5ba0763db56a05bd83dd9abdce5b3e5c45921e1..4341c14a3f42b544e927229f6090fd83945d72b1 100644 (file)
@@ -419,8 +419,9 @@ class Receiver
                                }
 
                                if (in_array($receiver, [$followers, self::PUBLIC_COLLECTION]) && !empty($actor)) {
+                                       $networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS];
                                        $condition = ['nurl' => normalise_link($actor), 'rel' => [Contact::SHARING, Contact::FRIEND],
-                                               'network' => Protocol::ACTIVITYPUB, 'archive' => false, 'pending' => false];
+                                               'network' => $networks, 'archive' => false, 'pending' => false];
                                        $contacts = DBA::select('contact', ['uid'], $condition);
                                        while ($contact = DBA::fetch($contacts)) {
                                                if ($contact['uid'] != 0) {
index 98422f3ad0895f177cbc465b3649437732711ece..a94b7f59fde0c9b18aaaf50eec92b7860232531d 100644 (file)
@@ -308,6 +308,12 @@ class Transmitter
         */
        private static function createPermissionBlockForItem($item)
        {
+               // Will be activated in a later step
+               // $networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS];
+
+               // For now only send to these contacts:
+               $networks = [Protocol::ACTIVITYPUB, Protocol::OSTATUS];
+
                $data = ['to' => [], 'cc' => []];
 
                $data = array_merge($data, self::fetchPermissionBlockFromConversation($item));
@@ -316,8 +322,6 @@ class Transmitter
 
                $terms = Term::tagArrayFromItemId($item['id'], TERM_MENTION);
 
-               $contacts[$item['author-link']] = $item['author-link'];
-
                if (!$item['private']) {
                        $data['to'][] = ActivityPub::PUBLIC_COLLECTION;
                        if (!empty($actor_profile['followers'])) {
@@ -326,13 +330,8 @@ class Transmitter
 
                        foreach ($terms as $term) {
                                $profile = APContact::getByURL($term['url'], false);
-                               if (!empty($profile) && empty($contacts[$profile['url']])) {
+                               if (!empty($profile)) {
                                        $data['to'][] = $profile['url'];
-                                       $contacts[$profile['url']] = $profile['url'];
-
-                                       if (($key = array_search($profile['url'], $data['cc'])) !== false) {
-                                               unset($data['cc'][$key]);
-                                       }
                                }
                        }
                } else {
@@ -343,21 +342,17 @@ class Transmitter
                        foreach ($terms as $term) {
                                $cid = Contact::getIdForURL($term['url'], $item['uid']);
                                if (!empty($cid) && in_array($cid, $receiver_list)) {
-                                       $contact = DBA::selectFirst('contact', ['url'], ['id' => $cid, 'network' => Protocol::ACTIVITYPUB]);
-                                       $data['to'][] = $contact['url'];
-                                       $contacts[$contact['url']] = $contact['url'];
-
-                                       if (($key = array_search($profile['url'], $data['cc'])) !== false) {
-                                               unset($data['cc'][$key]);
+                                       $contact = DBA::selectFirst('contact', ['url'], ['id' => $cid, 'network' => $networks]);
+                                       if (DBA::isResult($contact) && !empty($profile = APContact::getByURL($contact['url'], false))) {
+                                               $data['to'][] = $profile['url'];
                                        }
                                }
                        }
 
                        foreach ($receiver_list as $receiver) {
-                               $contact = DBA::selectFirst('contact', ['url'], ['id' => $receiver, 'network' => Protocol::ACTIVITYPUB]);
-                               if (DBA::isResult($contact) && empty($contacts[$contact['url']])) {
-                                       $data['cc'][] = $contact['url'];
-                                       $contacts[$contact['url']] = $contact['url'];
+                               $contact = DBA::selectFirst('contact', ['url'], ['id' => $receiver, 'network' => $networks]);
+                               if (DBA::isResult($contact) && !empty($profile = APContact::getByURL($contact['url'], false))) {
+                                       $data['cc'][] = $profile['url'];
                                }
                        }
                }
@@ -370,32 +365,28 @@ class Transmitter
                        }
 
                        $profile = APContact::getByURL($parent['author-link'], false);
-                       if (!empty($profile) && ($parent['uri'] == $item['thr-parent'])) {
-                               $data['to'][] = $profile['url'];
-                               $contacts[$profile['url']] = $profile['url'];
-
-                               if (($key = array_search($profile['url'], $data['cc'])) !== false) {
-                                       unset($data['cc'][$key]);
+                       if (!empty($profile)) {
+                               if ($parent['uri'] == $item['thr-parent']) {
+                                       $data['to'][] = $profile['url'];
+                               } else {
+                                       $data['cc'][] = $profile['url'];
                                }
                        }
 
-                       if (!empty($profile) && empty($contacts[$profile['url']])) {
-                               $data['cc'][] = $profile['url'];
-                               $contacts[$profile['url']] = $profile['url'];
-                       }
-
                        if ($item['gravity'] != GRAVITY_PARENT) {
                                continue;
                        }
 
                        $profile = APContact::getByURL($parent['owner-link'], false);
-                       if (!empty($profile) && empty($contacts[$profile['url']])) {
+                       if (!empty($profile)) {
                                $data['cc'][] = $profile['url'];
-                               $contacts[$profile['url']] = $profile['url'];
                        }
                }
                DBA::close($parents);
 
+               $data['to'] = array_unique($data['to']);
+               $data['cc'] = array_unique($data['cc']);
+
                if (($key = array_search($item['author-link'], $data['to'])) !== false) {
                        unset($data['to'][$key]);
                }
@@ -404,30 +395,50 @@ class Transmitter
                        unset($data['cc'][$key]);
                }
 
-               return ['to' => array_values(array_unique($data['to'])), 'cc' => array_values(array_unique($data['cc']))];
+               foreach ($data['to'] as $to) {
+                       if (($key = array_search($to, $data['cc'])) !== false) {
+                               unset($data['cc'][$key]);
+                       }
+               }
+
+               return ['to' => array_values($data['to']), 'cc' => array_values($data['cc'])];
        }
 
        /**
         * Fetches a list of inboxes of followers of a given user
         *
         * @param integer $uid User ID
+        * @param boolean $personal fetch personal inboxes
         *
         * @return array of follower inboxes
         */
-       public static function fetchTargetInboxesforUser($uid)
+       public static function fetchTargetInboxesforUser($uid, $personal = false)
        {
                $inboxes = [];
 
-               $condition = ['uid' => $uid, 'network' => Protocol::ACTIVITYPUB, 'archive' => false, 'pending' => false];
+               // Will be activated in a later step
+               // $networks = [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS];
+
+               // For now only send to these contacts:
+               $networks = [Protocol::ACTIVITYPUB, Protocol::OSTATUS];
+
+               $condition = ['uid' => $uid, 'network' => $networks, 'archive' => false, 'pending' => false];
 
                if (!empty($uid)) {
                        $condition['rel'] = [Contact::FOLLOWER, Contact::FRIEND];
                }
 
-               $contacts = DBA::select('contact', ['notify', 'batch'], $condition);
+               $contacts = DBA::select('contact', ['url'], $condition);
                while ($contact = DBA::fetch($contacts)) {
-                       $contact = defaults($contact, 'batch', $contact['notify']);
-                       $inboxes[$contact] = $contact;
+                       $profile = APContact::getByURL($contact['url'], false);
+                       if (!empty($profile)) {
+                               if (empty($profile['sharedinbox']) || $personal) {
+                                       $target = $profile['inbox'];
+                               } else {
+                                       $target = $profile['sharedinbox'];
+                               }
+                               $inboxes[$target] = $target;
+                       }
                }
                DBA::close($contacts);
 
@@ -439,10 +450,11 @@ class Transmitter
         *
         * @param array $item
         * @param integer $uid User ID
+        * @param boolean $personal fetch personal inboxes
         *
         * @return array with inboxes
         */
-       public static function fetchTargetInboxes($item, $uid)
+       public static function fetchTargetInboxes($item, $uid, $personal = false)
        {
                $permissions = self::createPermissionBlockForItem($item);
                if (empty($permissions)) {
@@ -452,9 +464,9 @@ class Transmitter
                $inboxes = [];
 
                if ($item['gravity'] == GRAVITY_ACTIVITY) {
-                       $item_profile = APContact::getByURL($item['author-link']);
+                       $item_profile = APContact::getByURL($item['author-link'], false);
                } else {
-                       $item_profile = APContact::getByURL($item['owner-link']);
+                       $item_profile = APContact::getByURL($item['owner-link'], false);
                }
 
                foreach (['to', 'cc', 'bto', 'bcc'] as $element) {
@@ -464,11 +476,15 @@ class Transmitter
 
                        foreach ($permissions[$element] as $receiver) {
                                if ($receiver == $item_profile['followers']) {
-                                       $inboxes = self::fetchTargetInboxesforUser($uid);
+                                       $inboxes = self::fetchTargetInboxesforUser($uid, $personal);
                                } else {
-                                       $profile = APContact::getByURL($receiver);
+                                       $profile = APContact::getByURL($receiver, false);
                                        if (!empty($profile)) {
-                                               $target = defaults($profile, 'sharedinbox', $profile['inbox']);
+                                               if (empty($profile['sharedinbox']) || $personal) {
+                                                       $target = $profile['inbox'];
+                                               } else {
+                                                       $target = $profile['sharedinbox'];
+                                               }
                                                $inboxes[$target] = $target;
                                        }
                                }
index ad33c3245d4be9d33e1381cb9d1cb00b40851842..3edc15c3b80496cbfbbf2997260af33a637cfad9 100644 (file)
@@ -512,6 +512,7 @@ class Notifier
        private static function activityPubDelivery($a, $cmd, $item_id, $uid, $target_item, $parent)
        {
                $inboxes = [];
+               $personal = false;
 
                if ($target_item['origin']) {
                        $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($target_item, $uid);
@@ -520,11 +521,14 @@ class Notifier
                        logger('Remote item ' . $item_id . ' with URL ' . $target_item['uri'] . ' is no AP post. It will not be distributed.', LOGGER_DEBUG);
                        return;
                } else {
+                       // Remote items are transmitted via the personal inboxes.
+                       // Doing so ensures that the dedicated receiver will get the message.
+                       $personal = true;
                        logger('Remote item ' . $item_id . ' with URL ' . $target_item['uri'] . ' will be distributed.', LOGGER_DEBUG);
                }
 
                if ($parent['origin']) {
-                       $parent_inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid);
+                       $parent_inboxes = ActivityPub\Transmitter::fetchTargetInboxes($parent, $uid, $personal);
                        $inboxes = array_merge($inboxes, $parent_inboxes);
                }