From aa4945f4a01ae2a5d227afca5a51a5590aca81e4 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 04:01:04 +0000 Subject: [PATCH 1/8] "x-social-relay" now exposes all supported protocols --- mod/_well_known.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mod/_well_known.php b/mod/_well_known.php index c5bee3fdad..782dc7a1b1 100644 --- a/mod/_well_known.php +++ b/mod/_well_known.php @@ -70,9 +70,11 @@ function wk_social_relay() } $relay = [ - "subscribe" => $subscribe, - "scope" => $scope, - "tags" => $taglist + 'subscribe' => $subscribe, + 'scope' => $scope, + 'tags' => $taglist, + 'protocols' => ['diaspora' => System::baseUrl() . '/receive/public', + 'dfrn' => System::baseUrl() . '/dfrn_notify'] ]; header('Content-type: application/json; charset=utf-8'); From d0dd5c44d94fae93989fdcaf8986fdddeacb09e1 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 05:33:47 +0000 Subject: [PATCH 2/8] Update or create relay contact from discovery / process new protocol values --- src/Protocol/Diaspora.php | 55 +++++++++++++++++--------------- src/Protocol/PortableContact.php | 15 +++++++++ 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index f4a649b51c..b25809a0e5 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -134,55 +134,58 @@ class Diaspora */ private static function getRelayContact($server_url) { - $batch = $server_url . '/receive/public'; - $fields = ['batch', 'id', 'name', 'network', 'archive', 'blocked']; // Fetch the relay contact - $condition = ['uid' => 0, 'network' => NETWORK_DIASPORA, 'batch' => $batch, + $condition = ['uid' => 0, 'nurl' => normalise_link($server_url), 'contact-type' => ACCOUNT_TYPE_RELAY]; $contact = dba::selectFirst('contact', $fields, $condition); - // If there is nothing found, we check if there is some unmarked relay - // This code segment can be removed before the release 2018-05 - if (!DBM::is_result($contact)) { - $condition = ['uid' => 0, 'network' => NETWORK_DIASPORA, 'batch' => $batch, - 'name' => 'relay', 'nick' => 'relay', 'url' => $server_url]; - $contact = dba::selectFirst('contact', $fields, $condition); - - if (DBM::is_result($contact)) { - // Mark the relay account as a relay account - $fields = ['contact-type' => ACCOUNT_TYPE_RELAY]; - dba::update('contact', $fields, ['id' => $contact['id']]); - } - } if (DBM::is_result($contact)) { if ($contact['archive'] || $contact['blocked']) { return false; } return $contact; } else { - $fields = ['uid' => 0, 'created' => DateTimeFormat::utcNow(), - 'name' => 'relay', 'nick' => 'relay', - 'url' => $server_url, 'nurl' => normalise_link($server_url), - 'batch' => $batch, 'network' => NETWORK_DIASPORA, - 'rel' => CONTACT_IS_FOLLOWER, 'blocked' => false, - 'contact-type' => ACCOUNT_TYPE_RELAY, - 'pending' => false, 'writable' => true]; - dba::insert('contact', $fields); + self::setRelayContact($server_url); - $fields = ['batch', 'id', 'name', 'network']; $contact = dba::selectFirst('contact', $fields, $condition); if (DBM::is_result($contact)) { return $contact; } - } // It should never happen that we arrive here return []; } + /** + * @brief Update or insert a relay contact + * + * @param string $server_url The url of the server + * @param array $network_fields Optional network specific fields + */ + public static function setRelayContact($server_url, $network_fields = []) + { + $fields = ['created' => DateTimeFormat::utcNow(), + 'name' => 'relay', 'nick' => 'relay', + 'url' => $server_url, 'network' => NETWORK_DIASPORA, + 'batch' => $server_url . '/receive/public', + 'rel' => CONTACT_IS_FOLLOWER, 'blocked' => false, + 'pending' => false, 'writable' => true]; + + $fields = array_merge($fields, $network_fields); + + $condition = ['uid' => 0, 'nurl' => normalise_link($server_url), + 'contact-type' => ACCOUNT_TYPE_RELAY]; + + if (dba::exists('contact', $condition)) { + unset($fields['created']); + } + + dba::update('contact', $fields, $condition, true); + } + /** * @brief Return a list of participating contacts for a thread * diff --git a/src/Protocol/PortableContact.php b/src/Protocol/PortableContact.php index 06c2636aca..672956ffb9 100644 --- a/src/Protocol/PortableContact.php +++ b/src/Protocol/PortableContact.php @@ -18,6 +18,7 @@ use Friendica\Model\Profile; use Friendica\Network\Probe; use Friendica\Util\DateTimeFormat; use Friendica\Util\Network; +use Friendica\Protocol\Diaspora; use dba; use DOMDocument; use DOMXPath; @@ -1429,6 +1430,20 @@ class PortableContact dba::insert('gserver-tag', ['gserver-id' => $gserver['id'], 'tag' => $tag]); } } + + // Create or update the relay contact + $fields = []; + if (isset($data->protocols)) { + if (isset($data->protocols->diaspora)) { + $fields['network'] = NETWORK_DIASPORA; + $fields['batch'] = $data->protocols->diaspora; + } + if (isset($data->protocols->dfrn)) { + $fields['network'] = NETWORK_DFRN; + $fields['batch'] = $data->protocols->dfrn; + } + } + Diaspora::setRelayContact($server_url, $fields); } /** From bbbebb2b9c8ff401829d336e2c39c0dc0cecfc10 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 05:56:40 +0000 Subject: [PATCH 3/8] Don't spool relay deliveries --- src/Worker/Delivery.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index f874e5f230..423691e2a5 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -275,6 +275,13 @@ class Delivery extends BaseObject $public_dfrn = ($contact['contact-type'] == ACCOUNT_TYPE_RELAY); $deliver_status = DFRN::transmit($owner, $contact, $atom, $public_dfrn); + + // We never spool failed relay deliveries + if ($public_dfrn) { + logger('Relay delivery to ' . $contact["url"] . ' with guid ' . $target_item["guid"] . ' returns ' . $deliver_status); + return; + } + if (($deliver_status < 200) || ($deliver_status > 299)) { // Transmit via Diaspora if not possible via Friendica self::deliverDiaspora($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup); From 74aa3499b0f424f81e656beda97228a1c808147a Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 12:41:56 +0000 Subject: [PATCH 4/8] Additional logging --- mod/dfrn_notify.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mod/dfrn_notify.php b/mod/dfrn_notify.php index e2f0336db6..10a0a792a7 100644 --- a/mod/dfrn_notify.php +++ b/mod/dfrn_notify.php @@ -208,7 +208,7 @@ function dfrn_dispatch_public($postdata) $contact = Contact::getDetailsByAddr($msg['author'], 0); if (!$contact) { logger('Contact not found for address ' . $msg['author']); - System::xmlExit(3, 'Contact not found'); + System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found'); } // We now have some contact, so we fetch it @@ -222,7 +222,7 @@ function dfrn_dispatch_public($postdata) // This should never fail if (!DBM::is_result($importer)) { logger('Contact not found for address ' . $msg['author']); - System::xmlExit(3, 'Contact not found'); + System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found'); } logger('Importing post from ' . $msg['author'] . ' with the public envelope.', LOGGER_DEBUG); @@ -246,7 +246,7 @@ function dfrn_dispatch_private($user, $postdata) $cid = Contact::getIdForURL($msg['author']); if (!$cid) { logger('Contact not found for address ' . $msg['author']); - System::xmlExit(3, 'Contact not found'); + System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found'); } } @@ -259,7 +259,7 @@ function dfrn_dispatch_private($user, $postdata) // This should never fail if (!DBM::is_result($importer)) { logger('Contact not found for address ' . $msg['author']); - System::xmlExit(3, 'Contact not found'); + System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found'); } // Set the user id. This is important if this is a public contact From b2b597288cdded396ba6ccfc20aa06c3983364cf Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 13:07:40 +0000 Subject: [PATCH 5/8] Deliver with the new function when delivering to a "uid=0" contact --- src/Worker/Delivery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 423691e2a5..05627e2b12 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -270,7 +270,7 @@ class Delivery extends BaseObject // We don't have a relationship with contacts on a public post. // Se we transmit with the new method and via Diaspora as a fallback - if ($items[0]['uid'] == 0) { + if (($items[0]['uid'] == 0) || ($contact['uid'] == 0)) { // Transmit in public if it's a relay post $public_dfrn = ($contact['contact-type'] == ACCOUNT_TYPE_RELAY); From 5588f0d2ae6f9890f2ee5646806e8db23436391a Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 13:08:48 +0000 Subject: [PATCH 6/8] Improved logging --- src/Worker/Delivery.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index 423691e2a5..e5a86e03e3 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -199,7 +199,7 @@ class Delivery extends BaseObject */ private static function deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup) { - logger('Deliver ' . $target_item["guid"] . ' via DFRN to ' . $contact['addr']); + logger('Deliver ' . $target_item["guid"] . ' via DFRN to ' . empty($contact['addr']) ? $contact['url'] : $contact['addr']); if ($cmd == self::MAIL) { $item = $target_item; From 1a8d0a573e1fd94026236c8a9f2651d42a358adb Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 16:45:00 +0000 Subject: [PATCH 7/8] Bugfix: Contact wasn't added on probing --- src/Network/Probe.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Network/Probe.php b/src/Network/Probe.php index d14c623e86..6e7e21d1e9 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -444,6 +444,11 @@ class Probe $old_fields = dba::selectFirst('contact', $fieldnames, $condition); + // When the contact doesn't exist, the value "true" will trigger an insert + if (!$old_fields) { + $old_fields = true; + } + dba::update('contact', $fields, $condition, $old_fields); } } From a182dd340034616f21631cdaab1019a1bf9918fe Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 30 Apr 2018 16:46:49 +0000 Subject: [PATCH 8/8] Improved logging, avoiding PHP warning --- src/Protocol/DFRN.php | 5 ++++- src/Worker/Delivery.php | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index ad7658a764..63bd2f83bc 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1426,9 +1426,12 @@ class DFRN Contact::markForArchival($contact); return -22; } + $pubkey = $fcontact['pubkey']; + } else { + $pubkey = ''; } - $envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $fcontact['pubkey'], $public_batch); + $envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $pubkey, $public_batch); // Create the endpoint for public posts. This is some WIP and should later be added to the probing if ($public_batch && empty($contact["batch"])) { diff --git a/src/Worker/Delivery.php b/src/Worker/Delivery.php index c56a2aa9bb..04e08edf52 100644 --- a/src/Worker/Delivery.php +++ b/src/Worker/Delivery.php @@ -199,7 +199,7 @@ class Delivery extends BaseObject */ private static function deliverDFRN($cmd, $contact, $owner, $items, $target_item, $public_message, $top_level, $followup) { - logger('Deliver ' . $target_item["guid"] . ' via DFRN to ' . empty($contact['addr']) ? $contact['url'] : $contact['addr']); + logger('Deliver ' . $target_item["guid"] . ' via DFRN to ' . (empty($contact['addr']) ? $contact['url'] : $contact['addr'])); if ($cmd == self::MAIL) { $item = $target_item;