X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=include%2Fdiaspora.php;h=cfb624fdf2a075a62803649aa982658ec85f4f19;hb=6c0c9d542abaabd8000a10eb47b0921426fcd25d;hp=8598ca7949ca511d7c5426aab3520f49c6e16dac;hpb=c1ce7059b6ce83f7f3995c06ea7d3c4fa5dbbef7;p=friendica.git diff --git a/include/diaspora.php b/include/diaspora.php index 8598ca7949..cfb624fdf2 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2,6 +2,10 @@ /** * @file include/diaspora.php * @brief The implementation of the diaspora protocol + * + * The new protocol is described here: http://diaspora.github.io/diaspora_federation/index.html + * Currently this implementation here interprets the old and the new protocol and sends the old one. + * This will change in the future. */ require_once("include/items.php"); @@ -315,8 +319,8 @@ class diaspora { dbesc(NETWORK_DIASPORA), dbesc($msg["author"]) ); - if($r) { - foreach($r as $rr) { + if ($r) { + foreach ($r as $rr) { logger("delivering to: ".$rr["username"]); self::dispatch($rr,$msg); } @@ -432,6 +436,8 @@ class diaspora { $type = $element->getName(); $orig_type = $type; + logger("Got message type ".$type.": ".$msg["message"], LOGGER_DATA); + // All retractions are handled identically from now on. // In the new version there will only be "retraction". if (in_array($type, array("signed_retraction", "relayable_retraction"))) @@ -568,6 +574,9 @@ class diaspora { $d = strtotime($person["updated"]." +00:00"); if ($d < strtotime("now - 14 days")) $update = true; + + if ($person["guid"] == "") + $update = true; } if (!$person OR $update) { @@ -601,6 +610,7 @@ class diaspora { `request` = '%s', `nick` = '%s', `addr` = '%s', + `guid` = '%s', `batch` = '%s', `notify` = '%s', `poll` = '%s', @@ -613,7 +623,8 @@ class diaspora { dbesc($arr["photo"]), dbesc($arr["request"]), dbesc($arr["nick"]), - dbesc($arr["addr"]), + dbesc(strtolower($arr["addr"])), + dbesc($arr["guid"]), dbesc($arr["batch"]), dbesc($arr["notify"]), dbesc($arr["poll"]), @@ -625,15 +636,16 @@ class diaspora { dbesc($arr["network"]) ); } else { - $r = q("INSERT INTO `fcontact` (`url`,`name`,`photo`,`request`,`nick`,`addr`, + $r = q("INSERT INTO `fcontact` (`url`,`name`,`photo`,`request`,`nick`,`addr`, `guid`, `batch`, `notify`,`poll`,`confirm`,`network`,`alias`,`pubkey`,`updated`) - VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", + VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')", dbesc($arr["url"]), dbesc($arr["name"]), dbesc($arr["photo"]), dbesc($arr["request"]), dbesc($arr["nick"]), dbesc($arr["addr"]), + dbesc($arr["guid"]), dbesc($arr["batch"]), dbesc($arr["notify"]), dbesc($arr["poll"]), @@ -665,7 +677,7 @@ class diaspora { $r = q("SELECT `addr` FROM `gcontact` WHERE `id` = %d AND `addr` != ''", intval($gcontact_id)); if ($r) - return $r[0]["addr"]; + return strtolower($r[0]["addr"]); } $r = q("SELECT `network`, `addr`, `self`, `url`, `nick` FROM `contact` WHERE `id` = %d", @@ -685,7 +697,7 @@ class diaspora { } } - return $handle; + return strtolower($handle); } /** @@ -794,7 +806,7 @@ class diaspora { dbesc($guid) ); - if($r) { + if ($r) { logger("message ".$guid." already exists for user ".$uid); return $r[0]["id"]; } @@ -987,17 +999,21 @@ class diaspora { */ private function author_contact_by_url($contact, $person, $uid) { - $r = q("SELECT `id`, `network` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1", + $r = q("SELECT `id`, `network`, `url` FROM `contact` WHERE `nurl` = '%s' AND `uid` = %d LIMIT 1", dbesc(normalise_link($person["url"])), intval($uid)); if ($r) { $cid = $r[0]["id"]; $network = $r[0]["network"]; + + // We are receiving content from a user that is about to be terminated + // This means the user is vital, so we remove a possible termination date. + unmark_for_death($contact); } else { $cid = $contact["id"]; $network = NETWORK_DIASPORA; } - return (array("cid" => $cid, "network" => $network)); + return array("cid" => $cid, "network" => $network); } /** @@ -1099,6 +1115,11 @@ class diaspora { $text = unxmlify($data->text); $author = notags(unxmlify($data->author)); + if (isset($data->created_at)) + $created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at))); + else + $created_at = datetime_convert(); + $contact = self::allowed_contact_by_handle($importer, $sender, true); if (!$contact) return false; @@ -1145,6 +1166,8 @@ class diaspora { $datarray["object-type"] = ACTIVITY_OBJ_COMMENT; $datarray["object"] = $xml; + $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; + $datarray["body"] = diaspora2bb($text); self::fetch_guid($datarray); @@ -1165,7 +1188,7 @@ class diaspora { ); // notify others - proc_run("php", "include/notifier.php", "comment-import", $message_id); + proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $message_id); } return $message_id; @@ -1255,7 +1278,7 @@ class diaspora { $r = q("SELECT `id` FROM `mail` WHERE `uri` = '%s' LIMIT 1", dbesc($message_uri) ); - if($r) { + if (dbm::is_result($r)) { logger("duplicate message already delivered.", LOGGER_DEBUG); return false; } @@ -1341,7 +1364,7 @@ class diaspora { intval($importer["uid"]), dbesc($guid), dbesc($author), - dbesc(datetime_convert("UTC", "UTC", $created_at)), + dbesc($created_at), dbesc(datetime_convert()), dbesc($subject), dbesc($participants) @@ -1500,7 +1523,7 @@ class diaspora { ); // notify others - proc_run("php", "include/notifier.php", "comment-import", $message_id); + proc_run(PRIORITY_HIGH, "include/notifier.php", "comment-import", $message_id); } return $message_id; @@ -1554,7 +1577,7 @@ class diaspora { dbesc($message_uri), intval($importer["uid"]) ); - if($r) { + if ($r) { logger("duplicate message already delivered.", LOGGER_DEBUG); return false; } @@ -1633,7 +1656,7 @@ class diaspora { * @return bool Success */ private function receive_profile($importer, $data) { - $author = notags(unxmlify($data->author)); + $author = strtolower(notags(unxmlify($data->author))); $contact = self::contact_by_handle($importer["uid"], $author); if (!$contact) @@ -1780,7 +1803,7 @@ class diaspora { $i = item_store($arr); if($i) - proc_run("php", "include/notifier.php", "activity", $i); + proc_run(PRIORITY_HIGH, "include/notifier.php", "activity", $i); } } } @@ -1838,10 +1861,26 @@ class diaspora { // That makes us friends. if ($contact) { if ($following AND $sharing) { + logger("Author ".$author." (Contact ".$contact["id"].") wants to have a bidirectional conection.", LOGGER_DEBUG); self::receive_request_make_friend($importer, $contact); + + // refetch the contact array + $contact = self::contact_by_handle($importer["uid"],$author); + + // If we are now friends, we are sending a share message. + // Normally we needn't to do so, but the first message could have been vanished. + if (in_array($contact["rel"], array(CONTACT_IS_FRIEND, CONTACT_IS_FOLLOWER))) { + $u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"])); + if($u) { + logger("Sending share message to author ".$author." - Contact: ".$contact["id"]." - User: ".$importer["uid"], LOGGER_DEBUG); + $ret = self::send_share($u[0], $contact); + } + } return true; - } else /// @todo Handle all possible variations of adding and retracting of permissions + } else { /// @todo Handle all possible variations of adding and retracting of permissions + logger("Author ".$author." (Contact ".$contact["id"].") wants to change the relationship: Following: ".$following." - sharing: ".$sharing. "(By now unsupported)", LOGGER_DEBUG); return false; + } } if (!$following AND $sharing AND in_array($importer["page-flags"], array(PAGE_SOAPBOX, PAGE_NORMAL))) { @@ -1850,6 +1889,12 @@ class diaspora { } elseif (!$following AND !$sharing) { logger("Author ".$author." doesn't want anything - and we don't know the author. Request is ignored.", LOGGER_DEBUG); return false; + } elseif (!$following AND $sharing) { + logger("Author ".$author." wants to share with us.", LOGGER_DEBUG); + } elseif ($following AND $sharing) { + logger("Author ".$author." wants to have a bidirectional conection.", LOGGER_DEBUG); + } elseif ($following AND !$sharing) { + logger("Author ".$author." wants to listen to us.", LOGGER_DEBUG); } $ret = self::person_by_handle($author); @@ -1889,6 +1934,8 @@ class diaspora { return; } + logger("Author ".$author." was added as contact number ".$contact_record["id"].".", LOGGER_DEBUG); + $def_gid = get_default_group($importer['uid'], $ret["network"]); if(intval($def_gid)) @@ -1898,6 +1945,8 @@ class diaspora { if($importer["page-flags"] == PAGE_NORMAL) { + logger("Sending intra message for author ".$author.".", LOGGER_DEBUG); + $hash = random_string().(string)time(); // Generate a confirm_key $ret = q("INSERT INTO `intro` (`uid`, `contact-id`, `blocked`, `knowyou`, `note`, `hash`, `datetime`) @@ -1914,6 +1963,8 @@ class diaspora { // automatic friend approval + logger("Does an automatic friend approval for author ".$author.".", LOGGER_DEBUG); + update_contact_avatar($contact_record["photo"],$importer["uid"],$contact_record["id"]); // technically they are sharing with us (CONTACT_IS_SHARING), @@ -1942,8 +1993,13 @@ class diaspora { ); $u = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer["uid"])); - if($u) + if($u) { + logger("Sending share message (Relation: ".$new_relation.") to author ".$author." - Contact: ".$contact_record["id"]." - User: ".$importer["uid"], LOGGER_DEBUG); $ret = self::send_share($u[0], $contact_record); + + // Send the profile data, maybe it weren't transmitted before + self::send_profile($importer["uid"], array($contact_record)); + } } return true; @@ -1966,7 +2022,7 @@ class diaspora { FROM `item` WHERE `guid` = '%s' AND `visible` AND NOT `deleted` AND `body` != '' LIMIT 1", dbesc($guid)); - if($r) { + if ($r) { logger("reshared message ".$guid." already exists on system."); // Maybe it is already a reshared item? @@ -2030,7 +2086,7 @@ class diaspora { $guid = notags(unxmlify($data->guid)); $author = notags(unxmlify($data->author)); $public = notags(unxmlify($data->public)); - $created_at = notags(unxmlify($data->created_at)); + $created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at))); $contact = self::allowed_contact_by_handle($importer, $author, false); if (!$contact) @@ -2077,7 +2133,7 @@ class diaspora { $datarray["plink"] = self::plink($author, $guid); $datarray["private"] = (($public == "false") ? 1 : 0); - $datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert("UTC", "UTC", $created_at); + $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; $datarray["object-type"] = $original_item["object-type"]; @@ -2117,12 +2173,6 @@ class diaspora { if (!$r) return false; - // Only delete it if the author really fits - if (!link_compare($r[0]["author-link"], $person["url"])) { - logger("Item author ".$r[0]["author-link"]." doesn't fit to expected contact ".$person["url"], LOGGER_DEBUG); - return false; - } - // Check if the sender is the thread owner $p = q("SELECT `id`, `author-link`, `origin` FROM `item` WHERE `id` = %d", intval($r[0]["parent"])); @@ -2146,7 +2196,7 @@ class diaspora { // Now check if the retraction needs to be relayed by us if($p[0]["origin"]) { // notify others - proc_run("php", "include/notifier.php", "drop", $r[0]["id"]); + proc_run(PRIORITY_HIGH, "include/notifier.php", "drop", $r[0]["id"]); } return true; @@ -2204,12 +2254,11 @@ class diaspora { * @return int The message id of the newly created item */ private function receive_status_message($importer, $data, $xml) { - $raw_message = unxmlify($data->raw_message); $guid = notags(unxmlify($data->guid)); $author = notags(unxmlify($data->author)); $public = notags(unxmlify($data->public)); - $created_at = notags(unxmlify($data->created_at)); + $created_at = datetime_convert("UTC", "UTC", notags(unxmlify($data->created_at))); $provider_display_name = notags(unxmlify($data->provider_display_name)); /// @todo enable support for polls @@ -2241,7 +2290,7 @@ class diaspora { $body = "[img]".unxmlify($photo->remote_photo_path). unxmlify($photo->remote_photo_name)."[/img]\n".$body; - $datarray["object-type"] = ACTIVITY_OBJ_PHOTO; + $datarray["object-type"] = ACTIVITY_OBJ_IMAGE; } else { $datarray["object-type"] = ACTIVITY_OBJ_NOTE; @@ -2277,7 +2326,7 @@ class diaspora { $datarray["plink"] = self::plink($author, $guid); $datarray["private"] = (($public == "false") ? 1 : 0); - $datarray["changed"] = $datarray["created"] = $datarray["edited"] = datetime_convert("UTC", "UTC", $created_at); + $datarray["changed"] = $datarray["created"] = $datarray["edited"] = $created_at; if (isset($address["address"])) $datarray["location"] = $address["address"]; @@ -2574,7 +2623,7 @@ class diaspora { logger("transmit: ".$logid."-".$guid." returns: ".$return_code); - if(!$return_code || (($return_code == 503) && (stristr($a->get_curl_headers(), "retry-after")))) { + if (!$return_code || (($return_code == 503) && (stristr($a->get_curl_headers(), "retry-after")))) { logger("queue message"); $r = q("SELECT `id` FROM `queue` WHERE `cid` = %d AND `network` = '%s' AND `content` = '%s' AND `batch` = %d LIMIT 1", @@ -2583,12 +2632,18 @@ class diaspora { dbesc($slap), intval($public_batch) ); - if($r) { + if ($r) { logger("add_to_queue ignored - identical item already in queue"); } else { // queue message for redelivery add_to_queue($contact["id"], NETWORK_DIASPORA, $slap, $public_batch); + + // The message could not be delivered. We mark the contact as "dead" + mark_for_death($contact); } + } elseif (($return_code >= 200) AND ($return_code <= 299)) { + // We successfully delivered a message, the contact is alive + unmark_for_death($contact); } return(($return_code) ? $return_code : (-1)); @@ -2629,6 +2684,10 @@ class diaspora { logger('message: '.$msg, LOGGER_DATA); logger('send guid '.$guid, LOGGER_DEBUG); + // Fallback if the private key wasn't transmitted in the expected field + if ($owner['uprvkey'] == "") + $owner['uprvkey'] = $owner['prvkey']; + $slap = self::build_message($msg, $owner, $contact, $owner['uprvkey'], $contact['pubkey'], $public_batch); if ($spool) { @@ -2655,6 +2714,8 @@ class diaspora { $message = array("sender_handle" => self::my_handle($owner), "recipient_handle" => $contact["addr"]); + logger("Send share ".print_r($message, true), LOGGER_DEBUG); + return self::build_and_transmit($owner, $contact, "request", $message); } @@ -2672,6 +2733,8 @@ class diaspora { "diaspora_handle" => self::my_handle($owner), "type" => "Person"); + logger("Send unshare ".print_r($message, true), LOGGER_DEBUG); + return self::build_and_transmit($owner, $contact, "retraction", $message); } @@ -2823,8 +2886,10 @@ class diaspora { "created_at" => $created, "provider_display_name" => $item["app"]); - if (count($location) == 0) + // Diaspora rejects messages when they contain a location without "lat" or "lng" + if (!isset($location["lat"]) OR !isset($location["lng"])) { unset($message["location"]); + } $type = "status_message"; } @@ -2860,7 +2925,7 @@ class diaspora { $p = q("SELECT `guid`, `uri`, `parent-uri` FROM `item` WHERE `uri` = '%s' LIMIT 1", dbesc($item["thr-parent"])); - if(!$p) + if (!dbm::is_result($p)) return false; $parent = $p[0]; @@ -2891,7 +2956,7 @@ class diaspora { intval($item["parent"]) ); - if (!$p) + if (!dbm::is_result($p)) return false; $parent = $p[0]; @@ -3105,7 +3170,7 @@ class diaspora { intval($item["uid"]) ); - if (!$r) { + if (!dbm::is_result($r)) { logger("conversation not found."); return; } @@ -3158,17 +3223,18 @@ class diaspora { * * @param int $uid The user id */ - public static function send_profile($uid) { + public static function send_profile($uid, $recips = false) { if (!$uid) return; - $recips = q("SELECT `id`,`name`,`network`,`pubkey`,`notify` FROM `contact` WHERE `network` = '%s' - AND `uid` = %d AND `rel` != %d", - dbesc(NETWORK_DIASPORA), - intval($uid), - intval(CONTACT_IS_SHARING) - ); + if (!$recips) + $recips = q("SELECT `id`,`name`,`network`,`pubkey`,`notify` FROM `contact` WHERE `network` = '%s' + AND `uid` = %d AND `rel` != %d", + dbesc(NETWORK_DIASPORA), + intval($uid), + intval(CONTACT_IS_SHARING) + ); if (!$recips) return; @@ -3232,8 +3298,10 @@ class diaspora { "searchable" => $searchable, "tag_string" => $tags); - foreach($recips as $recip) + foreach($recips as $recip) { + logger("Send updated profile data for user ".$uid." to contact ".$recip["id"], LOGGER_DEBUG); self::build_and_transmit($profile, $recip, "profile", $message, false, "", true); + } } /**