diff --git a/boot.php b/boot.php index 64741b1762..6be5f3aecb 100644 --- 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', 1284); +define('DB_UPDATE_VERSION', 1285); define('NEW_UPDATE_ROUTINE_VERSION', 1170); /** diff --git a/config/dbstructure.json b/config/dbstructure.json index 8f67686156..443f9bd755 100644 --- a/config/dbstructure.json +++ b/config/dbstructure.json @@ -192,6 +192,7 @@ "hidden": {"type": "boolean", "not null": "1", "default": "0", "comment": ""}, "archive": {"type": "boolean", "not null": "1", "default": "0", "comment": ""}, "pending": {"type": "boolean", "not null": "1", "default": "1", "comment": ""}, + "deleted": {"type": "boolean", "not null": "1", "default": "0", "comment": "Contact has been deleted"}, "rating": {"type": "tinyint", "not null": "1", "default": "0", "comment": ""}, "reason": {"type": "text", "comment": ""}, "closeness": {"type": "tinyint unsigned", "not null": "1", "default": "99", "comment": ""}, diff --git a/database.sql b/database.sql index a797c8df36..341ee5a858 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ -- Friendica 2018.12-dev (The Tazmans Flax-lily) --- DB_UPDATE_VERSION 1284 +-- DB_UPDATE_VERSION 1285 -- ------------------------------------------ @@ -189,6 +189,7 @@ CREATE TABLE IF NOT EXISTS `contact` ( `hidden` boolean NOT NULL DEFAULT '0' COMMENT '', `archive` boolean NOT NULL DEFAULT '0' COMMENT '', `pending` boolean NOT NULL DEFAULT '1' COMMENT '', + `deleted` boolean NOT NULL DEFAULT '0' COMMENT 'Contact has been deleted', `rating` tinyint NOT NULL DEFAULT 0 COMMENT '', `reason` text COMMENT '', `closeness` tinyint unsigned NOT NULL DEFAULT 99 COMMENT '', diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 23c31d0b17..f1260c7c44 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -521,7 +521,7 @@ class Contact extends BaseObject } // Archive the contact - DBA::update('contact', ['archive' => true, 'network' => Protocol::PHANTOM], ['id' => $id]); + DBA::update('contact', ['archive' => true, 'network' => Protocol::PHANTOM, 'deleted' => true], ['id' => $id]); // Delete it in the background Worker::add(PRIORITY_LOW, 'RemoveContact', $id); @@ -825,7 +825,7 @@ class Contact extends BaseObject // Fetch contact data from the contact table for the given user $r = q("SELECT `id`, `id` AS `cid`, 0 AS `gid`, 0 AS `zid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`, `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, `self` - FROM `contact` WHERE `addr` = '%s' AND `uid` = %d", + FROM `contact` WHERE `addr` = '%s' AND `uid` = %d AND NOT `deleted`", DBA::escape($addr), intval($uid) ); @@ -833,7 +833,7 @@ class Contact extends BaseObject if (!DBA::isResult($r)) { $r = q("SELECT `id`, 0 AS `cid`, `id` AS `zid`, 0 AS `gid`, `uid`, `url`, `nurl`, `alias`, `network`, `name`, `nick`, `addr`, `location`, `about`, `xmpp`, `keywords`, `gender`, `photo`, `thumb`, `micro`, `forum`, `prv`, (`forum` | `prv`) AS `community`, `contact-type`, `bd` AS `birthday`, 0 AS `self` - FROM `contact` WHERE `addr` = '%s' AND `uid` = 0", + FROM `contact` WHERE `addr` = '%s' AND `uid` = 0 AND NOT `deleted`", DBA::escape($addr) ); } @@ -1036,18 +1036,18 @@ class Contact extends BaseObject /// @todo Verify if we can't use Contact::getDetailsByUrl instead of the following // We first try the nurl (http://server.tld/nick), most common case - $contact = DBA::selectFirst('contact', ['id', 'avatar', 'avatar-date'], ['nurl' => normalise_link($url), 'uid' => $uid]); + $contact = DBA::selectFirst('contact', ['id', 'avatar', 'avatar-date'], ['nurl' => normalise_link($url), 'uid' => $uid, 'deleted' => false]); // Then the addr (nick@server.tld) if (!DBA::isResult($contact)) { - $contact = DBA::selectFirst('contact', ['id', 'avatar', 'avatar-date'], ['addr' => $url, 'uid' => $uid]); + $contact = DBA::selectFirst('contact', ['id', 'avatar', 'avatar-date'], ['addr' => $url, 'uid' => $uid, 'deleted' => false]); } // Then the alias (which could be anything) if (!DBA::isResult($contact)) { // The link could be provided as http although we stored it as https $ssl_url = str_replace('http://', 'https://', $url); - $condition = ['`alias` IN (?, ?, ?) AND `uid` = ?', $url, normalise_link($url), $ssl_url, $uid]; + $condition = ['`alias` IN (?, ?, ?) AND `uid` = ? AND NOT `deleted`', $url, normalise_link($url), $ssl_url, $uid]; $contact = DBA::selectFirst('contact', ['id', 'avatar', 'avatar-date'], $condition); } @@ -1515,7 +1515,7 @@ class Contact extends BaseObject $ret = Probe::uri($contact["url"], $network); // If Probe::uri fails the network code will be different - if (($ret["network"] != $contact["network"]) && ($ret["network"] != $network)) { + if (($ret["network"] != $contact["network"]) && !in_array($ret["network"], [Protocol::ACTIVITYPUB, $network])) { return false; } diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 166530f472..bfc5e6d084 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -298,6 +298,9 @@ class Processor $item = ['author-id' => Contact::getIdForURL($activity['actor']), 'author-link' => $activity['actor']]; + // Ensure that the contact has got the right network type + self::switchContact($item['author-id']); + Contact::addRelationship($owner, $contact, $item); $cid = Contact::getIdForURL($activity['actor'], $uid); if (empty($cid)) { diff --git a/src/Protocol/ActivityPub/Receiver.php b/src/Protocol/ActivityPub/Receiver.php index f54503708b..12edf3f06b 100644 --- a/src/Protocol/ActivityPub/Receiver.php +++ b/src/Protocol/ActivityPub/Receiver.php @@ -452,7 +452,7 @@ class Receiver * @param integer $uid User ID * @param string $url Profile URL */ - private static function switchContact($cid, $uid, $url) + public static function switchContact($cid, $uid, $url) { $profile = ActivityPub::probeProfile($url); if (empty($profile)) { diff --git a/src/Worker/OnePoll.php b/src/Worker/OnePoll.php index a68ad1336d..3c16af75f8 100644 --- a/src/Worker/OnePoll.php +++ b/src/Worker/OnePoll.php @@ -13,6 +13,7 @@ use Friendica\Database\DBA; use Friendica\Model\Contact; use Friendica\Model\Item; use Friendica\Protocol\Email; +use Friendica\Protocol\ActivityPub; use Friendica\Protocol\PortableContact; use Friendica\Util\DateTimeFormat; use Friendica\Util\Network; @@ -55,6 +56,17 @@ class OnePoll $importer_uid = $contact['uid']; + // Possibly switch the remote contact to AP + if ($contact['network'] === Protocol::OSTATUS) { + ActivityPub\Receiver::switchContact($contact['id'], $importer_uid, $contact['url']); + $contact = DBA::selectFirst('contact', [], ['id' => $contact_id]); + } + + // We currently don't do anything with AP here + if ($contact['network'] === Protocol::ACTIVITYPUB) { + return; + } + // load current friends if possible. if (($contact['poco'] != "") && ($contact['success_update'] > $contact['failure_update'])) { $r = q("SELECT count(*) AS total FROM glink