X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FDiaspora.php;h=981abb0831defaec2816419afe5ec16b307cbc7b;hb=dcfd81e2eec9bde5c30f4738afb0a29b623ee0f6;hp=6f03c0df87ad559cd0137034cb2d9d6f0f8d5a93;hpb=ad45a73bf3166011abdae06ead285df316857be9;p=friendica.git diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index 6f03c0df87..981abb0831 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -68,6 +68,12 @@ class Diaspora } if (Config::get("system", "relay_directly", false)) { + // We distribute our stuff based on the parent to ensure that the thread will be complete + $parent = dba::selectFirst('item', ['parent'], ['id' => $item_id]); + if (!DBM::is_result($parent)) { + return; + } + // Servers that want to get all content $servers = dba::select('gserver', ['url'], ['relay-subscribe' => true, 'relay-scope' => 'all']); while ($server = dba::fetch($servers)) { @@ -75,7 +81,7 @@ class Diaspora } // All tags of the current post - $condition = ['otype' => TERM_OBJ_POST, 'type' => TERM_HASHTAG, 'oid' => $item_id]; + $condition = ['otype' => TERM_OBJ_POST, 'type' => TERM_HASHTAG, 'oid' => $parent['parent']]; $tags = dba::select('term', ['term'], $condition); $taglist = []; while ($tag = dba::fetch($tags)) { @@ -134,55 +140,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); - - $fields = ['batch', 'id', 'name', 'network']; + self::setRelayContact($server_url); + $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 * @@ -596,9 +605,9 @@ class Diaspora } $importer = ["uid" => 0, "page-flags" => PAGE_FREELOVE]; - $message_id = self::dispatch($importer, $msg, $fields); + $success = self::dispatch($importer, $msg, $fields); - return $message_id; + return $success; } /** @@ -832,6 +841,10 @@ class Diaspora if (isset($parent_author_signature)) { $key = self::key($msg["author"]); + if (empty($key)) { + logger("No key found for parent author ".$msg["author"], LOGGER_DEBUG); + return false; + } if (!Crypto::rsaVerify($signed_data, $parent_author_signature, $key, "sha256")) { logger("No valid parent author signature for parent author ".$msg["author"]. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$parent_author_signature, LOGGER_DEBUG); @@ -840,6 +853,10 @@ class Diaspora } $key = self::key($fields->author); + if (empty($key)) { + logger("No key found for author ".$fields->author, LOGGER_DEBUG); + return false; + } if (!Crypto::rsaVerify($signed_data, $author_signature, $key, "sha256")) { logger("No valid author signature for author ".$fields->author. " in type ".$type." - signed data: ".$signed_data." - Message: ".$msg["message"]." - Signature ".$author_signature, LOGGER_DEBUG); @@ -1143,7 +1160,7 @@ class Diaspora //} // We don't seem to like that person - if ($contact["blocked"] || $contact["readonly"]) { + if ($contact["blocked"]) { // Maybe blocked, don't accept. return false; // We are following this person? @@ -1591,34 +1608,9 @@ class Diaspora logger('Contacts are updated.'); // update items - /// @todo This is an extreme performance killer - $fields = [ - 'owner-link' => [$contact["url"], $data["url"]], - 'author-link' => [$contact["url"], $data["url"]], - ]; - foreach ($fields as $n => $f) { - $r = q( - "SELECT `id` FROM `item` WHERE `%s` = '%s' AND `uid` = %d LIMIT 1", - $n, - dbesc($f[0]), - intval($importer["uid"]) - ); - - if (DBM::is_result($r)) { - $x = q( - "UPDATE `item` SET `%s` = '%s' WHERE `%s` = '%s' AND `uid` = %d", - $n, - dbesc($f[1]), - $n, - dbesc($f[0]), - intval($importer["uid"]) - ); - - if ($x === false) { - return false; - } - } - } + // This is an extreme performance killer + Item::update(['owner-link' => $data["url"]], ['owner-link' => $contact["url"], 'uid' => $importer["uid"]]); + Item::update(['author-link' => $data["url"]], ['author-link' => $contact["url"], 'uid' => $importer["uid"]]); logger('Items are updated.'); @@ -2721,10 +2713,15 @@ class Diaspora */ public static function originalItem($guid, $orig_author) { + if (empty($guid)) { + logger('Empty guid. Quitting.'); + return false; + } + // Do we already have this item? $fields = ['body', 'tag', 'app', 'created', 'object-type', 'uri', 'guid', 'author-name', 'author-link', 'author-avatar']; - $condition = ['guid' => $guid, 'visible' => true, 'deleted' => false]; + $condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => false]; $item = dba::selectfirst('item', $fields, $condition); if (DBM::is_result($item)) { @@ -2734,7 +2731,7 @@ class Diaspora // Then refetch the content, if it is a reshare from a reshare. // If it is a reshared post from another network then reformat to avoid display problems with two share elements if (self::isReshare($item["body"], true)) { - $r = []; + $item = []; } elseif (self::isReshare($item["body"], false) || strstr($item["body"], "[share")) { $item["body"] = Markdown::toBBCode(BBCode::toMarkdown($item["body"])); @@ -2749,21 +2746,26 @@ class Diaspora } } - if (!DBM::is_result($r)) { + if (!DBM::is_result($item)) { + if (empty($orig_author)) { + logger('Empty author for guid ' . $guid . '. Quitting.'); + return false; + } + $server = "https://".substr($orig_author, strpos($orig_author, "@") + 1); logger("1st try: reshared message ".$guid." will be fetched via SSL from the server ".$server); - $item_id = self::storeByGuid($guid, $server); + $stored = self::storeByGuid($guid, $server); - if (!$item_id) { + if (!$stored) { $server = "http://".substr($orig_author, strpos($orig_author, "@") + 1); - logger("2nd try: reshared message ".$guid." will be fetched without SLL from the server ".$server); - $item_id = self::storeByGuid($guid, $server); + logger("2nd try: reshared message ".$guid." will be fetched without SSL from the server ".$server); + $stored = self::storeByGuid($guid, $server); } - if ($item_id) { + if ($stored) { $fields = ['body', 'tag', 'app', 'created', 'object-type', 'uri', 'guid', 'author-name', 'author-link', 'author-avatar']; - $condition = ['id' => $item_id, 'visible' => true, 'deleted' => false]; + $condition = ['guid' => $guid, 'visible' => true, 'deleted' => false, 'private' => false]; $item = dba::selectfirst('item', $fields, $condition); if (DBM::is_result($item)) { @@ -2967,12 +2969,10 @@ class Diaspora case "StatusMessage": return self::itemRetraction($importer, $contact, $data); - case "Contact": - case "Person": - /// @todo What should we do with an "unshare"? - // Removing the contact isn't correct since we still can read the public items - Contact::remove($contact["id"]); - return true; + case "PollParticipation": + case "Photo": + // Currently unsupported + break; default: logger("Unknown target type ".$target_type); @@ -3569,8 +3569,12 @@ class Diaspora $ret["root_guid"] = $guid; return $ret; } + } elseif (($guid == "") && $complete) { + return false; } + $ret["root_guid"] = $guid; + $profile = ""; preg_match("/profile='(.*?)'/ism", $attributes, $matches); if ($matches[1] != "") { @@ -3591,10 +3595,6 @@ class Diaspora } } - if (!empty($guid)) { - $ret["root_guid"] = $guid; - } - if (empty($ret) && !$complete) { return true; }