]> git.mxchange.org Git - friendica.git/commitdiff
Improved distribution of non public messages
authorMichael <heluecht@pirati.ca>
Thu, 30 Nov 2023 05:51:38 +0000 (05:51 +0000)
committerMichael <heluecht@pirati.ca>
Thu, 30 Nov 2023 05:51:38 +0000 (05:51 +0000)
mod/item.php
src/Content/Item.php
src/Model/Item.php
src/Protocol/ActivityPub/Receiver.php

index 70c5c9a8b61f338d1d1d43fd75bfe2ac44b09a1e..e85c08e023c87a4a28c3771280c825cfa73067bf 100644 (file)
@@ -222,7 +222,7 @@ function item_insert(int $uid, array $request, bool $preview, string $return_pat
        DI::contentItem()->postProcessPost($post, $recipients);
 
        if (($post['private'] == Item::PRIVATE) && ($post['thr-parent-id'] != $post['uri-id'])) {
-               DI::contentItem()->copyPermissions($post['thr-parent-id'], $post['uri-id']);
+               DI::contentItem()->copyPermissions($post['thr-parent-id'], $post['uri-id'], $post['parent-uri-id']);
        }
 
        Logger::debug('post_complete');
index ab5ff1698f8db1f9d8bf8ae1dd406f14e93d902d..f74a9589626e082d6d002de3727ca826ec16dd9d 100644 (file)
@@ -1070,17 +1070,32 @@ class Item
                }
        }
 
-       public function copyPermissions(int $fromUriId, int $toUriId)
+       public function copyPermissions(int $fromUriId, int $toUriId, int $parentUriId)
        {
-               $from        = Post::selectFirstPost(['author-id'], ['uri-id' => $fromUriId]);
-               $from_author = DBA::selectFirst('account-view', ['ap-followers'], ['id' => $from['author-id']]);
-               $to          = Post::selectFirstPost(['author-id'], ['uri-id' => $toUriId]);
-               $to_author   = DBA::selectFirst('account-view', ['ap-followers'], ['id' => $to['author-id']]);
+               $from          = Post::selectFirstPost(['author-id'], ['uri-id' => $fromUriId]);
+               $from_author   = DBA::selectFirst('account-view', ['ap-followers'], ['id' => $from['author-id']]);
+               $to            = Post::selectFirstPost(['author-id'], ['uri-id' => $toUriId]);
+               $to_author     = DBA::selectFirst('account-view', ['ap-followers'], ['id' => $to['author-id']]);
+               $parent        = Post::selectFirstPost(['author-id'], ['uri-id' => $parentUriId]);
+               $parent_author = DBA::selectFirst('account-view', ['ap-followers'], ['id' => $parent['author-id']]);
+               
+               $followers = '';
+               foreach (array_column(Tag::getByURIId($parentUriId, [Tag::TO, Tag::CC, Tag::BCC]), 'url') as $url) {
+                       if ($url == $parent_author['ap-followers']) {
+                               $followers = $url;
+                               break;
+                       }
+               }
 
                $existing = array_column(Tag::getByURIId($toUriId, [Tag::TO, Tag::CC, Tag::BCC]), 'url');
 
                foreach (Tag::getByURIId($fromUriId, [Tag::TO, Tag::CC, Tag::BCC]) as $receiver) {
                        if ($receiver['url'] == $from_author['ap-followers']) {
+                               if (!empty($followers)) {
+                                       $receiver['url']  = $followers;
+                                       $receiver['name'] = trim(parse_url($receiver['url'], PHP_URL_PATH), '/');
+                                       Tag::store($toUriId, $receiver['type'], $receiver['name'], $receiver['url']);
+                               }
                                $receiver['url']  = $to_author['ap-followers'];
                                $receiver['name'] = trim(parse_url($receiver['url'], PHP_URL_PATH), '/');
                        }
index 27fcfcdd9b1ffe373f239199af15dd4c0da010d3..0e741ce816ab10009489502eb0e6bbef3f0c6277 100644 (file)
@@ -1366,7 +1366,7 @@ class Item
                if ($notify) {
                        DI::contentItem()->postProcessPost($posted_item);
                        if ($copy_permissions && ($posted_item['thr-parent-id'] != $posted_item['uri-id']) && ($posted_item['private'] == self::PRIVATE)) {
-                               DI::contentItem()->copyPermissions($posted_item['thr-parent-id'], $posted_item['uri-id']);
+                               DI::contentItem()->copyPermissions($posted_item['thr-parent-id'], $posted_item['uri-id'], $posted_item['parent-uri-id']);
                        }
                } else {
                        Hook::callAll('post_remote_end', $posted_item);
@@ -3758,7 +3758,7 @@ class Item
                DI::profiler()->startRecording('rendering');
                $trailing = '';
                foreach ($PostMedias as $PostMedia) {
-                       if (strpos($item['body'], $PostMedia->url)) {
+                       if (strpos($item['body'], (string)$PostMedia->url)) {
                                continue;
                        }
 
index e6371a5975ce8958d73318518c197f3b293a1980..de3acfea915dd30c0aef8736b3acd32e4f8dd06f 100644 (file)
@@ -308,12 +308,13 @@ class Receiver
         * @param boolean $push           Message had been pushed to our system
         * @param boolean $trust_source   Do we trust the source?
         * @param string  $original_actor Actor of the original activity. Used for receiver detection. (Optional)
+        * @param string  $http_signer    Actor who has signed the HTTP request
         *
         * @return array with object data
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       public static function prepareObjectData(array $activity, int $uid, bool $push, bool &$trust_source, string $original_actor = ''): array
+       public static function prepareObjectData(array $activity, int $uid, bool $push, bool &$trust_source, string $original_actor = '', string $http_signer = ''): array
        {
                $id        = JsonLD::fetchElement($activity, '@id');
                $type      = JsonLD::fetchElement($activity, '@type');
@@ -332,7 +333,7 @@ class Receiver
                $fetched = false;
 
                if (!empty($id) && !$trust_source) {
-                       $fetch_uid = $uid ?: self::getBestUserForActivity($activity, $original_actor);
+                       $fetch_uid = $uid ?: self::getBestUserForActivity($activity, $original_actor, '');
 
                        $fetched_activity = Processor::fetchCachedActivity($fetch_id, $fetch_uid);
                        if (!empty($fetched_activity)) {
@@ -368,7 +369,7 @@ class Receiver
                $type = JsonLD::fetchElement($activity, '@type');
 
                // Fetch all receivers from to, cc, bto and bcc
-               $receiverdata = self::getReceivers($activity, $original_actor ?: $actor, [], false, $push || $fetched);
+               $receiverdata = self::getReceivers($activity, $original_actor ?: $actor, [], false, $push || $fetched, $http_signer);
                $receivers = $reception_types = [];
                foreach ($receiverdata as $key => $data) {
                        $receivers[$key] = $data['uid'];
@@ -392,7 +393,7 @@ class Receiver
 
                // We possibly need some user to fetch private content,
                // so we fetch one out of the receivers if no uid is provided.
-               $fetch_uid = $uid ?: self::getBestUserForActivity($activity, $original_actor);
+               $fetch_uid = $uid ?: self::getBestUserForActivity($activity, $original_actor, $http_signer);
 
                $object_id = JsonLD::fetchElement($activity, 'as:object', '@id');
                if (empty($object_id)) {
@@ -682,7 +683,7 @@ class Receiver
                }
 
                // $trust_source is called by reference and is set to true if the content was retrieved successfully
-               $object_data = self::prepareObjectData($activity, $uid, $push, $trust_source, $original_actor);
+               $object_data = self::prepareObjectData($activity, $uid, $push, $trust_source, $original_actor, $trust_source ? $http_signer : '');
                if (empty($object_data)) {
                        Logger::info('No object data found', ['activity' => $activity]);
                        return true;
@@ -1094,15 +1095,16 @@ class Receiver
         *
         * @param array  $activity
         * @param string $actor
+        * @param string $http_signer
         *
         * @return int   user id
         */
-       public static function getBestUserForActivity(array $activity, string $actor = ''): int
+       public static function getBestUserForActivity(array $activity, string $actor = '', string $http_signer): int
        {
                $uid = 0;
                $actor = $actor ?: JsonLD::fetchElement($activity, 'as:actor', '@id') ?? '';
 
-               $receivers = self::getReceivers($activity, $actor, [], false, false);
+               $receivers = self::getReceivers($activity, $actor, [], false, false, $http_signer);
                foreach ($receivers as $receiver) {
                        if ($receiver['type'] == self::TARGET_GLOBAL) {
                                return 0;
@@ -1157,11 +1159,12 @@ class Receiver
         * @param array  $tags
         * @param bool   $fetch_unlisted
         * @param bool   $push
+        * @param string $http_signer
         *
         * @return array with receivers (user id)
         * @throws \Exception
         */
-       private static function getReceivers(array $activity, string $actor, array $tags, bool $fetch_unlisted, bool $push): array
+       private static function getReceivers(array $activity, string $actor, array $tags, bool $fetch_unlisted, bool $push, string $http_signer): array
        {
                $reply = $receivers = $profile = [];
 
@@ -1200,6 +1203,13 @@ class Receiver
                // We have to prevent false follower assumptions upon thread completions
                $follower_target = empty($activity['thread-completion']) ? self::TARGET_FOLLOWER : self::TARGET_UNKNOWN;
 
+               if (($actor != $http_signer) && ($http_signer != '') && ($follower_target == self::TARGET_FOLLOWER)) {
+                       $signer_profile   = APContact::getByURL($http_signer);
+                       $signer_followers = $signer_profile['followers'] ?? '';
+               } else {
+                       $signer_followers = '';
+               }
+
                foreach (['as:to', 'as:cc', 'as:bto', 'as:bcc','as:audience'] as $element) {
                        $receiver_list = JsonLD::fetchElementArray($activity, $element, '@id');
                        if (empty($receiver_list)) {
@@ -1222,6 +1232,11 @@ class Receiver
                                        continue;
                                }
 
+                               if ($receiver == $signer_followers) {
+                                       $receivers = self::getReceiverForActor($http_signer, [], $receivers, $follower_target, $signer_profile);
+                                       continue;
+                               }
+
                                // Fetching all directly addressed receivers
                                $condition = ['self' => true, 'nurl' => Strings::normaliseLink($receiver)];
                                $contact = DBA::selectFirst('contact', ['uid', 'contact-type'], $condition);
@@ -1949,7 +1964,7 @@ class Receiver
 
                $object_data = self::getObjectDataFromActivity($object);
 
-               $receiverdata = self::getReceivers($object, $actor ?: $object_data['actor'] ?? '', $object_data['tags'], true, false);
+               $receiverdata = self::getReceivers($object, $actor ?: $object_data['actor'] ?? '', $object_data['tags'], true, false, '');
                $receivers = $reception_types = [];
                foreach ($receiverdata as $key => $data) {
                        $receivers[$key] = $data['uid'];