1
0
Fork 0

XML generation is now improved

This commit is contained in:
Michael Vogel 2016-03-13 09:57:44 +01:00
parent f978bc9cc8
commit f8f19038bf
2 changed files with 105 additions and 95 deletions

View file

@ -729,7 +729,6 @@ class diaspora {
self::fetch_guid($datarray); self::fetch_guid($datarray);
$message_id = item_store($datarray); $message_id = item_store($datarray);
// print_r($datarray);
// If we are the origin of the parent we store the original data and notify our followers // If we are the origin of the parent we store the original data and notify our followers
if($message_id AND $parent_item["origin"]) { if($message_id AND $parent_item["origin"]) {
@ -1013,7 +1012,6 @@ class diaspora {
$datarray["body"] = self::construct_like_body($contact, $parent_item, $guid); $datarray["body"] = self::construct_like_body($contact, $parent_item, $guid);
$message_id = item_store($datarray); $message_id = item_store($datarray);
// print_r($datarray);
// If we are the origin of the parent we store the original data and notify our followers // If we are the origin of the parent we store the original data and notify our followers
if($message_id AND $parent_item["origin"]) { if($message_id AND $parent_item["origin"]) {
@ -1493,7 +1491,6 @@ class diaspora {
self::fetch_guid($datarray); self::fetch_guid($datarray);
$message_id = item_store($datarray); $message_id = item_store($datarray);
// print_r($datarray);
return $message_id; return $message_id;
} }
@ -1662,16 +1659,15 @@ class diaspora {
self::fetch_guid($datarray); self::fetch_guid($datarray);
$message_id = item_store($datarray); $message_id = item_store($datarray);
// print_r($datarray);
logger("Stored item with message id ".$message_id, LOGGER_DEBUG); logger("Stored item with message id ".$message_id, LOGGER_DEBUG);
return $message_id; return $message_id;
} }
/******************************************************************************************* /******************************************************************************************
* Here come all the functions that are needed to transmit data with the Diaspora protocol * * Here are all the functions that are needed to transmit data with the Diaspora protocol *
*******************************************************************************************/ ******************************************************************************************/
private function my_handle($me) { private function my_handle($me) {
if ($contact["addr"] != "") if ($contact["addr"] != "")
@ -1701,21 +1697,18 @@ class diaspora {
$signature = rsa_sign($signable_data,$prvkey); $signature = rsa_sign($signable_data,$prvkey);
$sig = base64url_encode($signature); $sig = base64url_encode($signature);
$magic_env = <<< EOT $xmldata = array("diaspora" => array("header" => array("author_id" => $handle),
<?xml version='1.0' encoding='UTF-8'?> "me:env" => array("me:encoding" => "base64url",
<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env" > "me:alg" => "RSA-SHA256",
<header> "me:data" => $data,
<author_id>$handle</author_id> "@attributes" => array("type" => "application/xml"),
</header> "me:sig" => $sig)));
<me:env>
<me:encoding>base64url</me:encoding> $namespaces = array("" => "https://joindiaspora.com/protocol",
<me:alg>RSA-SHA256</me:alg> "me" => "http://salmon-protocol.org/ns/magic-env");
<me:data type="application/xml">$data</me:data>
<me:sig>$sig</me:sig> $magic_env = xml::from_array($xmldata, $xml, false, $namespaces);
</me:env>
</diaspora>
EOT;
die($magic_env."\n");
logger("magic_env: ".$magic_env, LOGGER_DATA); logger("magic_env: ".$magic_env, LOGGER_DATA);
return $magic_env; return $magic_env;
} }
@ -1783,30 +1776,17 @@ die($magic_env."\n");
"ciphertext" => base64_encode($ciphertext))); "ciphertext" => base64_encode($ciphertext)));
$cipher_json = base64_encode($encrypted_header_json_object); $cipher_json = base64_encode($encrypted_header_json_object);
$xml = nul;
$xmldata = array("diaspora" => array("encrypted_header" => $cipher_json, $xmldata = array("diaspora" => array("encrypted_header" => $cipher_json,
"me:env" => array("me:encoding" => "base64url", "me:env" => array("me:encoding" => "base64url",
"me:alg" => "RSA-SHA256", "me:alg" => "RSA-SHA256",
"me:data" => $data, "me:data" => $data,
"@attributes" => array("type" => "application/xml"),
"me:sig" => $sig))); "me:sig" => $sig)));
$encrypted_header = xml::from_array($xmldata, $xml, true);
echo $encrypted_header."\n";
$encrypted_header = "<encrypted_header>".$cipher_json."</encrypted_header>"; $namespaces = array("" => "https://joindiaspora.com/protocol",
"me" => "http://salmon-protocol.org/ns/magic-env");
$magic_env = <<< EOT $magic_env = xml::from_array($xmldata, $xml, false, $namespaces);
<?xml version='1.0' encoding='UTF-8'?>
<diaspora xmlns="https://joindiaspora.com/protocol" xmlns:me="http://salmon-protocol.org/ns/magic-env" >
$encrypted_header
<me:env>
<me:encoding>base64url</me:encoding>
<me:alg>RSA-SHA256</me:alg>
<me:data type="application/xml">$data</me:data>
<me:sig>$sig</me:sig>
</me:env>
</diaspora>
EOT;
die($magic_env."\n");
logger("magic_env: ".$magic_env, LOGGER_DATA); logger("magic_env: ".$magic_env, LOGGER_DATA);
return $magic_env; return $magic_env;
@ -1896,7 +1876,7 @@ die($magic_env."\n");
logger('send guid '.$guid, LOGGER_DEBUG); logger('send guid '.$guid, LOGGER_DEBUG);
$slap = self::build_message($msg, $owner, $contact, $owner['uprvkey'], $contact['pubkey'], $public_batch); $slap = self::build_message($msg, $owner, $contact, $owner['uprvkey'], $contact['pubkey'], $public_batch);
die($slap);
$return_code = self::transmit($owner, $contact, $slap, $public_batch, false, $guid); $return_code = self::transmit($owner, $contact, $slap, $public_batch, false, $guid);
logger("guid: ".$item["guid"]." result ".$return_code, LOGGER_DEBUG); logger("guid: ".$item["guid"]." result ".$return_code, LOGGER_DEBUG);
@ -2118,51 +2098,24 @@ die($slap);
return self::build_and_transmit($owner, $contact, $type, $message, $public_batch, $item["guid"]); return self::build_and_transmit($owner, $contact, $type, $message, $public_batch, $item["guid"]);
} }
function send_relay($item, $owner, $contact, $public_batch = false) { private function message_from_signatur($item, $signature) {
if ($item["deleted"]) {
$sql_sign_id = "retract_iid";
$type = "relayable_retraction";
} elseif ($item['verb'] === ACTIVITY_LIKE) {
$sql_sign_id = "iid";
$type = "like";
} else {
$sql_sign_id = "iid";
$type = "comment";
}
// fetch the original signature if the relayable was created by a Diaspora
// or DFRN user.
$r = q("SELECT `signed_text`, `signature`, `signer` FROM `sign` WHERE `".$sql_sign_id."` = %d LIMIT 1",
intval($item["id"])
);
if (!$r)
return self::send_followup($item, $owner, $contact, $public_batch);
$orig_sign = $r[0];
// Old way - is used by the internal Friendica functions
/// @todo Change all signatur storing functions to the new format
if ($orig_sign['signed_text'] AND $orig_sign['signature'] AND $orig_sign['signer']) {
// Split the signed text // Split the signed text
$signed_parts = explode(";", $orig_sign['signed_text']); $signed_parts = explode(";", $signature['signed_text']);
if ($item["deleted"]) if ($item["deleted"])
$message = array("parent_author_signature" => "", $message = array("parent_author_signature" => "",
"target_guid" => $signed_parts[0], "target_guid" => $signed_parts[0],
"target_type" => $signed_parts[1], "target_type" => $signed_parts[1],
"sender_handle" => $orig_sign['signer'], "sender_handle" => $signature['signer'],
"target_author_signature" => $orig_sign['signature']); "target_author_signature" => $signature['signature']);
elseif ($item['verb'] === ACTIVITY_LIKE) elseif ($item['verb'] === ACTIVITY_LIKE)
$message = array("positive" => $signed_parts[0], $message = array("positive" => $signed_parts[0],
"guid" => $signed_parts[1], "guid" => $signed_parts[1],
"target_type" => $signed_parts[2], "target_type" => $signed_parts[2],
"parent_guid" => $signed_parts[3], "parent_guid" => $signed_parts[3],
"parent_author_signature" => "", "parent_author_signature" => "",
"author_signature" => $orig_sign['signature'], "author_signature" => $signature['signature'],
"diaspora_handle" => $signed_parts[4]); "diaspora_handle" => $signed_parts[4]);
else { else {
// Remove the comment guid // Remove the comment guid
@ -2180,14 +2133,43 @@ die($slap);
$message = array("guid" => $guid, $message = array("guid" => $guid,
"parent_guid" => $parent_guid, "parent_guid" => $parent_guid,
"parent_author_signature" => "", "parent_author_signature" => "",
"author_signature" => $orig_sign['signature'], "author_signature" => $signature['signature'],
"text" => implode(";", $signed_parts), "text" => implode(";", $signed_parts),
"diaspora_handle" => $handle); "diaspora_handle" => $handle);
} }
} else { // New way return $message;
$message = json_decode($orig_sign['signed_text']);
} }
public static function send_relay($item, $owner, $contact, $public_batch = false) {
if ($item["deleted"]) {
$sql_sign_id = "retract_iid";
$type = "relayable_retraction";
} elseif ($item['verb'] === ACTIVITY_LIKE) {
$sql_sign_id = "iid";
$type = "like";
} else {
$sql_sign_id = "iid";
$type = "comment";
}
// fetch the original signature
$r = q("SELECT `signed_text`, `signature`, `signer` FROM `sign` WHERE `".$sql_sign_id."` = %d LIMIT 1",
intval($item["id"]));
if (!$r)
return self::send_followup($item, $owner, $contact, $public_batch);
$signature = $r[0];
// Old way - is used by the internal Friendica functions
/// @todo Change all signatur storing functions to the new format
if ($signature['signed_text'] AND $signature['signature'] AND $signature['signer'])
$message = self::message_from_signatur($item, $signature);
else // New way
$message = json_decode($signature['signed_text']);
if ($item["deleted"]) { if ($item["deleted"]) {
$signed_text = $message["target_guid"].';'.$message["target_type"]; $signed_text = $message["target_guid"].';'.$message["target_type"];
$message["parent_author_signature"] = base64_encode(rsa_sign($signed_text, $owner["uprvkey"], "sha256")); $message["parent_author_signature"] = base64_encode(rsa_sign($signed_text, $owner["uprvkey"], "sha256"));

View file

@ -4,12 +4,15 @@
* *
*/ */
class xml { class xml {
function from_array($array, &$xml, $remove_header = false) { function from_array($array, &$xml, $remove_header = false, $namespaces = array(), $root = true) {
if (!is_object($xml)) { if ($root) {
foreach($array as $key => $value) { foreach($array as $key => $value) {
foreach ($namespaces AS $nskey => $nsvalue)
$key .= " xmlns".($nskey == "" ? "":":").$nskey.'="'.$nsvalue.'"';
$root = new SimpleXMLElement("<".$key."/>"); $root = new SimpleXMLElement("<".$key."/>");
self::from_array($value, $root); self::from_array($value, $root, $remove_header, $namespaces, false);
$dom = dom_import_simplexml($root)->ownerDocument; $dom = dom_import_simplexml($root)->ownerDocument;
$dom->formatOutput = true; $dom->formatOutput = true;
@ -25,10 +28,35 @@ class xml {
} }
foreach($array as $key => $value) { foreach($array as $key => $value) {
if (!is_array($value) AND !is_numeric($key)) if ($key == "@attributes") {
$xml->addChild($key, xmlify($value)); if (!isset($element) OR !is_array($value))
elseif (is_array($value)) continue;
self::from_array($value, $xml->addChild($key));
foreach ($value as $attr_key => $attr_value) {
$element_parts = explode(":", $attr_key);
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
$namespace = $namespaces[$element_parts[0]];
else
$namespace = NULL;
$element->addAttribute ($attr_key, $attr_value, $namespace);
}
continue;
}
$element_parts = explode(":", $key);
if ((count($element_parts) > 1) AND isset($namespaces[$element_parts[0]]))
$namespace = $namespaces[$element_parts[0]];
else
$namespace = NULL;
if (!is_array($value))
$element = $xml->addChild($key, xmlify($value), $namespace);
elseif (is_array($value)) {
$element = $xml->addChild($key, NULL, $namespace);
self::from_array($value, $element, $remove_header, $namespaces, false);
}
} }
} }