]> git.mxchange.org Git - friendica.git/commitdiff
Delete removed contacts
authorMichael <heluecht@pirati.ca>
Tue, 15 Dec 2020 22:56:46 +0000 (22:56 +0000)
committerMichael <heluecht@pirati.ca>
Tue, 15 Dec 2020 22:56:46 +0000 (22:56 +0000)
src/Model/APContact.php
src/Model/Contact.php
src/Model/User.php
src/Module/Proxy.php
src/Protocol/ActivityPub.php
src/Util/HTTPSignature.php
src/Worker/RemoveContact.php

index 37faf240ce1bc5efcf22826e7a4b5ba1b86c3cdf..68e81072e661f15b149082561c5fa05d99cd1a80 100644 (file)
@@ -147,14 +147,25 @@ class APContact
                        $url = $apcontact['url'];
                }
 
-               $data = ActivityPub::fetchContent($url);
-               if (empty($data)) {
+               $curlResult = HTTPSignature::fetchRaw($url);
+               $failed = empty($curlResult) || empty($curlResult->getBody()) ||
+                       (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410));
+
+               if (!$failed) {
+                       $data = json_decode($curlResult->getBody(), true);
+                       $failed = empty($data) || !is_array($data);
+               }
+
+               if (!$failed && ($curlResult->getReturnCode() == 410)) {
+                       $data = ['@context' => ActivityPub::CONTEXT, 'id' => $url, 'type' => 'Tombstone'];
+               }
+
+               if ($failed) {
                        self::markForArchival($fetched_contact ?: []);
                        return $fetched_contact;
                }
 
                $compacted = JsonLD::compact($data);
-
                if (empty($compacted['@id'])) {
                        return $fetched_contact;
                }
@@ -207,8 +218,11 @@ class APContact
                }
 
                // Quit if none of the basic values are set
-               if (empty($apcontact['url']) || empty($apcontact['inbox']) || empty($apcontact['type'])) {
+               if (empty($apcontact['url']) || empty($apcontact['type']) || (($apcontact['type'] != 'Tombstone') && empty($apcontact['inbox']))) {
                        return $fetched_contact;
+               } elseif ($apcontact['type'] == 'Tombstone') {
+                       // The "inbox" field must have a content
+                       $apcontact['inbox'] = '';
                }
 
                // Quit if this doesn't seem to be an account at all
index df21796c18ac423ba7f2300e51b8273f9cf79af2..2908385f583e06430ebe775a754740c652bf9db6 100644 (file)
@@ -724,7 +724,7 @@ class Contact
        {
                // We want just to make sure that we don't delete our "self" contact
                $contact = DBA::selectFirst('contact', ['uid'], ['id' => $id, 'self' => false]);
-               if (!DBA::isResult($contact) || !intval($contact['uid'])) {
+               if (!DBA::isResult($contact)) {
                        return;
                }
 
@@ -1762,6 +1762,17 @@ class Contact
                DBA::update('contact', $fields, ['id' => $cids]);
        }
 
+       public static function deleteContactByUrl(string $url)
+       {
+               // Update contact data for all users
+               $condition = ['self' => false, 'nurl' => Strings::normaliseLink($url)];
+               $contacts = DBA::select('contact', ['id', 'uid'], $condition);
+               while ($contact = DBA::fetch($contacts)) {
+                       Logger::info('Deleting contact', ['id' => $contact['id'], 'uid' => $contact['uid'], 'url' => $url]);
+                       self::remove($contact['id']);
+               }
+       }
+
        /**
         * Helper function for "updateFromProbe". Updates personal and public contact
         *
@@ -1914,6 +1925,15 @@ class Contact
                        return false;
                }
 
+               if (!empty($ret['account-type']) && $ret['account-type'] == User::ACCOUNT_TYPE_DELETED) {
+                       Logger::info('Deleted account', ['id' => $id, 'url' => $ret['url'], 'ret' => $ret]);
+                       self::remove($id);
+
+                       // Delete all contacts with the same URL
+                       self::deleteContactByUrl($ret['url']);
+                       return true;
+               }
+
                $uid = $contact['uid'];
                unset($contact['uid']);
 
index bcd555a0ec11c46a8b1bbc6cc858074c22b67c62..96a5bbfbcf7ecca9131766c36d05ed62568aeff1 100644 (file)
@@ -97,6 +97,7 @@ class User
        const ACCOUNT_TYPE_NEWS =         2;
        const ACCOUNT_TYPE_COMMUNITY =    3;
        const ACCOUNT_TYPE_RELAY =        4;
+       const ACCOUNT_TYPE_DELETED =    127;
        /**
         * @}
         */
index e1231f0b13ab1d5cffabb5074706a50e480533a4..f20b13bcef88e972a27cc4414f1627ef65039d2a 100644 (file)
@@ -104,7 +104,7 @@ class Proxy extends BaseModule
 
                // It shouldn't happen but it does - spaces in URL
                $request['url'] = str_replace(' ', '+', $request['url']);
-               $fetchResult = HTTPSignature::fetchRaw($request['url'], local_user(), true, ['timeout' => 10]);
+               $fetchResult = HTTPSignature::fetchRaw($request['url'], local_user(), ['timeout' => 10]);
                $img_str = $fetchResult->getBody();
 
                // If there is an error then return a blank image
index 19eb8c8bce1159e1622ae8ac9145527c42c6a257..5cbaf92357fcd86f9a04333a38df1d08d8d4020d 100644 (file)
@@ -68,7 +68,7 @@ class ActivityPub
                'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers',
                'sensitive' => 'as:sensitive', 'Hashtag' => 'as:Hashtag',
                'directMessage' => 'litepub:directMessage']];
-       const ACCOUNT_TYPES = ['Person', 'Organization', 'Service', 'Group', 'Application'];
+       const ACCOUNT_TYPES = ['Person', 'Organization', 'Service', 'Group', 'Application', 'Tombstone'];
        /**
         * Checks if the web request is done for the AP protocol
         *
@@ -113,7 +113,10 @@ class ActivityPub
                        case 'Application':
                                $accounttype = User::ACCOUNT_TYPE_RELAY;
                                break;
-               }
+                       case 'Tombstone':
+                               $accounttype = User::ACCOUNT_TYPE_DELETED;
+                               break;
+                       }
 
                return $accounttype;
        }
index 5b7bb02a3ec9252ec1082355da352c18a04ad929..1ede550885a27117f86f089517dd749b151be270 100644 (file)
@@ -376,8 +376,7 @@ class HTTPSignature
         */
        public static function fetch($request, $uid)
        {
-               $opts = ['accept_content' => 'application/activity+json, application/ld+json'];
-               $curlResult = self::fetchRaw($request, $uid, false, $opts);
+               $curlResult = self::fetchRaw($request, $uid);
 
                if (empty($curlResult)) {
                        return false;
@@ -410,7 +409,7 @@ class HTTPSignature
         * @return object CurlResult
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
-       public static function fetchRaw($request, $uid = 0, $binary = false, $opts = [])
+       public static function fetchRaw($request, $uid = 0, $opts = ['accept_content' => 'application/activity+json, application/ld+json'])
        {
                $header = [];
 
index 05771e2dc5c0ee5d1e494bcb5bfc552160df8711..a84cb0d53760701f9eb9a825b5a24c22fbf3255d 100644 (file)
@@ -31,15 +31,21 @@ use Friendica\Model\Photo;
  */
 class RemoveContact {
        public static function execute($id) {
-
                // Only delete if the contact is to be deleted
                $contact = DBA::selectFirst('contact', ['uid'], ['deleted' => true, 'id' => $id]);
                if (!DBA::isResult($contact)) {
                        return;
                }
 
+               Logger::info('Start deleting contact', ['id' => $id]);
                // Now we delete the contact and all depending tables
-               $condition = ['uid' => $contact['uid'], 'contact-id' => $id];
+               if ($contact['uid'] == 0) {
+                       DBA::delete('post-tag', ['cid' => $id]);
+                       $condition = ["`author-id` = ? OR `owner-id` = ? OR `causer-id` = ? OR `contact-id` = ?",
+                               $id, $id, $id, $id];
+               } else {
+                       $condition = ['uid' => $contact['uid'], 'contact-id' => $id];
+               }
                do {
                        $items = Item::select(['id', 'guid'], $condition, ['limit' => 100]);
                        while ($item = Item::fetch($items)) {
@@ -49,7 +55,8 @@ class RemoveContact {
                        DBA::close($items);
                } while (Item::exists($condition));
 
-               Photo::delete(['uid' => $contact['uid'], 'contact-id' => $id]);
-               DBA::delete('contact', ['id' => $id]);
+               Photo::delete(['contact-id' => $id]);
+               $ret = DBA::delete('contact', ['id' => $id]);
+               Logger::info('Deleted contact', ['id' => $id, 'result' => $ret]);
        }
 }