From 2d72e2d93219dfbb3eb237154a8837958cf50ea7 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Wed, 29 Jun 2016 22:50:30 +0200 Subject: [PATCH 1/8] Diaspora: Support for new fetch functionality (replacement for /p/) --- include/diaspora.php | 12 +++--- include/notifier.php | 19 +++++++--- include/xml.php | 2 +- mod/fetch.php | 88 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 13 deletions(-) create mode 100644 mod/fetch.php diff --git a/include/diaspora.php b/include/diaspora.php index c450a10d1..204ac08b9 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2287,10 +2287,10 @@ class diaspora { $sig = base64url_encode($signature); $xmldata = array("diaspora" => array("header" => array("author_id" => $handle), - "me:env" => array("me:encoding" => "base64url", - "me:alg" => "RSA-SHA256", + "me:env" => array("me:encoding" => $encoding, + "me:alg" => $alg, "me:data" => $data, - "@attributes" => array("type" => "application/xml"), + "@attributes" => array("type" => $type), "me:sig" => $sig))); $namespaces = array("" => "https://joindiaspora.com/protocol", @@ -2377,10 +2377,10 @@ class diaspora { $cipher_json = base64_encode($encrypted_header_json_object); $xmldata = array("diaspora" => array("encrypted_header" => $cipher_json, - "me:env" => array("me:encoding" => "base64url", - "me:alg" => "RSA-SHA256", + "me:env" => array("me:encoding" => $encoding, + "me:alg" => $alg, "me:data" => $data, - "@attributes" => array("type" => "application/xml"), + "@attributes" => array("type" => $type), "me:sig" => $sig))); $namespaces = array("" => "https://joindiaspora.com/protocol", diff --git a/include/notifier.php b/include/notifier.php index 7019ffcce..e7eb278ef 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -132,18 +132,25 @@ function notifier_run(&$argv, &$argc){ $recipients[] = $suggest[0]['cid']; $item = $suggest[0]; } elseif($cmd === 'removeme') { - $r = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1", intval($item_id)); - if (! $r) + $r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`, + `user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`, + `user`.`page-flags`, `user`.`prvnets` + FROM `contact` INNER JOIN `user` ON `user`.`uid` = `contact`.`uid` + WHERE `contact`.`uid` = %d AND `contact`.`self` LIMIT 1", + intval($item_id)); + if (!$r) return; $user = $r[0]; - $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1", intval($item_id)); - if (! $r) + + $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($item_id)); + if (!$r) return; $self = $r[0]; - $r = q("SELECT * FROM `contact` WHERE `self` = 0 AND `uid` = %d", intval($item_id)); - if(! $r) + + $r = q("SELECT * FROM `contact` WHERE NOT `self` AND `uid` = %d", intval($item_id)); + if(!$r) return; require_once('include/Contact.php'); diff --git a/include/xml.php b/include/xml.php index 39a9102de..ed2f49fb7 100644 --- a/include/xml.php +++ b/include/xml.php @@ -44,7 +44,7 @@ class xml { } foreach($array as $key => $value) { - if ($key == "@attributes") { + if (substr($key, 0, 11) == "@attributes") { if (!isset($element) OR !is_array($value)) continue; diff --git a/mod/fetch.php b/mod/fetch.php new file mode 100644 index 000000000..457fc86a6 --- /dev/null +++ b/mod/fetch.php @@ -0,0 +1,88 @@ +argc != 3) OR (!in_array($a->argv[1], array("post", "status_message", "reshare")))) { + header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); + killme(); + } + + $guid = $a->argv[2]; + + $item = q("SELECT `uid`, `title`, `body`, `guid`, `contact-id`, `private`, `created`, `app`, `location` + FROM `item` WHERE `wall` AND NOT `private` AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", + dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); + if (!$item) { + header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); + killme(); + } + $post = array(); + + $reshared = diaspora::is_reshare($item[0]["body"]); + + if ($reshared) { + $nodename = "reshare"; + $post["root_diaspora_id"] = $reshared["root_handle"]; + $post["root_guid"] = $reshared["root_guid"]; + $post["guid"] = $item[0]["guid"]; + $post["diaspora_handle"] = diaspora::handle_from_contact($item[0]["contact-id"]); + $post["public"] = (!$item[0]["private"] ? 'true':'false'); + $post["created_at"] = datetime_convert('UTC','UTC',$item[0]["created"]); + } else { + $body = bb2diaspora($item[0]["body"]); + + if(strlen($item[0]["title"])) + $body = "## ".html_entity_decode($item[0]["title"])."\n\n".$body; + + $nodename = "status_message"; + $post["raw_message"] = str_replace("&", "&", $body); + $post["location"] = $item[0]["location"]; + $post["guid"] = $item[0]["guid"]; + $post["diaspora_handle"] = diaspora::handle_from_contact($item[0]["contact-id"]); + $post["public"] = (!$item[0]["private"] ? 'true':'false'); + $post["created_at"] = datetime_convert('UTC','UTC',$item[0]["created"]); + $post["provider_display_name"] = $item[0]["app"]; + } + + $data = array("XML" => array("post" => array($nodename => $post))); + $xml = xml::from_array($data, $xmlobj); + + $r = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d", intval($item[0]["uid"])); + if (!$r) { + header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); + killme(); + } + + $user = $r[0]; + + $key_id = ""; + + $b64url_data = base64url_encode($xml); + $data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); + + $type = "application/xml"; + $encoding = "base64url"; + $alg = "RSA-SHA256"; + $signable_data = $data.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg); + $signature = rsa_sign($signable_data, $user["prvkey"]); + $sig = base64url_encode($signature); + + $xmldata = array("me:env" => array("me:data" => $data, + "@attributes" => array("type" => $type), + "me:encoding" => $encoding, + "me:alg" => $alg, + "me:sig" => $sig, + "@attributes2" => array("key_id" => $key_id))); + + $namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env"); + + $envelope = xml::from_array($xmldata, $xml, false, $namespaces); + header("Content-Type: application/xml; charset=utf-8"); + echo $envelope; + + killme(); +} From c0669d365be829c1043e31dbc3fe9c1267432886 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 00:22:42 +0200 Subject: [PATCH 2/8] The key_id was added --- mod/fetch.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mod/fetch.php b/mod/fetch.php index 457fc86a6..8888649ab 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -2,7 +2,9 @@ /* This file is part of the Diaspora protocol. It is used for fetching single public posts. */ +require_once("include/crypto.php"); require_once("include/diaspora.php"); +require_once("include/xml.php"); function fetch_init($a){ @@ -51,7 +53,7 @@ function fetch_init($a){ $data = array("XML" => array("post" => array($nodename => $post))); $xml = xml::from_array($data, $xmlobj); - $r = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d", intval($item[0]["uid"])); + $r = q("SELECT `guid`, `prvkey` FROM `user` WHERE `uid` = %d", intval($item[0]["uid"])); if (!$r) { header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); killme(); @@ -59,11 +61,10 @@ function fetch_init($a){ $user = $r[0]; - $key_id = ""; - $b64url_data = base64url_encode($xml); $data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); + $key_id = base64url_encode($user["guid"]); $type = "application/xml"; $encoding = "base64url"; $alg = "RSA-SHA256"; From 2c7fd1cb3c81abc1ef816f022fb894ea93c8c5e7 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 01:18:44 +0200 Subject: [PATCH 3/8] It should be now valid --- include/diaspora.php | 2 +- mod/fetch.php | 31 ++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 204ac08b9..3fe9fff5e 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2242,7 +2242,7 @@ class diaspora { * * @return string the handle in the format user@domain.tld */ - private function my_handle($contact) { + function my_handle($contact) { if ($contact["addr"] != "") return $contact["addr"]; diff --git a/mod/fetch.php b/mod/fetch.php index 8888649ab..1db87f417 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -15,7 +15,7 @@ function fetch_init($a){ $guid = $a->argv[2]; - $item = q("SELECT `uid`, `title`, `body`, `guid`, `contact-id`, `private`, `created`, `app`, `location` + $item = q("SELECT `uid`, `title`, `body`, `guid`, `contact-id`, `private`, `created`, `app`, `location`, `coord` FROM `item` WHERE `wall` AND NOT `private` AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); if (!$item) { @@ -35,6 +35,18 @@ function fetch_init($a){ $post["public"] = (!$item[0]["private"] ? 'true':'false'); $post["created_at"] = datetime_convert('UTC','UTC',$item[0]["created"]); } else { + + $location = array(); + + if ($item[0]["location"] != "") + $location["address"] = $item[0]["location"]; + + if ($item[0]["coord"] != "") { + $coord = explode(" ", $item[0]["coord"]); + $location["lat"] = $coord[0]; + $location["lng"] = $coord[1]; + } + $body = bb2diaspora($item[0]["body"]); if(strlen($item[0]["title"])) @@ -42,7 +54,7 @@ function fetch_init($a){ $nodename = "status_message"; $post["raw_message"] = str_replace("&", "&", $body); - $post["location"] = $item[0]["location"]; + $post["location"] = $location; $post["guid"] = $item[0]["guid"]; $post["diaspora_handle"] = diaspora::handle_from_contact($item[0]["contact-id"]); $post["public"] = (!$item[0]["private"] ? 'true':'false'); @@ -53,7 +65,9 @@ function fetch_init($a){ $data = array("XML" => array("post" => array($nodename => $post))); $xml = xml::from_array($data, $xmlobj); - $r = q("SELECT `guid`, `prvkey` FROM `user` WHERE `uid` = %d", intval($item[0]["uid"])); + $r = q("SELECT `user`.`prvkey`, `contact`.`addr`, `user`.`nickname`, `contact`.`nick` FROM `user` + INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` + WHERE `user`.`uid` = %d", intval($item[0]["uid"])); if (!$r) { header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); killme(); @@ -64,7 +78,7 @@ function fetch_init($a){ $b64url_data = base64url_encode($xml); $data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); - $key_id = base64url_encode($user["guid"]); + $key_id = base64url_encode(diaspora::my_handle($user)); $type = "application/xml"; $encoding = "base64url"; $alg = "RSA-SHA256"; @@ -81,9 +95,12 @@ function fetch_init($a){ $namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env"); - $envelope = xml::from_array($xmldata, $xml, false, $namespaces); - header("Content-Type: application/xml; charset=utf-8"); - echo $envelope; + //header("Content-Type: application/xml; charset=utf-8"); + //echo $xml; + //killme(); + $envelope = xml::from_array($xmldata, $xml, false, $namespaces); + header("Content-Type: application/magic-envelope+xml; charset=utf-8"); + echo $envelope; killme(); } From 99f0746660ec51f7ec244bf1eb3c2e42f831b847 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 07:32:07 +0200 Subject: [PATCH 4/8] Cleaned up the code --- include/diaspora.php | 74 +++++++++++++++++++++++++++++++++++++------- mod/fetch.php | 74 ++++++-------------------------------------- mod/p.php | 60 +++++++++-------------------------- 3 files changed, 85 insertions(+), 123 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 3fe9fff5e..8e206533d 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2242,7 +2242,7 @@ class diaspora { * * @return string the handle in the format user@domain.tld */ - function my_handle($contact) { + private function my_handle($contact) { if ($contact["addr"] != "") return $contact["addr"]; @@ -2256,6 +2256,40 @@ class diaspora { return $nick."@".substr(App::get_baseurl(), strpos(App::get_baseurl(),"://") + 3); } + /** + * @brief Creates the envelope for the "fetch" endpoint + * + * @param string $msg The message that is to be transmitted + * @param array $user The record of the sender + * + * @return string The envelope + */ + + function build_magic_envelope($msg, $user) { + + $b64url_data = base64url_encode($msg); + $data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); + + $key_id = base64url_encode(diaspora::my_handle($user)); + $type = "application/xml"; + $encoding = "base64url"; + $alg = "RSA-SHA256"; + $signable_data = $data.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg); + $signature = rsa_sign($signable_data, $user["prvkey"]); + $sig = base64url_encode($signature); + + $xmldata = array("me:env" => array("me:data" => $data, + "@attributes" => array("type" => $type), + "me:encoding" => $encoding, + "me:alg" => $alg, + "me:sig" => $sig, + "@attributes2" => array("key_id" => $key_id))); + + $namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env"); + + return xml::from_array($xmldata, $xml, false, $namespaces); + } + /** * @brief Creates the envelope for a public message * @@ -2287,11 +2321,11 @@ class diaspora { $sig = base64url_encode($signature); $xmldata = array("diaspora" => array("header" => array("author_id" => $handle), - "me:env" => array("me:encoding" => $encoding, - "me:alg" => $alg, - "me:data" => $data, - "@attributes" => array("type" => $type), - "me:sig" => $sig))); + "me:env" => array("me:encoding" => $encoding, + "me:alg" => $alg, + "me:data" => $data, + "@attributes" => array("type" => $type), + "me:sig" => $sig))); $namespaces = array("" => "https://joindiaspora.com/protocol", "me" => "http://salmon-protocol.org/ns/magic-env"); @@ -2647,16 +2681,16 @@ class diaspora { } /** - * @brief Sends a post + * @brief Create a post (status message or reshare) * * @param array $item The item that will be exported * @param array $owner the array of the item owner - * @param array $contact Target of the communication - * @param bool $public_batch Is it a public post? * - * @return int The result of the transmission + * @return array + * 'type' -> Message type ("status_message" or "reshare") + * 'message' -> Array of XML elements of the status */ - public static function send_status($item, $owner, $contact, $public_batch = false) { + public static function build_status($item, $owner) { $myaddr = self::my_handle($owner); @@ -2719,8 +2753,24 @@ class diaspora { $type = "status_message"; } + return array("type" => $type, "message" => $message); + } - return self::build_and_transmit($owner, $contact, $type, $message, $public_batch, $item["guid"]); + /** + * @brief Sends a post + * + * @param array $item The item that will be exported + * @param array $owner the array of the item owner + * @param array $contact Target of the communication + * @param bool $public_batch Is it a public post? + * + * @return int The result of the transmission + */ + public static function send_status($item, $owner, $contact, $public_batch = false) { + + $status = diaspora::build_status($item, $owner); + + return self::build_and_transmit($owner, $contact, $status["type"], $status["message"], $public_batch, $item["guid"]); } /** diff --git a/mod/fetch.php b/mod/fetch.php index 1db87f417..5db6250a2 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -15,56 +15,16 @@ function fetch_init($a){ $guid = $a->argv[2]; + // Fetch the item $item = q("SELECT `uid`, `title`, `body`, `guid`, `contact-id`, `private`, `created`, `app`, `location`, `coord` - FROM `item` WHERE `wall` AND NOT `private` AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", + FROM `item` WHERE `wall` AND NOT `private` AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); if (!$item) { header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); killme(); } - $post = array(); - - $reshared = diaspora::is_reshare($item[0]["body"]); - - if ($reshared) { - $nodename = "reshare"; - $post["root_diaspora_id"] = $reshared["root_handle"]; - $post["root_guid"] = $reshared["root_guid"]; - $post["guid"] = $item[0]["guid"]; - $post["diaspora_handle"] = diaspora::handle_from_contact($item[0]["contact-id"]); - $post["public"] = (!$item[0]["private"] ? 'true':'false'); - $post["created_at"] = datetime_convert('UTC','UTC',$item[0]["created"]); - } else { - - $location = array(); - - if ($item[0]["location"] != "") - $location["address"] = $item[0]["location"]; - - if ($item[0]["coord"] != "") { - $coord = explode(" ", $item[0]["coord"]); - $location["lat"] = $coord[0]; - $location["lng"] = $coord[1]; - } - - $body = bb2diaspora($item[0]["body"]); - - if(strlen($item[0]["title"])) - $body = "## ".html_entity_decode($item[0]["title"])."\n\n".$body; - - $nodename = "status_message"; - $post["raw_message"] = str_replace("&", "&", $body); - $post["location"] = $location; - $post["guid"] = $item[0]["guid"]; - $post["diaspora_handle"] = diaspora::handle_from_contact($item[0]["contact-id"]); - $post["public"] = (!$item[0]["private"] ? 'true':'false'); - $post["created_at"] = datetime_convert('UTC','UTC',$item[0]["created"]); - $post["provider_display_name"] = $item[0]["app"]; - } - - $data = array("XML" => array("post" => array($nodename => $post))); - $xml = xml::from_array($data, $xmlobj); + // Fetch some data from the author (We could combine both queries - but I think this is more readable) $r = q("SELECT `user`.`prvkey`, `contact`.`addr`, `user`.`nickname`, `contact`.`nick` FROM `user` INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d", intval($item[0]["uid"])); @@ -72,35 +32,19 @@ function fetch_init($a){ header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); killme(); } - $user = $r[0]; - $b64url_data = base64url_encode($xml); - $data = str_replace(array("\n", "\r", " ", "\t"), array("", "", "", ""), $b64url_data); + $status = diaspora::build_status($item[0], $user); + $data = array("XML" => array("post" => array($status["type"] => $status["message"]))); + $xml = xml::from_array($data, $xmlobj); - $key_id = base64url_encode(diaspora::my_handle($user)); - $type = "application/xml"; - $encoding = "base64url"; - $alg = "RSA-SHA256"; - $signable_data = $data.".".base64url_encode($type).".".base64url_encode($encoding).".".base64url_encode($alg); - $signature = rsa_sign($signable_data, $user["prvkey"]); - $sig = base64url_encode($signature); - - $xmldata = array("me:env" => array("me:data" => $data, - "@attributes" => array("type" => $type), - "me:encoding" => $encoding, - "me:alg" => $alg, - "me:sig" => $sig, - "@attributes2" => array("key_id" => $key_id))); - - $namespaces = array("me" => "http://salmon-protocol.org/ns/magic-env"); + // Send the envelope + header("Content-Type: application/magic-envelope+xml; charset=utf-8"); + echo diaspora::build_magic_envelope($xml, $user); //header("Content-Type: application/xml; charset=utf-8"); //echo $xml; //killme(); - $envelope = xml::from_array($xmldata, $xml, false, $namespaces); - header("Content-Type: application/magic-envelope+xml; charset=utf-8"); - echo $envelope; killme(); } diff --git a/mod/p.php b/mod/p.php index 20d6cfdba..ae25a0889 100644 --- a/mod/p.php +++ b/mod/p.php @@ -19,62 +19,30 @@ function p_init($a){ $guid = strtolower(substr($guid, 0, -4)); - $item = q("SELECT `title`, `body`, `guid`, `contact-id`, `private`, `created`, `app` FROM `item` WHERE `uid` = 0 AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", + // Fetch the item + $item = q("SELECT `uid`, `title`, `body`, `guid`, `contact-id`, `private`, `created`, `app`, `location`, `coord` + FROM `item` WHERE `wall` AND NOT `private` AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); if (!$item) { header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); killme(); } - $post = array(); - - $reshared = diaspora::is_reshare($item[0]["body"]); - - if ($reshared) { - $nodename = "reshare"; - $post["root_diaspora_id"] = $reshared["root_handle"]; - $post["root_guid"] = $reshared["root_guid"]; - $post["guid"] = $item[0]["guid"]; - $post["diaspora_handle"] = diaspora::handle_from_contact($item[0]["contact-id"]); - $post["public"] = (!$item[0]["private"] ? 'true':'false'); - $post["created_at"] = datetime_convert('UTC','UTC',$item[0]["created"]); - } else { - - $body = bb2diaspora($item[0]["body"]); - - if(strlen($item[0]["title"])) - $body = "## ".html_entity_decode($item[0]["title"])."\n\n".$body; - - $nodename = "status_message"; - $post["raw_message"] = str_replace("&", "&", $body); - $post["guid"] = $item[0]["guid"]; - $post["diaspora_handle"] = diaspora::handle_from_contact($item[0]["contact-id"]); - $post["public"] = (!$item[0]["private"] ? 'true':'false'); - $post["created_at"] = datetime_convert('UTC','UTC',$item[0]["created"]); - $post["provider_display_name"] = $item[0]["app"]; + // Fetch some data from the author (We could combine both queries - but I think this is more readable) + $r = q("SELECT `user`.`prvkey`, `contact`.`addr`, `user`.`nickname`, `contact`.`nick` FROM `user` + INNER JOIN `contact` ON `contact`.`uid` = `user`.`uid` + WHERE `user`.`uid` = %d", intval($item[0]["uid"])); + if (!$r) { + header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); + killme(); } + $user = $r[0]; - $dom = new DOMDocument("1.0"); - $root = $dom->createElement("XML"); - $dom->appendChild($root); - $postelement = $dom->createElement("post"); - $root->appendChild($postelement); - $statuselement = $dom->createElement($nodename); - $postelement->appendChild($statuselement); - - foreach($post AS $index => $value) { - $postnode = $dom->createElement($index, $value); - $statuselement->appendChild($postnode); - } + $status = diaspora::build_status($item[0], $user); + $data = array("XML" => array("post" => array($status["type"] => $status["message"]))); + $xml = xml::from_array($data, $xmlobj); header("Content-Type: application/xml; charset=utf-8"); - $xml = $dom->saveXML(); - - // Diaspora doesn't send the XML header, so we remove them as well. - // So we avoid possible compatibility problems. - if (substr($xml, 0, 21) == '') - $xml = trim(substr($xml, 21)); - echo $xml; killme(); From d1259398887b092f991ed6ac893c9cac9792ab3d Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 07:46:00 +0200 Subject: [PATCH 5/8] Just some more centralised functionality --- include/diaspora.php | 18 +++++++++++++++--- mod/fetch.php | 7 +------ mod/p.php | 3 +-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index 8e206533d..1e8d586c7 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2532,6 +2532,20 @@ class diaspora { } + /** + * @brief Build the post xml + * + * @param string $type The message type + * @param array $message The message data + * + * @return string The post XML + */ + public static function build_post_xml($type, $message) { + + $data = array("XML" => array("post" => array($type => $message))); + return xml::from_array($data, $xml); + } + /** * @brief Builds and transmit messages * @@ -2547,9 +2561,7 @@ class diaspora { */ private function build_and_transmit($owner, $contact, $type, $message, $public_batch = false, $guid = "", $spool = false) { - $data = array("XML" => array("post" => array($type => $message))); - - $msg = xml::from_array($data, $xml); + $msg = build_post_xml($type, $message); logger('message: '.$msg, LOGGER_DATA); logger('send guid '.$guid, LOGGER_DEBUG); diff --git a/mod/fetch.php b/mod/fetch.php index 5db6250a2..70766e8e5 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -35,16 +35,11 @@ function fetch_init($a){ $user = $r[0]; $status = diaspora::build_status($item[0], $user); - $data = array("XML" => array("post" => array($status["type"] => $status["message"]))); - $xml = xml::from_array($data, $xmlobj); + $xml = diaspora::build_post_xml($status["type"], $status["message"]); // Send the envelope header("Content-Type: application/magic-envelope+xml; charset=utf-8"); echo diaspora::build_magic_envelope($xml, $user); - //header("Content-Type: application/xml; charset=utf-8"); - //echo $xml; - //killme(); - killme(); } diff --git a/mod/p.php b/mod/p.php index ae25a0889..80333ef21 100644 --- a/mod/p.php +++ b/mod/p.php @@ -39,8 +39,7 @@ function p_init($a){ $user = $r[0]; $status = diaspora::build_status($item[0], $user); - $data = array("XML" => array("post" => array($status["type"] => $status["message"]))); - $xml = xml::from_array($data, $xmlobj); + $xml = diaspora::build_post_xml($status["type"], $status["message"]); header("Content-Type: application/xml; charset=utf-8"); echo $xml; From 24e0fffa2e6bbbdab7b3bcd26b92f08e6fce68fa Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 07:56:06 +0200 Subject: [PATCH 6/8] Small bugfix --- include/diaspora.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/diaspora.php b/include/diaspora.php index 1e8d586c7..18206be8e 100644 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -2561,7 +2561,7 @@ class diaspora { */ private function build_and_transmit($owner, $contact, $type, $message, $public_batch = false, $guid = "", $spool = false) { - $msg = build_post_xml($type, $message); + $msg = self::build_post_xml($type, $message); logger('message: '.$msg, LOGGER_DATA); logger('send guid '.$guid, LOGGER_DEBUG); From 53412236173759ac0e307479bd13024d8d318893 Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 08:55:26 +0200 Subject: [PATCH 7/8] Do a redirect when the post doesn't come from our system but we know where it comes from. --- mod/fetch.php | 14 ++++++++++++++ mod/p.php | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/mod/fetch.php b/mod/fetch.php index 70766e8e5..f0838af50 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -20,6 +20,20 @@ function fetch_init($a){ FROM `item` WHERE `wall` AND NOT `private` AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); if (!$item) { + $r = q("SELECT `author-link` + FROM `item` WHERE `uid` = 0 AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", + dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); + if ($r) { + $parts = parse_url($r[0]["author-link"]); + $host = $parts["scheme"]."://".$parts["host"]; + + $location = $host."/fetch/".$a->argv[1]."/".$guid; + + header("HTTP/1.1 301 Moved Permanently"); + header("Location:".$location); + killme(); + } + header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); killme(); } diff --git a/mod/p.php b/mod/p.php index 80333ef21..df904372a 100644 --- a/mod/p.php +++ b/mod/p.php @@ -24,6 +24,20 @@ function p_init($a){ FROM `item` WHERE `wall` AND NOT `private` AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); if (!$item) { + $r = q("SELECT `author-link` + FROM `item` WHERE `uid` = 0 AND `guid` = '%s' AND `network` IN ('%s', '%s') AND `id` = `parent` LIMIT 1", + dbesc($guid), NETWORK_DFRN, NETWORK_DIASPORA); + if ($r) { + $parts = parse_url($r[0]["author-link"]); + $host = $parts["scheme"]."://".$parts["host"]; + + $location = $host."/p/".$guid.".xml"; + + header("HTTP/1.1 301 Moved Permanently"); + header("Location:".$location); + killme(); + } + header($_SERVER["SERVER_PROTOCOL"].' 404 '.t('Not Found')); killme(); } From 6f203b0a7533ae28e241bb22f4c140982396fadb Mon Sep 17 00:00:00 2001 From: Michael Vogel Date: Thu, 30 Jun 2016 08:58:36 +0200 Subject: [PATCH 8/8] urlencode is better --- mod/fetch.php | 2 +- mod/p.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mod/fetch.php b/mod/fetch.php index f0838af50..cfcd82bb3 100644 --- a/mod/fetch.php +++ b/mod/fetch.php @@ -27,7 +27,7 @@ function fetch_init($a){ $parts = parse_url($r[0]["author-link"]); $host = $parts["scheme"]."://".$parts["host"]; - $location = $host."/fetch/".$a->argv[1]."/".$guid; + $location = $host."/fetch/".$a->argv[1]."/".urlencode($guid); header("HTTP/1.1 301 Moved Permanently"); header("Location:".$location); diff --git a/mod/p.php b/mod/p.php index df904372a..899b51116 100644 --- a/mod/p.php +++ b/mod/p.php @@ -31,7 +31,7 @@ function p_init($a){ $parts = parse_url($r[0]["author-link"]); $host = $parts["scheme"]."://".$parts["host"]; - $location = $host."/p/".$guid.".xml"; + $location = $host."/p/".urlencode($guid).".xml"; header("HTTP/1.1 301 Moved Permanently"); header("Location:".$location);