]> git.mxchange.org Git - friendica.git/commitdiff
More rework to make private communities working
authorMichael <heluecht@pirati.ca>
Wed, 16 Feb 2022 22:56:55 +0000 (22:56 +0000)
committerMichael <heluecht@pirati.ca>
Wed, 16 Feb 2022 22:56:55 +0000 (22:56 +0000)
mod/settings.php
src/Model/Item.php
src/Module/ActivityPub/Objects.php
src/Protocol/ActivityPub/Receiver.php
src/Protocol/ActivityPub/Transmitter.php
src/Worker/Notifier.php
view/templates/settings/settings.tpl
view/theme/frio/templates/settings/settings.tpl

index 111e52330261d9c82084588f00b71e1d19a25d84..c18a36704cd32c25f922a146d66284402eabba20 100644 (file)
@@ -239,7 +239,6 @@ function settings_post(App $a)
        $allow_location   = ((!empty($_POST['allow_location']) && (intval($_POST['allow_location']) == 1)) ? 1: 0);
        $publish          = ((!empty($_POST['profile_in_directory']) && (intval($_POST['profile_in_directory']) == 1)) ? 1: 0);
        $net_publish      = ((!empty($_POST['profile_in_netdirectory']) && (intval($_POST['profile_in_netdirectory']) == 1)) ? 1: 0);
-       $old_visibility   = ((!empty($_POST['visibility']) && (intval($_POST['visibility']) == 1)) ? 1 : 0);
        $account_type     = ((!empty($_POST['account-type']) && (intval($_POST['account-type']))) ? intval($_POST['account-type']) : 0);
        $page_flags       = ((!empty($_POST['page-flags']) && (intval($_POST['page-flags']))) ? intval($_POST['page-flags']) : 0);
        $blockwall        = ((!empty($_POST['blockwall']) && (intval($_POST['blockwall']) == 1)) ? 0: 1); // this setting is inverted!
@@ -361,16 +360,21 @@ function settings_post(App $a)
        DI::pConfig()->set(local_user(), 'system', 'unlisted', $unlisted);
        DI::pConfig()->set(local_user(), 'system', 'accessible-photos', $accessiblephotos);
 
+       if ($account_type == User::ACCOUNT_TYPE_COMMUNITY) {
+               $str_group_allow   = '';
+               $str_contact_allow = '';
+               $str_group_deny    = '';
+               $str_contact_deny  = '';
+
+               DI::pConfig()->set(local_user(), 'system', 'unlisted', true);
+
+               $blockwall    = true;
+               $blocktags    = true;
+               $hide_friends = true;
+       }
+
        if ($page_flags == User::PAGE_FLAGS_PRVGROUP) {
-               $hidewall = 1;
-               if (!$str_contact_allow && !$str_group_allow && !$str_contact_deny && !$str_group_deny) {
-                       if ($def_gid) {
-                               info(DI::l10n()->t('Private forum has no privacy permissions. Using default privacy group.'));
-                               $str_group_allow = '<' . $def_gid . '>';
-                       } else {
-                               notice(DI::l10n()->t('Private forum has no privacy permissions and no default privacy group.'));
-                       }
-               }
+               $str_group_allow = '<' . Group::FOLLOWERS . '>';
        }
 
        $fields = ['username' => $username, 'email' => $email, 'timezone' => $timezone,
@@ -756,7 +760,7 @@ function settings_content(App $a)
                '$allowloc' => ['allow_location', DI::l10n()->t('Use Browser Location:'), ($user['allow_location'] == 1), ''],
 
                '$h_prv'                  => DI::l10n()->t('Security and Privacy Settings'),
-               '$visibility'         => $profile['net-publish'],
+               '$is_community'       => ($user['account-type'] == User::ACCOUNT_TYPE_COMMUNITY),
                '$maxreq'                 => ['maxreq', DI::l10n()->t('Maximum Friend Requests/Day:'), $maxreq , DI::l10n()->t("\x28to prevent spam abuse\x29")],
                '$profile_in_dir'     => $profile_in_dir,
                '$profile_in_net_dir' => ['profile_in_netdirectory', DI::l10n()->t('Allow your profile to be searchable globally?'), $profile['net-publish'], DI::l10n()->t("Activate this setting if you want others to easily find and follow you. Your profile will be searchable on remote systems. This setting also determines whether Friendica will inform search engines that your profile should be indexed or not.") . $net_pub_desc],
index 69a967b2c4be923b2943c8e1f7ba9a1277b9dbee..318a8ab511e33052acde5b802bec66e10d8d4fdd 100644 (file)
@@ -1994,10 +1994,8 @@ class Item
                Logger::info('Community post will be distributed', ['uri' => $item['uri'], 'uid' => $uid, 'id' => $item_id, 'uri-id' => $item['uri-id'], 'guid' => $item['guid']]);
 
                if ($owner['page-flags'] == User::PAGE_FLAGS_PRVGROUP) {
-                       Group::getMembersForForum($owner['id']);
-
-                       $allow_cid = '<' . $owner['id'] . '>';
-                       $allow_gid = '<' . Group::getIdForForum($owner['id']) . '>';
+                       $allow_cid = '';
+                       $allow_gid = '<' . Group::FOLLOWERS . '>';
                        $deny_cid  = '';
                        $deny_gid  = '';
                        self::performActivity($item['id'], 'announce', $uid, $allow_cid, $allow_gid, $deny_cid, $deny_gid);
@@ -3210,30 +3208,20 @@ class Item
        }
 
        /**
-        * Is the given item array a post that is sent as starting post to a forum?
+        * Does the given uri-id belongs to a post that is sent as starting post to a forum?
         *
-        * @param array $item
-        * @param array $owner
+        * @param int $uri_id
         *
         * @return boolean "true" when it is a forum post
         */
-       public static function isForumPost(array $item, array $owner = [])
+       public static function isForumPost(int $uri_id)
        {
-               if (empty($owner)) {
-                       $owner = User::getOwnerDataById($item['uid']);
-                       if (empty($owner)) {
-                               return false;
+               foreach (Tag::getByURIId($uri_id, [Tag::EXCLUSIVE_MENTION]) as $tag) {
+                       if (DBA::exists('contact', ['uid' => 0, 'nurl' => Strings::normaliseLink($tag['url']), 'contact-type' => Contact::TYPE_COMMUNITY])) {
+                               return true;
                        }
                }
-
-               if (($item['author-id'] == $item['owner-id']) ||
-                       ($owner['id'] == $item['contact-id']) ||
-                       ($item['uri-id'] != $item['parent-uri-id']) ||
-                       $item['origin']) {
-                       return false;
-               }
-
-               return Contact::isForum($item['contact-id']);
+               return false;
        }
 
        /**
index 0a523ea435471079021f64906fcac793f3824157..f3a37b7dadc9eaadf387e4d941b4bcab1b9b361b 100644 (file)
@@ -81,6 +81,7 @@ class Objects extends BaseModule
                        $requester = HTTPSignature::getSigner('', $_SERVER);
                        if (!empty($requester)) {
                                $receivers = Item::enumeratePermissions($item, false);
+                               $receivers[] = $item['contact-id'];
 
                                $validated = in_array(Contact::getIdForURL($requester, $item['uid']), $receivers);
                                if (!$validated) {
index 7f08410f69eda22f63982ff450af4fadad20813e..003cae0c9f9a444a3aabd85221538c032963f964 100644 (file)
@@ -667,6 +667,15 @@ class Receiver
                                $uid = $receiver['uid'];
                        }
                }
+
+               // When we haven't found any user yet, we just chose a user who most likely could have access to the content
+               if (empty($uid)) {
+                       $contact = Contact::selectFirst(['uid'], ['nurl' => Strings::normaliseLink($actor), 'rel' => [Contact::SHARING, Contact::FRIEND]]);
+                       if (!empty($contact['uid'])) {
+                               $uid = $contact['uid'];
+                       }
+               }
+
                return $uid;
        }
 
index 7be55898c8488ff6de86bd122831cc889cb69674..884f9430f102762d1cacc52960b0b5e349978122 100644 (file)
@@ -509,28 +509,33 @@ class Transmitter
        /**
         * Creates an array of permissions from an item thread
         *
-        * @param array   $item       Item array
-        * @param boolean $blindcopy  addressing via "bcc" or "cc"?
-        * @param integer $last_id    Last item id for adding receivers
-        * @param boolean $forum_post "true" means that we are sending content to a forum
+        * @param array   $item      Item array
+        * @param boolean $blindcopy addressing via "bcc" or "cc"?
+        * @param integer $last_id   Last item id for adding receivers
         *
         * @return array with permission data
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       private static function createPermissionBlockForItem($item, $blindcopy, $last_id = 0, $forum_post = false)
+       private static function createPermissionBlockForItem($item, $blindcopy, $last_id = 0)
        {
                if ($last_id == 0) {
                        $last_id = $item['id'];
                }
 
                $always_bcc = false;
+               $is_forum   = false;
+               $follower   = '';
 
                // Check if we should always deliver our stuff via BCC
                if (!empty($item['uid'])) {
-                       $profile = User::getOwnerDataById($item['uid']);
-                       if (!empty($profile)) {
-                               $always_bcc = $profile['hide-friends'];
+                       $owner = User::getOwnerDataById($item['uid']);
+                       if (!empty($owner)) {
+                               $always_bcc = $owner['hide-friends'];
+                               $is_forum   = ($owner['account-type'] == User::ACCOUNT_TYPE_COMMUNITY) && $owner['manually-approve'];
+
+                               $profile  = APContact::getByURL($owner['url'], false);
+                               $follower = $profile['followers'] ?? '';
                        }
                }
 
@@ -613,7 +618,9 @@ class Transmitter
                                }
                        }
 
-                       if (!$exclusive) {
+                       if ($is_forum && !$exclusive && !empty($follower)) {
+                               $data['cc'][] = $follower;
+                       } elseif (!$exclusive) {
                                foreach ($receiver_list as $receiver) {
                                        $contact = DBA::selectFirst('contact', ['url', 'hidden', 'network', 'protocol', 'gsid'], ['id' => $receiver, 'network' => Protocol::FEDERATED]);
                                        if (!DBA::isResult($contact) || !self::isAPContact($contact, $networks)) {
@@ -652,9 +659,7 @@ class Transmitter
                                                        }
                                                } elseif (!$exclusive) {
                                                        // Public thread parent post always are directed to the followers.
-                                                       // This mustn't be done by posts that are directed to forum servers via the exclusive mention.
-                                                       // But possibly in that case we could add the "followers" collection of the forum to the message.
-                                                       if (($item['private'] != Item::PRIVATE) && !$forum_post) {
+                                                       if ($item['private'] != Item::PRIVATE) {
                                                                $data['cc'][] = $actor_profile['followers'];
                                                        }
                                                }
@@ -820,18 +825,17 @@ class Transmitter
        /**
         * Fetches an array of inboxes for the given item and user
         *
-        * @param array   $item       Item array
-        * @param integer $uid        User ID
-        * @param boolean $personal   fetch personal inboxes
-        * @param integer $last_id    Last item id for adding receivers
-        * @param boolean $forum_post "true" means that we are sending content to a forum
+        * @param array   $item     Item array
+        * @param integer $uid      User ID
+        * @param boolean $personal fetch personal inboxes
+        * @param integer $last_id  Last item id for adding receivers
         * @return array with inboxes
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       public static function fetchTargetInboxes($item, $uid, $personal = false, $last_id = 0, $forum_post = false)
+       public static function fetchTargetInboxes($item, $uid, $personal = false, $last_id = 0)
        {
-               $permissions = self::createPermissionBlockForItem($item, true, $last_id, $forum_post);
+               $permissions = self::createPermissionBlockForItem($item, true, $last_id);
                if (empty($permissions)) {
                        return [];
                }
index 3a5c7f13e17f29a87cd4b5f6a43aeb26dd8ec207..f79b466377d2db5ddeeb2ea7f9a04219130132b0 100644 (file)
@@ -235,13 +235,13 @@ class Notifier
                        }
 
                        // Special treatment for forum posts
-                       if (Item::isForumPost($target_item, $owner)) {
+                       if (Item::isForumPost($target_item['uri-id'])) {
                                $relay_to_owner = true;
                                $direct_forum_delivery = true;
                        }
 
                        // Avoid that comments in a forum thread are sent to OStatus
-                       if (Item::isForumPost($parent, $owner)) {
+                       if (Item::isForumPost($parent['uri-id'])) {
                                $direct_forum_delivery = true;
                        }
 
@@ -729,6 +729,14 @@ class Notifier
 
                $uid = $target_item['contact-uid'] ?: $target_item['uid'];
 
+               // Update the locally stored follower list when we deliver to a forum
+               foreach (Tag::getByURIId($target_item['uri-id'], [Tag::EXCLUSIVE_MENTION]) as $tag) {
+                       $target_contact = Contact::getByURL(Strings::normaliseLink($tag['url']), null, [], $uid);
+                       if (($target_contact['contact-type'] == Contact::TYPE_COMMUNITY) && $target_contact['manually-approve']) {
+                               Group::getMembersForForum($target_contact['id']);
+                       }
+               }
+
                if ($target_item['origin']) {
                        $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($target_item, $uid);
 
@@ -738,9 +746,6 @@ class Notifier
                        }
 
                        Logger::info('Origin item ' . $target_item['id'] . ' with URL ' . $target_item['uri'] . ' will be distributed.');
-               } elseif (Item::isForumPost($target_item, $owner)) {
-                       $inboxes = ActivityPub\Transmitter::fetchTargetInboxes($target_item, $uid, false, 0, true);
-                       Logger::info('Forum item ' . $target_item['id'] . ' with URL ' . $target_item['uri'] . ' will be distributed.');
                } elseif (!DBA::exists('conversation', ['item-uri' => $target_item['uri'], 'protocol' => Conversation::PARCEL_ACTIVITYPUB])) {
                        Logger::info('Remote item ' . $target_item['id'] . ' with URL ' . $target_item['uri'] . ' is no AP post. It will not be distributed.');
                        return ['count' => 0, 'contacts' => []];
index c2ed1a9424be92899ba96adacd97ebdae1a37f2a..c0e821ac7cb51763d82fca630f2be399200f4964 100644 (file)
 
        <h2 class="settings-heading"><a href="javascript:;">{{$h_prv}}</a></h2>
        <div class="settings-content-block">
-
-               <input type="hidden" name="visibility" value="{{$visibility}}"/>
-
                {{include file="field_input.tpl" field=$maxreq}}
 
                {{$profile_in_dir nofilter}}
 
                {{include file="field_checkbox.tpl" field=$profile_in_net_dir}}
-               {{include file="field_checkbox.tpl" field=$hide_friends}}
+               {{if not $is_community}}{{include file="field_checkbox.tpl" field=$hide_friends}}{{/if}}
                {{include file="field_checkbox.tpl" field=$hide_wall}}
-               {{include file="field_checkbox.tpl" field=$unlisted}}
+               {{if not $is_community}}{{include file="field_checkbox.tpl" field=$unlisted}}{{/if}}
                {{include file="field_checkbox.tpl" field=$accessiblephotos}}
+               {{if not $is_community}}
                {{include file="field_checkbox.tpl" field=$blockwall}}
                {{include file="field_checkbox.tpl" field=$blocktags}}
+               {{/if}}
                {{include file="field_checkbox.tpl" field=$unkmail}}
                {{include file="field_input.tpl" field=$cntunkmail}}
 
                {{$group_select nofilter}}
-
+               {{if not $is_community}}
                <h3>{{$permissions}}</h3>
 
                {{$aclselect nofilter}}
+               {{/if}}
                <div class="settings-submit-wrapper">
                        <input type="submit" name="submit" class="settings-submit" value="{{$submit}}"/>
                </div>
index bf129cc12ea78ff04246190734bc668d09dd2bfb..b9e105e8860607a37477800d4583397e0d3e75e5 100644 (file)
                                </div>
                                <div id="privacy-settings-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="privacy-settings">
                                        <div class="panel-body">
-
-                                               <input type="hidden" name="visibility" value="{{$visibility}}" />
-
                                                {{include file="field_input.tpl" field=$maxreq}}
 
                                                {{$profile_in_dir nofilter}}
 
                                                {{include file="field_checkbox.tpl" field=$profile_in_net_dir}}
-                                               {{include file="field_checkbox.tpl" field=$hide_friends}}
+                                               {{if not $is_community}}{{include file="field_checkbox.tpl" field=$hide_friends}}{{/if}}
                                                {{include file="field_checkbox.tpl" field=$hide_wall}}
-                                               {{include file="field_checkbox.tpl" field=$unlisted}}
+                                               {{if not $is_community}}{{include file="field_checkbox.tpl" field=$unlisted}}{{/if}}
                                                {{include file="field_checkbox.tpl" field=$accessiblephotos}}
+                                               {{if not $is_community}}
                                                {{include file="field_checkbox.tpl" field=$blockwall}}
                                                {{include file="field_checkbox.tpl" field=$blocktags}}
+                                               {{/if}}
                                                {{include file="field_checkbox.tpl" field=$unkmail}}
                                                {{include file="field_input.tpl" field=$cntunkmail}}
 
                                                {{$group_select nofilter}}
 
+                                               {{if not $is_community}}
                                                <h3>{{$permissions}}</h3>
 
                                                {{$aclselect nofilter}}
+                                               {{/if}}
                                        </div>
                                        <div class="panel-footer">
                                                <button type="submit" name="submit" class="btn btn-primary" value="{{$submit}}">{{$submit}}</button>