]> git.mxchange.org Git - friendica.git/commitdiff
The access to the profile and the list of followers/followings can now be restricted
authorMichael <heluecht@pirati.ca>
Fri, 21 Jul 2023 07:06:55 +0000 (07:06 +0000)
committerMichael <heluecht@pirati.ca>
Fri, 21 Jul 2023 07:06:55 +0000 (07:06 +0000)
src/Module/Profile/Profile.php
src/Protocol/ActivityPub.php
src/Protocol/ActivityPub/Transmitter.php

index 5e5028cb865f76c50a20b73162ce6f5378dae1d1..7ee953a6254c42a854c2bb496bf397c7dd30f145 100644 (file)
@@ -84,7 +84,7 @@ class Profile extends BaseProfile
                        $user = $this->database->selectFirst('user', ['uid'], ['nickname' => $this->parameters['nickname'] ?? '', 'account_removed' => false]);
                        if ($user) {
                                try {
-                                       $data = ActivityPub\Transmitter::getProfile($user['uid']);
+                                       $data = ActivityPub\Transmitter::getProfile($user['uid'], !ActivityPub::isAcceptedRequester($user['uid']));
                                        header('Access-Control-Allow-Origin: *');
                                        header('Cache-Control: max-age=23200, stale-while-revalidate=23200');
                                        System::jsonExit($data, 'application/activity+json');
index ad1e9367cad4df50aa47b4546878352477ad165c..4a1030eaab8f5fa9cf0b786ef4f5617aabc1ed3c 100644 (file)
@@ -23,10 +23,13 @@ namespace Friendica\Protocol;
 
 use Friendica\Core\Logger;
 use Friendica\Core\Protocol;
+use Friendica\Core\System;
 use Friendica\Model\APContact;
+use Friendica\Model\Contact;
 use Friendica\Model\User;
 use Friendica\Util\HTTPSignature;
 use Friendica\Util\JsonLD;
+use Friendica\Util\Network;
 
 /**
  * ActivityPub Protocol class
@@ -277,4 +280,44 @@ class ActivityPub
        {
                return !empty(APContact::getByURL($url, $update));
        }
+
+       public static function isAcceptedRequester(int $uid = 0): bool
+       {
+               $called_by = System::callstack(1);
+
+               $signer = HTTPSignature::getSigner('', $_SERVER);
+               if (!$signer) {
+                       Logger::debug('No signer', ['uid' => $uid, 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'called_by' => $called_by]);
+                       return false;
+               }
+
+               $apcontact = APContact::getByURL($signer);
+               if (empty($apcontact)) {
+                       Logger::debug('APContact not found', ['uid' => $uid, 'handle' => $signer, 'called_by' => $called_by]);
+                       return false;
+               }
+
+               if (empty($apcontact['gsid'] || empty($apcontact['baseurl']))) {
+                       Logger::debug('No server found', ['uid' => $uid, 'signer' => $signer, 'called_by' => $called_by]);
+                       return false;
+               }
+
+               // Check added as a precaution. It should not occur.
+               if (Network::isUrlBlocked($apcontact['baseurl'])) {
+                       Logger::info('Requesting domain is blocked', ['uid' => $uid, 'id' => $apcontact['gsid'], 'url' => $apcontact['baseurl'], 'signer' => $signer, 'called_by' => $called_by]);
+                       return false;
+               }
+
+               $contact = Contact::getByURL($signer, false, ['id', 'baseurl', 'gsid']);
+               if (!empty($contact) && Contact\User::isBlocked($contact['id'], $uid)) {
+                       Logger::info('Requesting contact is blocked', ['uid' => $uid, 'id' => $contact['id'], 'signer' => $signer, 'baseurl' => $contact['baseurl'], 'called_by' => $called_by]);
+                       return false;
+               }
+
+               // @todo Look for user blocked domains
+
+               Logger::debug('Server is an accepted requester', ['uid' => $uid, 'id' => $contact['gsid'], 'url' => $contact['baseurl'], 'signer' => $signer, 'called_by' => $called_by]);
+
+               return true;
+       }
 }
index 6c0cbd92b9cae04813e5c912331ace7501b7bc8d..bda202421be5a918604d4213e78911d6768878bc 100644 (file)
@@ -195,7 +195,7 @@ class Transmitter
                }
 
                // When we hide our friends we will only show the pure number but don't allow more.
-               $show_contacts = empty($owner['hide-friends']);
+               $show_contacts = ActivityPub::isAcceptedRequester($owner['uid']) && empty($owner['hide-friends']);
 
                // Allow fetching the contact list when the requester is part of the list.
                if (($owner['page-flags'] == User::PAGE_FLAGS_PRVGROUP) && !empty($requester)) {
@@ -337,12 +337,13 @@ class Transmitter
        /**
         * Return the ActivityPub profile of the given user
         *
-        * @param int $uid User ID
+        * @param int  $uid     User ID
+        * @param bool $limited If limited, only the basic information is returned
         * @return array with profile data
         * @throws HTTPException\NotFoundException
         * @throws HTTPException\InternalServerErrorException
         */
-       public static function getProfile(int $uid): array
+       public static function getProfile(int $uid, bool $limited = false): array
        {
                $owner = User::getOwnerDataById($uid);
                if (!isset($owner['id'])) {
@@ -372,16 +373,16 @@ class Transmitter
                $data['preferredUsername'] = $owner['nick'];
                $data['name'] = $owner['name'];
 
-               if (!empty($owner['country-name'] . $owner['region'] . $owner['locality'])) {
+               if (!$limited && !empty($owner['country-name'] . $owner['region'] . $owner['locality'])) {
                        $data['vcard:hasAddress'] = ['@type' => 'vcard:Home', 'vcard:country-name' => $owner['country-name'],
                                'vcard:region' => $owner['region'], 'vcard:locality' => $owner['locality']];
                }
 
-               if (!empty($owner['about'])) {
+               if (!$limited && !empty($owner['about'])) {
                        $data['summary'] = BBCode::convertForUriId($owner['uri-id'] ?? 0, $owner['about'], BBCode::EXTERNAL);
                }
 
-               if (!empty($owner['xmpp']) || !empty($owner['matrix'])) {
+               if (!$limited && (!empty($owner['xmpp']) || !empty($owner['matrix']))) {
                        $data['vcard:hasInstantMessage'] = [];
 
                        if (!empty($owner['xmpp'])) {
@@ -399,7 +400,7 @@ class Transmitter
                        'owner' => $owner['url'],
                        'publicKeyPem' => $owner['pubkey']];
                $data['endpoints'] = ['sharedInbox' => DI::baseUrl() . '/inbox'];
-               if ($uid != 0) {
+               if (!$limited && $uid != 0) {
                        $data['icon'] = ['type' => 'Image', 'url' => User::getAvatarUrl($owner)];
 
                        $resourceid = Photo::ridFromURI($owner['photo']);