From 32ee4ca4b1df1a98625ec363de25dd9ca014a1b6 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 06:21:44 +0000 Subject: [PATCH 01/13] OStatus: Fixed communication issues with deleted contacts --- include/items.php | 2 +- index.php | 2 +- mod/pubsub.php | 61 ++++++++++++++++++++-------------------- src/Protocol/OStatus.php | 11 ++++---- 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/include/items.php b/include/items.php index 31c8aaa79..83aa82c94 100644 --- a/include/items.php +++ b/include/items.php @@ -290,7 +290,7 @@ function subscribe_to_hub($url, $importer, $contact, $hubmode = 'subscribe') { return; } - $push_url = Config::get('system','url') . '/pubsub/' . $r[0]['nickname'] . '/' . $contact['id']; + $push_url = System::baseUrl() . '/pubsub/' . $r[0]['nickname'] . '/' . $contact['id']; // Use a single verify token, even if multiple hubs $verify_token = ((strlen($contact['hub-verify'])) ? $contact['hub-verify'] : random_string()); diff --git a/index.php b/index.php index ef8440099..ca7b4217a 100644 --- a/index.php +++ b/index.php @@ -72,7 +72,7 @@ if (!$install) { if (Config::get('system', 'force_ssl') && ($a->get_scheme() == "http") && (intval(Config::get('system', 'ssl_policy')) == SSL_POLICY_FULL) && (substr(System::baseUrl(), 0, 8) == "https://") - ) { + && ($_SERVER['REQUEST_METHOD'] == 'GET')) { header("HTTP/1.1 302 Moved Temporarily"); header("Location: " . System::baseUrl() . "/" . $a->query_string); exit(); diff --git a/mod/pubsub.php b/mod/pubsub.php index 1cee91f4d..028b2ba95 100644 --- a/mod/pubsub.php +++ b/mod/pubsub.php @@ -2,15 +2,15 @@ use Friendica\App; use Friendica\Database\DBM; +use Friendica\Protocol\OStatus; function hub_return($valid,$body) { - if($valid) { + if ($valid) { header($_SERVER["SERVER_PROTOCOL"] . ' 200 ' . 'OK'); echo $body; killme(); - } - else { + } else { header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . 'Not Found'); killme(); } @@ -34,15 +34,14 @@ function pubsub_init(App $a) { $nick = (($a->argc > 1) ? notags(trim($a->argv[1])) : ''); $contact_id = (($a->argc > 2) ? intval($a->argv[2]) : 0 ); - if($_SERVER['REQUEST_METHOD'] === 'GET') { - + if ($_SERVER['REQUEST_METHOD'] === 'GET') { $hub_mode = ((x($_GET,'hub_mode')) ? notags(trim($_GET['hub_mode'])) : ''); $hub_topic = ((x($_GET,'hub_topic')) ? notags(trim($_GET['hub_topic'])) : ''); $hub_challenge = ((x($_GET,'hub_challenge')) ? notags(trim($_GET['hub_challenge'])) : ''); $hub_lease = ((x($_GET,'hub_lease_seconds')) ? notags(trim($_GET['hub_lease_seconds'])) : ''); $hub_verify = ((x($_GET,'hub_verify_token')) ? notags(trim($_GET['hub_verify_token'])) : ''); - logger('pubsub: Subscription from ' . $_SERVER['REMOTE_ADDR']); + logger('pubsub: Subscription from ' . $_SERVER['REMOTE_ADDR'] . ' Mode: ' . $hub_mode . ' Nick: ' . $nick); logger('pubsub: data: ' . print_r($_GET,true), LOGGER_DATA); $subscribe = (($hub_mode === 'subscribe') ? 1 : 0); @@ -50,7 +49,7 @@ function pubsub_init(App $a) { $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `account_expired` = 0 AND `account_removed` = 0 LIMIT 1", dbesc($nick) ); - if (! DBM::is_result($r)) { + if (!DBM::is_result($r)) { logger('pubsub: local account not found: ' . $nick); hub_return(false, ''); } @@ -65,36 +64,34 @@ function pubsub_init(App $a) { intval($contact_id), intval($owner['uid']) ); - if (! DBM::is_result($r)) { + if (!DBM::is_result($r)) { logger('pubsub: contact '.$contact_id.' not found.'); hub_return(false, ''); } - if ($hub_topic) - if(! link_compare($hub_topic,$r[0]['poll'])) { + if ($hub_topic) { + if (!link_compare($hub_topic,$r[0]['poll'])) { logger('pubsub: hub topic ' . $hub_topic . ' != ' . $r[0]['poll']); // should abort but let's humour them. } + } $contact = $r[0]; // We must initiate an unsubscribe request with a verify_token. // Don't allow outsiders to unsubscribe us. - if($hub_mode === 'unsubscribe') { - if(! strlen($hub_verify)) { + if ($hub_mode === 'unsubscribe') { + if (!strlen($hub_verify)) { logger('pubsub: bogus unsubscribe'); hub_return(false, ''); } logger('pubsub: unsubscribe success'); } - if ($hub_mode) - $r = q("UPDATE `contact` SET `subhub` = %d WHERE `id` = %d", - intval($subscribe), - intval($contact['id']) - ); - + if ($hub_mode) { + dba::update('contact', ['subhub' => $subscribe], ['id' => $contact['id']]); + } hub_return(true, $hub_challenge); } } @@ -109,18 +106,13 @@ function pubsub_post(App $a) { logger('pubsub: user-agent: ' . $_SERVER['HTTP_USER_AGENT'] ); logger('pubsub: data: ' . $xml, LOGGER_DATA); -// if(! stristr($xml,'argc > 1) ? notags(trim($a->argv[1])) : ''); $contact_id = (($a->argc > 2) ? intval($a->argv[2]) : 0 ); $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `account_expired` = 0 AND `account_removed` = 0 LIMIT 1", dbesc($nick) ); - if (! DBM::is_result($r)) { + if (!DBM::is_result($r)) { hub_post_return(); } @@ -135,19 +127,26 @@ function pubsub_post(App $a) { dbesc(NETWORK_FEED) ); - if (! DBM::is_result($r)) { - logger('pubsub: no contact record for "'.$nick.' ('.$contact_id.')" - ignored. '.$xml); - hub_post_return(); + if (!DBM::is_result($r)) { + $author = OStatus::salmonAuthor($xml, $importer); + if (!empty($author['contact-id'])) { + $contact = dba::selectFirst('contact', [], ['id' => $author['contact-id']]); + if (!in_array($contact['rel'], [CONTACT_IS_SHARING, CONTACT_IS_FRIEND]) && ($contact['network'] != NETWORK_FEED)) { + logger('Contact ' . $author['contact-id'] . ' is not expected to share with us - ignored.'); + hub_post_return(); + } + logger('pubsub: no contact record for "'.$nick.' ('.$contact_id.')" - using '.$author['contact-id'].' instead.'); + } + } else { + $contact = $r[0]; } - $contact = $r[0]; - // we have no way to match Diaspora guid's with atom post id's and could get duplicates. // we'll assume that direct delivery is robust (and this is a bad assumption, but the duplicates are messy). - if($r[0]['network'] === NETWORK_DIASPORA) + if ($r[0]['network'] === NETWORK_DIASPORA) { hub_post_return(); - + } $feedhub = ''; require_once('include/items.php'); diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index fed5cca98..aad97c80f 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -246,13 +246,12 @@ class OStatus $xpath->registerNamespace('ostatus', NAMESPACE_OSTATUS); $xpath->registerNamespace('statusnet', NAMESPACE_STATUSNET); - $entries = $xpath->query('/atom:entry'); + $contact = ["id" => 0]; - foreach ($entries as $entry) { - // fetch the author - $author = self::fetchAuthor($xpath, $entry, $importer, $contact, true); - return $author; - } + // Fetch the first author + $authordata = $xpath->query('//author')->item(0); + $author = self::fetchAuthor($xpath, $authordata, $importer, $contact, true); + return $author; } /** From 4d3b1ae918dcbd9986d0fb9aab6a8a4e6ac70f2d Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 07:16:31 +0000 Subject: [PATCH 02/13] We don't need the contact-id anymore --- mod/pubsub.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/mod/pubsub.php b/mod/pubsub.php index 028b2ba95..4fa6afd3e 100644 --- a/mod/pubsub.php +++ b/mod/pubsub.php @@ -57,19 +57,24 @@ function pubsub_init(App $a) { $owner = $r[0]; - $sql_extra = ((strlen($hub_verify)) ? sprintf(" AND `hub-verify` = '%s' ", dbesc($hub_verify)) : ''); + if (!empty($hub_verify)) { + $sql_extra = sprintf(" AND `hub-verify` = '%s' ", dbesc($hub_verify)); + $log_info = 'hub-verify: ' . $hub_verify; + } else { + $sql_extra = sprintf(" AND `id` = %d ", intval($contact_id)); + $log_info = 'contact-id: ' . $contact_id; + } - $r = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d - AND `blocked` = 0 AND `pending` = 0 $sql_extra LIMIT 1", - intval($contact_id), + $r = q("SELECT * FROM `contact` WHERE `uid` = %d + AND NOT `blocked` AND NOT `pending` $sql_extra LIMIT 1", intval($owner['uid']) ); if (!DBM::is_result($r)) { - logger('pubsub: contact '.$contact_id.' not found.'); + logger('pubsub: contact not found. ' . $log_info); hub_return(false, ''); } - if ($hub_topic) { + if (!empty($hub_topic)) { if (!link_compare($hub_topic,$r[0]['poll'])) { logger('pubsub: hub topic ' . $hub_topic . ' != ' . $r[0]['poll']); // should abort but let's humour them. @@ -86,11 +91,11 @@ function pubsub_init(App $a) { logger('pubsub: bogus unsubscribe'); hub_return(false, ''); } - logger('pubsub: unsubscribe success'); } - if ($hub_mode) { + if (!empty($hub_mode)) { dba::update('contact', ['subhub' => $subscribe], ['id' => $contact['id']]); + logger('pubsub: ' . $hub_mode . ' success'); } hub_return(true, $hub_challenge); } From c20a42c889626a2dc0850fcd9d939166e7c18d97 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 21:03:56 +0000 Subject: [PATCH 03/13] Completely reformatted and restructured code, using dba functions now. --- mod/pubsub.php | 160 ++++++++++++++++++++----------------------------- 1 file changed, 65 insertions(+), 95 deletions(-) diff --git a/mod/pubsub.php b/mod/pubsub.php index 4fa6afd3e..0582ca1d5 100644 --- a/mod/pubsub.php +++ b/mod/pubsub.php @@ -4,164 +4,134 @@ use Friendica\App; use Friendica\Database\DBM; use Friendica\Protocol\OStatus; -function hub_return($valid,$body) { +require_once('include/security.php'); +require_once('include/items.php'); +function hub_return($valid, $body) +{ if ($valid) { - header($_SERVER["SERVER_PROTOCOL"] . ' 200 ' . 'OK'); + header($_SERVER["SERVER_PROTOCOL"] . ' 200 OK'); echo $body; - killme(); } else { - header($_SERVER["SERVER_PROTOCOL"] . ' 404 ' . 'Not Found'); - killme(); + header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found'); } - - // NOTREACHED + killme(); } // when receiving an XML feed, always return OK -function hub_post_return() { - - header($_SERVER["SERVER_PROTOCOL"] . ' 200 ' . 'OK'); +function hub_post_return() +{ + header($_SERVER["SERVER_PROTOCOL"] . ' 200 OK'); killme(); - } - - -function pubsub_init(App $a) { - +function pubsub_init(App $a) +{ $nick = (($a->argc > 1) ? notags(trim($a->argv[1])) : ''); $contact_id = (($a->argc > 2) ? intval($a->argv[2]) : 0 ); if ($_SERVER['REQUEST_METHOD'] === 'GET') { - $hub_mode = ((x($_GET,'hub_mode')) ? notags(trim($_GET['hub_mode'])) : ''); - $hub_topic = ((x($_GET,'hub_topic')) ? notags(trim($_GET['hub_topic'])) : ''); - $hub_challenge = ((x($_GET,'hub_challenge')) ? notags(trim($_GET['hub_challenge'])) : ''); - $hub_lease = ((x($_GET,'hub_lease_seconds')) ? notags(trim($_GET['hub_lease_seconds'])) : ''); - $hub_verify = ((x($_GET,'hub_verify_token')) ? notags(trim($_GET['hub_verify_token'])) : ''); + $hub_mode = notags(trim(defaults($_GET, 'hub_mode', ''))); + $hub_topic = notags(trim(defaults($_GET, 'hub_topic', ''))); + $hub_challenge = notags(trim(defaults($_GET, 'hub_challenge', ''))); + $hub_lease = notags(trim(defaults($_GET, 'hub_lease_seconds', ''))); + $hub_verify = notags(trim(defaults($_GET, 'hub_verify_token', ''))); - logger('pubsub: Subscription from ' . $_SERVER['REMOTE_ADDR'] . ' Mode: ' . $hub_mode . ' Nick: ' . $nick); - logger('pubsub: data: ' . print_r($_GET,true), LOGGER_DATA); + logger('Subscription from ' . $_SERVER['REMOTE_ADDR'] . ' Mode: ' . $hub_mode . ' Nick: ' . $nick); + logger('Data: ' . print_r($_GET,true), LOGGER_DATA); $subscribe = (($hub_mode === 'subscribe') ? 1 : 0); - $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `account_expired` = 0 AND `account_removed` = 0 LIMIT 1", - dbesc($nick) - ); - if (!DBM::is_result($r)) { - logger('pubsub: local account not found: ' . $nick); + $owner = dba::selectFirst('user', ['uid'], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]); + if (!DBM::is_result($owner)) { + logger('Local account not found: ' . $nick); hub_return(false, ''); } - - $owner = $r[0]; + $condition = ['uid' => $owner['uid'], 'id' => $contact_id, 'blocked' => false, 'pending' => false]; if (!empty($hub_verify)) { - $sql_extra = sprintf(" AND `hub-verify` = '%s' ", dbesc($hub_verify)); - $log_info = 'hub-verify: ' . $hub_verify; - } else { - $sql_extra = sprintf(" AND `id` = %d ", intval($contact_id)); - $log_info = 'contact-id: ' . $contact_id; + $condition['hub-verify'] = $hub_verify; } - $r = q("SELECT * FROM `contact` WHERE `uid` = %d - AND NOT `blocked` AND NOT `pending` $sql_extra LIMIT 1", - intval($owner['uid']) - ); - if (!DBM::is_result($r)) { - logger('pubsub: contact not found. ' . $log_info); + $contact = dba::selectFirst('contact', ['id', 'poll'], $condition); + if (!DBM::is_result($contact)) { + logger('Contact ' . $contact_id . ' not found.'); hub_return(false, ''); } - if (!empty($hub_topic)) { - if (!link_compare($hub_topic,$r[0]['poll'])) { - logger('pubsub: hub topic ' . $hub_topic . ' != ' . $r[0]['poll']); - // should abort but let's humour them. - } + if (!empty($hub_topic) && !link_compare($hub_topic, $contact['poll'])) { + logger('Hub topic ' . $hub_topic . ' != ' . $contact['poll']); + hub_return(false, ''); } - $contact = $r[0]; - // We must initiate an unsubscribe request with a verify_token. // Don't allow outsiders to unsubscribe us. - if ($hub_mode === 'unsubscribe') { - if (!strlen($hub_verify)) { - logger('pubsub: bogus unsubscribe'); - hub_return(false, ''); - } + if (($hub_mode === 'unsubscribe') && empty($hub_verify)) { + logger('Bogus unsubscribe'); + hub_return(false, ''); } if (!empty($hub_mode)) { dba::update('contact', ['subhub' => $subscribe], ['id' => $contact['id']]); - logger('pubsub: ' . $hub_mode . ' success'); + logger($hub_mode . ' success for contact ' . $contact_id . '.'); } hub_return(true, $hub_challenge); } } -require_once('include/security.php'); - -function pubsub_post(App $a) { - +function pubsub_post(App $a) +{ $xml = file_get_contents('php://input'); - logger('pubsub: feed arrived from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $a->cmd ); - logger('pubsub: user-agent: ' . $_SERVER['HTTP_USER_AGENT'] ); - logger('pubsub: data: ' . $xml, LOGGER_DATA); + logger('Feed arrived from ' . $_SERVER['REMOTE_ADDR'] . ' for ' . $a->cmd . ' with user-agent: ' . $_SERVER['HTTP_USER_AGENT']); + logger('Data: ' . $xml, LOGGER_DATA); $nick = (($a->argc > 1) ? notags(trim($a->argv[1])) : ''); $contact_id = (($a->argc > 2) ? intval($a->argv[2]) : 0 ); - $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' AND `account_expired` = 0 AND `account_removed` = 0 LIMIT 1", - dbesc($nick) - ); - if (!DBM::is_result($r)) { + $importer = dba::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]); + if (!DBM::is_result($importer)) { hub_post_return(); } - $importer = $r[0]; + $condition = ['id' => $contact_id, 'uid' => $importer['uid'], 'subhub' => true, 'blocked' => false]; + $contact = dba::selectFirst('contact', [], $condition); - $r = q("SELECT * FROM `contact` WHERE `subhub` AND `id` = %d AND `uid` = %d - AND (`rel` = %d OR `rel` = %d OR network = '%s') AND NOT `blocked` LIMIT 1", - intval($contact_id), - intval($importer['uid']), - intval(CONTACT_IS_SHARING), - intval(CONTACT_IS_FRIEND), - dbesc(NETWORK_FEED) - ); - - if (!DBM::is_result($r)) { + if (!DBM::is_result($contact)) { $author = OStatus::salmonAuthor($xml, $importer); if (!empty($author['contact-id'])) { - $contact = dba::selectFirst('contact', [], ['id' => $author['contact-id']]); - if (!in_array($contact['rel'], [CONTACT_IS_SHARING, CONTACT_IS_FRIEND]) && ($contact['network'] != NETWORK_FEED)) { - logger('Contact ' . $author['contact-id'] . ' is not expected to share with us - ignored.'); - hub_post_return(); - } - logger('pubsub: no contact record for "'.$nick.' ('.$contact_id.')" - using '.$author['contact-id'].' instead.'); + $condition = ['id' => $author['contact-id'], 'uid' => $importer['uid'], 'subhub' => true, 'blocked' => false]; + $contact = dba::selectFirst('contact', [], $condition); + logger('No record for ' . $nick .' with contact id ' . $contact_id . ' - using '.$author['contact-id'].' instead.'); + } + if (!DBM::is_result($contact)) { + logger('Contact ' . $contact_id . ' for user ' . $nick . " wasn't found - ignored."); + hub_post_return(); } - } else { - $contact = $r[0]; } - // we have no way to match Diaspora guid's with atom post id's and could get duplicates. - // we'll assume that direct delivery is robust (and this is a bad assumption, but the duplicates are messy). - - if ($r[0]['network'] === NETWORK_DIASPORA) { + if (!in_array($contact['rel'], [CONTACT_IS_SHARING, CONTACT_IS_FRIEND]) && ($contact['network'] != NETWORK_FEED)) { + logger('Contact ' . $contact['id'] . ' is not expected to share with us - ignored.'); hub_post_return(); } + + // We import feeds from OStatus, Friendica and ATOM/RSS. + /// @todo Check if Friendica posts really arrive here - otherwise we can discard some stuff + if (!in_array($contact['network'], [NETWORK_OSTATUS, NETWORK_DFRN, NETWORK_FEED])) { + hub_post_return(); + } + + logger('Import item for ' . $nick . ' from ' . $contact['nick'] . ' (' . $contact['id'] . ')'); $feedhub = ''; + consume_feed($xml, $importer, $contact, $feedhub); - require_once('include/items.php'); - - consume_feed($xml,$importer,$contact,$feedhub,1,1); - - // do it a second time so that any children find their parents. - - consume_feed($xml,$importer,$contact,$feedhub,1,2); + // do it a second time for DFRN so that any children find their parents. + if ($contact['network'] === NETWORK_DFRN) { + consume_feed($xml, $importer, $contact, $feedhub); + } hub_post_return(); - } From bc848526829c9808868bb8520f8e3510b1a0000e Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 21:10:19 +0000 Subject: [PATCH 04/13] Added logging --- mod/pubsub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/pubsub.php b/mod/pubsub.php index 0582ca1d5..39a0162ea 100644 --- a/mod/pubsub.php +++ b/mod/pubsub.php @@ -108,7 +108,7 @@ function pubsub_post(App $a) logger('No record for ' . $nick .' with contact id ' . $contact_id . ' - using '.$author['contact-id'].' instead.'); } if (!DBM::is_result($contact)) { - logger('Contact ' . $contact_id . ' for user ' . $nick . " wasn't found - ignored."); + logger('Contact ' . $contact_id . ' for user ' . $nick . " wasn't found - ignored. XML: " . $xml); hub_post_return(); } } From aff99b32fd11aaf87f13248ed992712cf69d9a23 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 21:33:45 +0000 Subject: [PATCH 05/13] Improved logging --- mod/pubsub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/pubsub.php b/mod/pubsub.php index 39a0162ea..11f92af6a 100644 --- a/mod/pubsub.php +++ b/mod/pubsub.php @@ -108,7 +108,7 @@ function pubsub_post(App $a) logger('No record for ' . $nick .' with contact id ' . $contact_id . ' - using '.$author['contact-id'].' instead.'); } if (!DBM::is_result($contact)) { - logger('Contact ' . $contact_id . ' for user ' . $nick . " wasn't found - ignored. XML: " . $xml); + logger('Contact ' . $author["author-link"] . ' (' . $contact_id . ') for user ' . $nick . " wasn't found - ignored. XML: " . $xml); hub_post_return(); } } From 3f6fefaa9ac2dd5a48ab3c521f425c84c9d32273 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 21:58:05 +0000 Subject: [PATCH 06/13] Pleroma with the Mastodon UI handles content warning different --- src/Protocol/OStatus.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index aad97c80f..aa1079407 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -660,8 +660,9 @@ class OStatus // Mastodon Content Warning if (($item["verb"] == ACTIVITY_POST) && $xpath->evaluate('boolean(atom:summary)', $entry)) { $clear_text = $xpath->query('atom:summary/text()', $entry)->item(0)->nodeValue; - - $item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]'; + if (!empty($clear_text)) { + $item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]'; + } } if (($self != '') && empty($item['protocol'])) { From f49391a21cccef4e8cfb3c328ff161cdc309c4da Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 22:39:08 +0000 Subject: [PATCH 07/13] "nsfw" at "content warning" content doesn't fit together --- src/Protocol/OStatus.php | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index aa1079407..c7c264f5a 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -604,21 +604,6 @@ class OStatus $item["coord"] = $georsspoint->item(0)->nodeValue; } - $categories = $xpath->query('atom:category', $entry); - if ($categories) { - foreach ($categories as $category) { - foreach ($category->attributes as $attributes) { - if ($attributes->name == "term") { - $term = $attributes->textContent; - if (strlen($item["tag"])) { - $item["tag"] .= ','; - } - $item["tag"] .= "#[url=".System::baseUrl()."/search?tag=".$term."]".$term."[/url]"; - } - } - } - } - $self = ''; $add_body = ''; @@ -658,10 +643,12 @@ class OStatus } // Mastodon Content Warning + $content_warning = false; if (($item["verb"] == ACTIVITY_POST) && $xpath->evaluate('boolean(atom:summary)', $entry)) { $clear_text = $xpath->query('atom:summary/text()', $entry)->item(0)->nodeValue; if (!empty($clear_text)) { $item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]'; + $content_warning = true; } } @@ -686,6 +673,25 @@ class OStatus $item["parent-uri"] = $item["uri"]; } + $categories = $xpath->query('atom:category', $entry); + if ($categories) { + foreach ($categories as $category) { + foreach ($category->attributes as $attributes) { + if ($attributes->name == "term") { + $term = $attributes->textContent; + // don't add nsfw with content warning + // Background: "nsfw" is set automatically by Mastodon and superfluous + if (!$content_warning || ($term != 'nsfw')) { + if (strlen($item["tag"])) { + $item["tag"] .= ','; + } + $item["tag"] .= "#[url=".System::baseUrl()."/search?tag=".$term."]".$term."[/url]"; + } + } + } + } + } + if (($item['author-link'] != '') && !empty($item['protocol'])) { $item = Conversation::insert($item); } From f17f61df38856589cf47d90817ba3f35acf22ae0 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 13 Mar 2018 23:32:38 +0000 Subject: [PATCH 08/13] Fix indentation --- mod/pubsub.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod/pubsub.php b/mod/pubsub.php index 11f92af6a..a68b222ec 100644 --- a/mod/pubsub.php +++ b/mod/pubsub.php @@ -129,7 +129,7 @@ function pubsub_post(App $a) consume_feed($xml, $importer, $contact, $feedhub); // do it a second time for DFRN so that any children find their parents. - if ($contact['network'] === NETWORK_DFRN) { + if ($contact['network'] === NETWORK_DFRN) { consume_feed($xml, $importer, $contact, $feedhub); } From 858fd127a16bf02cb1b9566e2263cd3263bf9ed4 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 14 Mar 2018 00:27:15 +0000 Subject: [PATCH 09/13] Fix: subscribing to the old followers hadn't worked --- mod/ostatus_subscribe.php | 3 +++ mod/settings.php | 3 +-- src/Util/Network.php | 7 ++++++- view/templates/settings/connectors.tpl | 2 +- view/theme/frio/templates/settings/connectors.tpl | 4 ++-- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/mod/ostatus_subscribe.php b/mod/ostatus_subscribe.php index 07f4647e6..e8ba144a1 100644 --- a/mod/ostatus_subscribe.php +++ b/mod/ostatus_subscribe.php @@ -29,12 +29,14 @@ function ostatus_subscribe_content(App $a) { if (PConfig::get($uid, "ostatus", "legacy_friends") == "") { if ($_REQUEST["url"] == "") { + PConfig::delete($uid, "ostatus", "legacy_contact"); return $o.L10n::t("No contact provided."); } $contact = Probe::uri($_REQUEST["url"]); if (!$contact) { + PConfig::delete($uid, "ostatus", "legacy_contact"); return $o.L10n::t("Couldn't fetch information for contact."); } @@ -44,6 +46,7 @@ function ostatus_subscribe_content(App $a) { $data = Network::curl($api."statuses/friends.json?screen_name=".$contact["nick"]); if (!$data["success"]) { + PConfig::delete($uid, "ostatus", "legacy_contact"); return $o.L10n::t("Couldn't fetch friends for contact."); } diff --git a/mod/settings.php b/mod/settings.php index b2dc37324..5fd67afa1 100644 --- a/mod/settings.php +++ b/mod/settings.php @@ -207,8 +207,7 @@ function settings_post(App $a) return; } - if (($a->argc > 1) && ($a->argv[1] == 'connectors')) - { + if (($a->argc > 1) && ($a->argv[1] == 'connectors')) { check_form_security_token_redirectOnErr('/settings/connectors', 'settings_connectors'); if (x($_POST, 'general-submit')) { diff --git a/src/Util/Network.php b/src/Util/Network.php index c9955f800..d25b79924 100644 --- a/src/Util/Network.php +++ b/src/Util/Network.php @@ -217,7 +217,7 @@ class Network $newurl = $curl_info['redirect_url']; - if (($new_location_info['path'] == '') && ( $new_location_info['host'] != '')) { + if (($new_location_info['path'] == '') && ($new_location_info['host'] != '')) { $newurl = $new_location_info['scheme'] . '://' . $new_location_info['host'] . $old_location_info['path']; } @@ -229,6 +229,11 @@ class Network if (strpos($newurl, '/') === 0) { $newurl = $old_location_info["scheme"]."://".$old_location_info["host"].$newurl; } + $old_location_query = @parse_url($url, PHP_URL_QUERY); + + if ($old_location_query != '') { + $newurl .= '?' . $old_location_query; + } if (filter_var($newurl, FILTER_VALIDATE_URL)) { $redirects++; diff --git a/view/templates/settings/connectors.tpl b/view/templates/settings/connectors.tpl index 58306fb27..83ebd74f5 100644 --- a/view/templates/settings/connectors.tpl +++ b/view/templates/settings/connectors.tpl @@ -22,7 +22,7 @@

{{$repair_ostatus_text}}

-
+
diff --git a/view/theme/frio/templates/settings/connectors.tpl b/view/theme/frio/templates/settings/connectors.tpl index c388a6e25..e5d21158c 100644 --- a/view/theme/frio/templates/settings/connectors.tpl +++ b/view/theme/frio/templates/settings/connectors.tpl @@ -28,7 +28,7 @@

{{$repair_ostatus_text}}

- +
@@ -67,4 +67,4 @@ {{/if}} - \ No newline at end of file + From 6352aa112b2866ca88d13f90fea9a2b50564f2e8 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 14 Mar 2018 07:13:17 +0000 Subject: [PATCH 10/13] Add the nsfw removal behind a config switch --- doc/htconfig.md | 1 + src/Protocol/OStatus.php | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/htconfig.md b/doc/htconfig.md index a19a92a4a..99d02dda4 100644 --- a/doc/htconfig.md +++ b/doc/htconfig.md @@ -87,6 +87,7 @@ Example: To set the automatic database cleanup process add this line to your .ht * **relay_server_tags** - Comma separated list of tags for the "tags" subscription (see "relay_scrope") * **relay_user_tags** (Boolean) - If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags". * **remove_multiplicated_lines** (Boolean) - If enabled, multiple linefeeds in items are stripped to a single one. +* **remove_nsfw_with_cw** (Boolean) - If enabled, the "nsfw" will be removed from Mastodon posts with content warning. * **show_unsupported_addons** (Boolean) - Show all addons including the unsupported ones. * **show_unsupported_themes** (Boolean) - Show all themes including the unsupported ones. * **show_global_community_hint** (Boolean) - When the global community page is enabled, use this option to display a hint above the stream, that this is a collection of all public top-level postings that arrive on your node. diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index c7c264f5a..452da7d2d 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -679,9 +679,10 @@ class OStatus foreach ($category->attributes as $attributes) { if ($attributes->name == "term") { $term = $attributes->textContent; - // don't add nsfw with content warning - // Background: "nsfw" is set automatically by Mastodon and superfluous - if (!$content_warning || ($term != 'nsfw')) { + // don't add nsfw with content warning if enabled. + // Background: "nsfw" is set automatically by Mastodon + if (!Config::get('system', 'remove_nsfw_with_cw', false) || + !$content_warning || ($term != 'nsfw')) { if (strlen($item["tag"])) { $item["tag"] .= ','; } From 5bd519efffa6d2c484b6c4dce8c58dcdab2cd168 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 14 Mar 2018 22:28:35 +0000 Subject: [PATCH 11/13] There is now a "content-warning" field --- boot.php | 2 +- database.sql | 5 +++-- include/conversation.php | 2 +- include/text.php | 5 +++++ src/Database/DBStructure.php | 1 + src/Protocol/OStatus.php | 40 +++++++++++++++--------------------- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/boot.php b/boot.php index b8b9b0ec2..caf645c04 100644 --- a/boot.php +++ b/boot.php @@ -39,7 +39,7 @@ define('FRIENDICA_PLATFORM', 'Friendica'); define('FRIENDICA_CODENAME', 'Asparagus'); define('FRIENDICA_VERSION', '3.6-rc'); define('DFRN_PROTOCOL_VERSION', '2.23'); -define('DB_UPDATE_VERSION', 1255); +define('DB_UPDATE_VERSION', 1256); define('NEW_UPDATE_ROUTINE_VERSION', 1170); /** diff --git a/database.sql b/database.sql index 4275c3831..181e9e804 100644 --- a/database.sql +++ b/database.sql @@ -1,6 +1,6 @@ -- ------------------------------------------ --- Friendica 3.6-dev (Asparagus) --- DB_UPDATE_VERSION 1255 +-- Friendica 3.6-rc (Asparagus) +-- DB_UPDATE_VERSION 1256 -- ------------------------------------------ @@ -466,6 +466,7 @@ CREATE TABLE IF NOT EXISTS `item` ( `author-link` varchar(255) NOT NULL DEFAULT '' COMMENT '', `author-avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '', `title` varchar(255) NOT NULL DEFAULT '' COMMENT '', + `content-warning` varchar(255) NOT NULL DEFAULT '' COMMENT '', `body` mediumtext COMMENT '', `app` varchar(255) NOT NULL DEFAULT '' COMMENT '', `verb` varchar(100) NOT NULL DEFAULT '' COMMENT '', diff --git a/include/conversation.php b/include/conversation.php index dc99a8319..0fc43fb09 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -445,7 +445,7 @@ These Fields are not added below (yet). They are here to for bug search. return "`item`.`author-id`, `item`.`author-link`, `item`.`author-name`, `item`.`author-avatar`, `item`.`owner-id`, `item`.`owner-link`, `item`.`owner-name`, `item`.`owner-avatar`, `item`.`contact-id`, `item`.`uid`, `item`.`id`, `item`.`parent`, - `item`.`uri`, `item`.`thr-parent`, `item`.`parent-uri`, + `item`.`uri`, `item`.`thr-parent`, `item`.`parent-uri`, `item`.`content-warning`, `item`.`commented`, `item`.`created`, `item`.`edited`, `item`.`received`, `item`.`verb`, `item`.`object-type`, `item`.`postopts`, `item`.`plink`, `item`.`guid`, `item`.`wall`, `item`.`private`, `item`.`starred`, diff --git a/include/text.php b/include/text.php index 1474b8bf0..0aeaa7203 100644 --- a/include/text.php +++ b/include/text.php @@ -1182,6 +1182,11 @@ function put_item_in_cache(&$item, $update = false) // I'm not sure if we should store it permanently, so we save the old value. $body = $item["body"]; + // Add the content warning + if (!empty($item['content-warning'])) { + $item["body"] = $item['content-warning'] . '[spoiler]' . $item["body"] . '[/spoiler]'; + } + $a = get_app(); redir_private_images($a, $item); diff --git a/src/Database/DBStructure.php b/src/Database/DBStructure.php index f4a88871d..a1ef3374f 100644 --- a/src/Database/DBStructure.php +++ b/src/Database/DBStructure.php @@ -1143,6 +1143,7 @@ class DBStructure "author-link" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "author-avatar" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "title" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], + "content-warning" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "body" => ["type" => "mediumtext", "comment" => ""], "app" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""], "verb" => ["type" => "varchar(100)", "not null" => "1", "default" => "", "comment" => ""], diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index 452da7d2d..eb8474ba2 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -604,6 +604,21 @@ class OStatus $item["coord"] = $georsspoint->item(0)->nodeValue; } + $categories = $xpath->query('atom:category', $entry); + if ($categories) { + foreach ($categories as $category) { + foreach ($category->attributes as $attributes) { + if ($attributes->name == "term") { + $term = $attributes->textContent; + if (strlen($item["tag"])) { + $item["tag"] .= ','; + } + $item["tag"] .= "#[url=".System::baseUrl()."/search?tag=".$term."]".$term."[/url]"; + } + } + } + } + $self = ''; $add_body = ''; @@ -643,12 +658,11 @@ class OStatus } // Mastodon Content Warning - $content_warning = false; if (($item["verb"] == ACTIVITY_POST) && $xpath->evaluate('boolean(atom:summary)', $entry)) { $clear_text = $xpath->query('atom:summary/text()', $entry)->item(0)->nodeValue; if (!empty($clear_text)) { - $item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]'; - $content_warning = true; + $item['content-warning'] = html2bbcode($clear_text); + //$item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]'; } } @@ -673,26 +687,6 @@ class OStatus $item["parent-uri"] = $item["uri"]; } - $categories = $xpath->query('atom:category', $entry); - if ($categories) { - foreach ($categories as $category) { - foreach ($category->attributes as $attributes) { - if ($attributes->name == "term") { - $term = $attributes->textContent; - // don't add nsfw with content warning if enabled. - // Background: "nsfw" is set automatically by Mastodon - if (!Config::get('system', 'remove_nsfw_with_cw', false) || - !$content_warning || ($term != 'nsfw')) { - if (strlen($item["tag"])) { - $item["tag"] .= ','; - } - $item["tag"] .= "#[url=".System::baseUrl()."/search?tag=".$term."]".$term."[/url]"; - } - } - } - } - } - if (($item['author-link'] != '') && !empty($item['protocol'])) { $item = Conversation::insert($item); } From c4a023dfd460a9a225d933272189584d720fec6a Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 14 Mar 2018 22:30:05 +0000 Subject: [PATCH 12/13] Remove unused description --- doc/htconfig.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/htconfig.md b/doc/htconfig.md index 99d02dda4..a19a92a4a 100644 --- a/doc/htconfig.md +++ b/doc/htconfig.md @@ -87,7 +87,6 @@ Example: To set the automatic database cleanup process add this line to your .ht * **relay_server_tags** - Comma separated list of tags for the "tags" subscription (see "relay_scrope") * **relay_user_tags** (Boolean) - If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags". * **remove_multiplicated_lines** (Boolean) - If enabled, multiple linefeeds in items are stripped to a single one. -* **remove_nsfw_with_cw** (Boolean) - If enabled, the "nsfw" will be removed from Mastodon posts with content warning. * **show_unsupported_addons** (Boolean) - Show all addons including the unsupported ones. * **show_unsupported_themes** (Boolean) - Show all themes including the unsupported ones. * **show_global_community_hint** (Boolean) - When the global community page is enabled, use this option to display a hint above the stream, that this is a collection of all public top-level postings that arrive on your node. From 2bedead6f446db414c78ac7863915021adb97680 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 14 Mar 2018 22:31:52 +0000 Subject: [PATCH 13/13] Remove commented code --- src/Protocol/OStatus.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index eb8474ba2..26909102f 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -662,7 +662,6 @@ class OStatus $clear_text = $xpath->query('atom:summary/text()', $entry)->item(0)->nodeValue; if (!empty($clear_text)) { $item['content-warning'] = html2bbcode($clear_text); - //$item["body"] = html2bbcode($clear_text) . '[spoiler]' . $item["body"] . '[/spoiler]'; } }