Merge pull request #4900 from annando/dfrn-rework
Preparation for transmitting public posts via DFRN
This commit is contained in:
commit
952b057631
2 changed files with 123 additions and 82 deletions
|
@ -25,42 +25,13 @@ function dfrn_notify_post(App $a) {
|
||||||
$data = json_decode($postdata);
|
$data = json_decode($postdata);
|
||||||
if (is_object($data)) {
|
if (is_object($data)) {
|
||||||
$nick = defaults($a->argv, 1, '');
|
$nick = defaults($a->argv, 1, '');
|
||||||
|
|
||||||
$user = dba::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]);
|
$user = dba::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]);
|
||||||
if (!DBM::is_result($user)) {
|
if (!DBM::is_result($user)) {
|
||||||
System::httpExit(500);
|
System::httpExit(500);
|
||||||
}
|
}
|
||||||
$msg = Diaspora::decodeRaw($user, $postdata);
|
dfrn_dispatch_private($user, $postdata);
|
||||||
|
} elseif (!dfrn_dispatch_public($postdata)) {
|
||||||
// Check if the user has got this contact
|
|
||||||
$cid = Contact::getIdForURL($msg['author'], $user['uid']);
|
|
||||||
if (!$cid) {
|
|
||||||
// Otherwise there should be a public contact
|
|
||||||
$cid = Contact::getIdForURL($msg['author']);
|
|
||||||
if (!$cid) {
|
|
||||||
logger('Contact not found for address ' . $msg['author']);
|
|
||||||
System::xmlExit(3, 'Contact not found');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We now have some contact, so we fetch it
|
|
||||||
$importer = dba::fetch_first("SELECT *, `name` as `senderName`
|
|
||||||
FROM `contact`
|
|
||||||
WHERE NOT `blocked` AND `id` = ? LIMIT 1",
|
|
||||||
$cid);
|
|
||||||
|
|
||||||
// This should never fail
|
|
||||||
if (!DBM::is_result($importer)) {
|
|
||||||
logger('Contact not found for address ' . $msg['author']);
|
|
||||||
System::xmlExit(3, 'Contact not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the user id. This is important if this is a public contact
|
|
||||||
$importer['importer_uid'] = $user['uid'];
|
|
||||||
|
|
||||||
// Now we should be able to import it
|
|
||||||
$ret = DFRN::import($msg['message'], $importer);
|
|
||||||
System::xmlExit($ret, 'Done');
|
|
||||||
} else {
|
|
||||||
require_once 'mod/salmon.php';
|
require_once 'mod/salmon.php';
|
||||||
salmon_post($a, $postdata);
|
salmon_post($a, $postdata);
|
||||||
}
|
}
|
||||||
|
@ -91,19 +62,12 @@ function dfrn_notify_post(App $a) {
|
||||||
$dfrn_id = substr($dfrn_id, 2);
|
$dfrn_id = substr($dfrn_id, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1",
|
if (!dba::exists('challenge', ['dfrn-id' => $dfrn_id, 'challenge' => $challenge])) {
|
||||||
dbesc($dfrn_id),
|
logger('could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
|
||||||
dbesc($challenge)
|
|
||||||
);
|
|
||||||
if (! DBM::is_result($r)) {
|
|
||||||
logger('dfrn_notify: could not match challenge to dfrn_id ' . $dfrn_id . ' challenge=' . $challenge);
|
|
||||||
System::xmlExit(3, 'Could not match challenge');
|
System::xmlExit(3, 'Could not match challenge');
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s'",
|
dba::delete('challenge', ['dfrn-id' => $dfrn_id, 'challenge' => $challenge]);
|
||||||
dbesc($dfrn_id),
|
|
||||||
dbesc($challenge)
|
|
||||||
);
|
|
||||||
|
|
||||||
// find the local user who owns this relationship.
|
// find the local user who owns this relationship.
|
||||||
|
|
||||||
|
@ -144,7 +108,7 @@ function dfrn_notify_post(App $a) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!DBM::is_result($r)) {
|
if (!DBM::is_result($r)) {
|
||||||
logger('dfrn_notify: contact not found for dfrn_id ' . $dfrn_id);
|
logger('contact not found for dfrn_id ' . $dfrn_id);
|
||||||
System::xmlExit(3, 'Contact not found');
|
System::xmlExit(3, 'Contact not found');
|
||||||
//NOTREACHED
|
//NOTREACHED
|
||||||
}
|
}
|
||||||
|
@ -153,15 +117,11 @@ function dfrn_notify_post(App $a) {
|
||||||
|
|
||||||
$importer = $r[0];
|
$importer = $r[0];
|
||||||
|
|
||||||
logger("Remote rino version: ".$rino_remote." for ".$importer["url"], LOGGER_DEBUG);
|
|
||||||
|
|
||||||
if ((($writable != (-1)) && ($writable != $importer['writable'])) || ($importer['forum'] != $forum) || ($importer['prv'] != $prv)) {
|
if ((($writable != (-1)) && ($writable != $importer['writable'])) || ($importer['forum'] != $forum) || ($importer['prv'] != $prv)) {
|
||||||
q("UPDATE `contact` SET `writable` = %d, forum = %d, prv = %d WHERE `id` = %d",
|
$fields = ['writable' => ($writable == (-1)) ? $importer['writable'] : $writable,
|
||||||
intval(($writable == (-1)) ? $importer['writable'] : $writable),
|
'forum' => $forum, 'prv' => $prv];
|
||||||
intval($forum),
|
dba::update('contact', $fields, ['id' => $importer['id']]);
|
||||||
intval($prv),
|
|
||||||
intval($importer['id'])
|
|
||||||
);
|
|
||||||
if ($writable != (-1)) {
|
if ($writable != (-1)) {
|
||||||
$importer['writable'] = $writable;
|
$importer['writable'] = $writable;
|
||||||
}
|
}
|
||||||
|
@ -173,8 +133,7 @@ function dfrn_notify_post(App $a) {
|
||||||
|
|
||||||
$importer = Contact::updateSslPolicy($importer, $ssl_policy);
|
$importer = Contact::updateSslPolicy($importer, $ssl_policy);
|
||||||
|
|
||||||
logger('dfrn_notify: received notify from ' . $importer['name'] . ' for ' . $importer['username']);
|
logger('data: ' . $data, LOGGER_DATA);
|
||||||
logger('dfrn_notify: data: ' . $data, LOGGER_DATA);
|
|
||||||
|
|
||||||
if ($dissolve == 1) {
|
if ($dissolve == 1) {
|
||||||
// Relationship is dissolved permanently
|
// Relationship is dissolved permanently
|
||||||
|
@ -186,8 +145,6 @@ function dfrn_notify_post(App $a) {
|
||||||
$rino = Config::get('system', 'rino_encrypt');
|
$rino = Config::get('system', 'rino_encrypt');
|
||||||
$rino = intval($rino);
|
$rino = intval($rino);
|
||||||
|
|
||||||
logger("Local rino version: " . $rino, LOGGER_DEBUG);
|
|
||||||
|
|
||||||
if (strlen($key)) {
|
if (strlen($key)) {
|
||||||
|
|
||||||
// if local rino is lower than remote rino, abort: should not happen!
|
// if local rino is lower than remote rino, abort: should not happen!
|
||||||
|
@ -198,17 +155,18 @@ function dfrn_notify_post(App $a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$rawkey = hex2bin(trim($key));
|
$rawkey = hex2bin(trim($key));
|
||||||
logger('rino: md5 raw key: ' . md5($rawkey));
|
logger('rino: md5 raw key: ' . md5($rawkey), LOGGER_DATA);
|
||||||
|
|
||||||
$final_key = '';
|
$final_key = '';
|
||||||
|
|
||||||
if ($dfrn_version >= 2.1) {
|
if ($dfrn_version >= 2.1) {
|
||||||
if ((($importer['duplex']) && strlen($importer['cprvkey'])) || (! strlen($importer['cpubkey']))) {
|
if (($importer['duplex'] && strlen($importer['cprvkey'])) || !strlen($importer['cpubkey'])) {
|
||||||
openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
|
openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
|
||||||
} else {
|
} else {
|
||||||
openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
|
openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((($importer['duplex']) && strlen($importer['cpubkey'])) || (! strlen($importer['cprvkey']))) {
|
if (($importer['duplex'] && strlen($importer['cpubkey'])) || !strlen($importer['cprvkey'])) {
|
||||||
openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
|
openssl_public_decrypt($rawkey, $final_key, $importer['cpubkey']);
|
||||||
} else {
|
} else {
|
||||||
openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
|
openssl_private_decrypt($rawkey, $final_key, $importer['cprvkey']);
|
||||||
|
@ -230,12 +188,92 @@ function dfrn_notify_post(App $a) {
|
||||||
logger('rino: decrypted data: ' . $data, LOGGER_DATA);
|
logger('rino: decrypted data: ' . $data, LOGGER_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger('Importing post from ' . $importer['addr'] . ' to ' . $importer['nickname'] . ' with the RINO ' . $rino_remote . ' encryption.', LOGGER_DEBUG);
|
||||||
|
|
||||||
$ret = DFRN::import($data, $importer);
|
$ret = DFRN::import($data, $importer);
|
||||||
System::xmlExit($ret, 'Processed');
|
System::xmlExit($ret, 'Processed');
|
||||||
|
|
||||||
// NOTREACHED
|
// NOTREACHED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dfrn_dispatch_public($postdata)
|
||||||
|
{
|
||||||
|
/// @todo Currently disabled, until there is a working item distribution for public posts
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$msg = Diaspora::decodeRaw([], $postdata);
|
||||||
|
if (!$msg) {
|
||||||
|
// We have to fail silently to be able to hand it over to the salmon parser
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the corresponding public contact
|
||||||
|
$contact = Contact::getDetailsByAddr($msg['author'], 0);
|
||||||
|
if (!$contact) {
|
||||||
|
logger('Contact not found for address ' . $msg['author']);
|
||||||
|
System::xmlExit(3, 'Contact not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now have some contact, so we fetch it
|
||||||
|
$importer = dba::fetch_first("SELECT *, `name` as `senderName`
|
||||||
|
FROM `contact`
|
||||||
|
WHERE NOT `blocked` AND `id` = ? LIMIT 1",
|
||||||
|
$contact['id']);
|
||||||
|
|
||||||
|
$importer['importer_uid'] = 0;
|
||||||
|
|
||||||
|
// This should never fail
|
||||||
|
if (!DBM::is_result($importer)) {
|
||||||
|
logger('Contact not found for address ' . $msg['author']);
|
||||||
|
System::xmlExit(3, 'Contact not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
logger('Importing post from ' . $msg['author'] . ' with the public envelope.', LOGGER_DEBUG);
|
||||||
|
|
||||||
|
// Now we should be able to import it
|
||||||
|
$ret = DFRN::import($msg['message'], $importer);
|
||||||
|
System::xmlExit($ret, 'Done');
|
||||||
|
}
|
||||||
|
|
||||||
|
function dfrn_dispatch_private($user, $postdata)
|
||||||
|
{
|
||||||
|
$msg = Diaspora::decodeRaw($user, $postdata);
|
||||||
|
if (!$msg) {
|
||||||
|
System::xmlExit(4, 'Unable to parse message');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user has got this contact
|
||||||
|
$cid = Contact::getIdForURL($msg['author'], $user['uid']);
|
||||||
|
if (!$cid) {
|
||||||
|
// Otherwise there should be a public contact
|
||||||
|
$cid = Contact::getIdForURL($msg['author']);
|
||||||
|
if (!$cid) {
|
||||||
|
logger('Contact not found for address ' . $msg['author']);
|
||||||
|
System::xmlExit(3, 'Contact not found');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now have some contact, so we fetch it
|
||||||
|
$importer = dba::fetch_first("SELECT *, `name` as `senderName`
|
||||||
|
FROM `contact`
|
||||||
|
WHERE NOT `blocked` AND `id` = ? LIMIT 1",
|
||||||
|
$cid);
|
||||||
|
|
||||||
|
// This should never fail
|
||||||
|
if (!DBM::is_result($importer)) {
|
||||||
|
logger('Contact not found for address ' . $msg['author']);
|
||||||
|
System::xmlExit(3, 'Contact not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the user id. This is important if this is a public contact
|
||||||
|
$importer['importer_uid'] = $user['uid'];
|
||||||
|
|
||||||
|
logger('Importing post from ' . $msg['author'] . ' to ' . $user['nickname'] . ' with the private envelope.', LOGGER_DEBUG);
|
||||||
|
|
||||||
|
// Now we should be able to import it
|
||||||
|
$ret = DFRN::import($msg['message'], $importer);
|
||||||
|
System::xmlExit($ret, 'Done');
|
||||||
|
}
|
||||||
|
|
||||||
function dfrn_notify_content(App $a) {
|
function dfrn_notify_content(App $a) {
|
||||||
|
|
||||||
|
@ -252,7 +290,7 @@ function dfrn_notify_content(App $a) {
|
||||||
$type = "";
|
$type = "";
|
||||||
$last_update = "";
|
$last_update = "";
|
||||||
|
|
||||||
logger('dfrn_notify: new notification dfrn_id=' . $dfrn_id);
|
logger('new notification dfrn_id=' . $dfrn_id);
|
||||||
|
|
||||||
$direction = (-1);
|
$direction = (-1);
|
||||||
if (strpos($dfrn_id,':') == 1) {
|
if (strpos($dfrn_id,':') == 1) {
|
||||||
|
@ -264,18 +302,13 @@ function dfrn_notify_content(App $a) {
|
||||||
|
|
||||||
$status = 0;
|
$status = 0;
|
||||||
|
|
||||||
$r = q("DELETE FROM `challenge` WHERE `expire` < " . intval(time()));
|
dba::delete('challenge', ["`expire` < ?", time()]);
|
||||||
|
|
||||||
$r = q("INSERT INTO `challenge` ( `challenge`, `dfrn-id`, `expire` , `type`, `last_update` )
|
$fields = ['challenge' => $hash, 'dfrn-id' => $dfrn_id, 'expire' => time() + 90,
|
||||||
VALUES( '%s', '%s', %d, '%s', '%s' ) ",
|
'type' => $type, 'last_update' => $last_update];
|
||||||
dbesc($hash),
|
dba::insert('challenge', $fields);
|
||||||
dbesc($dfrn_id),
|
|
||||||
intval(time() + 90 ),
|
|
||||||
dbesc($type),
|
|
||||||
dbesc($last_update)
|
|
||||||
);
|
|
||||||
|
|
||||||
logger('dfrn_notify: challenge=' . $hash, LOGGER_DEBUG);
|
logger('challenge=' . $hash, LOGGER_DATA);
|
||||||
|
|
||||||
$sql_extra = '';
|
$sql_extra = '';
|
||||||
switch($direction) {
|
switch($direction) {
|
||||||
|
@ -306,7 +339,7 @@ function dfrn_notify_content(App $a) {
|
||||||
$status = 1;
|
$status = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger("Remote rino version: ".$rino_remote." for ".$r[0]["url"], LOGGER_DEBUG);
|
logger("Remote rino version: ".$rino_remote." for ".$r[0]["url"], LOGGER_DATA);
|
||||||
|
|
||||||
$challenge = '';
|
$challenge = '';
|
||||||
$encrypted_id = '';
|
$encrypted_id = '';
|
||||||
|
@ -316,7 +349,7 @@ function dfrn_notify_content(App $a) {
|
||||||
$pub_key = trim($r[0]['pubkey']);
|
$pub_key = trim($r[0]['pubkey']);
|
||||||
$dplx = intval($r[0]['duplex']);
|
$dplx = intval($r[0]['duplex']);
|
||||||
|
|
||||||
if ((($dplx) && (strlen($prv_key))) || ((strlen($prv_key)) && (!(strlen($pub_key))))) {
|
if (($dplx && strlen($prv_key)) || (strlen($prv_key) && !strlen($pub_key))) {
|
||||||
openssl_private_encrypt($hash, $challenge, $prv_key);
|
openssl_private_encrypt($hash, $challenge, $prv_key);
|
||||||
openssl_private_encrypt($id_str, $encrypted_id, $prv_key);
|
openssl_private_encrypt($id_str, $encrypted_id, $prv_key);
|
||||||
} elseif (strlen($pub_key)) {
|
} elseif (strlen($pub_key)) {
|
||||||
|
@ -334,7 +367,7 @@ function dfrn_notify_content(App $a) {
|
||||||
$rino = Config::get('system', 'rino_encrypt');
|
$rino = Config::get('system', 'rino_encrypt');
|
||||||
$rino = intval($rino);
|
$rino = intval($rino);
|
||||||
|
|
||||||
logger("Local rino version: ". $rino, LOGGER_DEBUG);
|
logger("Local rino version: ". $rino, LOGGER_DATA);
|
||||||
|
|
||||||
// if requested rino is lower than enabled local rino, lower local rino version
|
// if requested rino is lower than enabled local rino, lower local rino version
|
||||||
// if requested rino is higher than enabled local rino, reply with local rino
|
// if requested rino is higher than enabled local rino, reply with local rino
|
||||||
|
@ -342,7 +375,7 @@ function dfrn_notify_content(App $a) {
|
||||||
$rino = $rino_remote;
|
$rino = $rino_remote;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((($r[0]['rel']) && ($r[0]['rel'] != CONTACT_IS_SHARING)) || ($r[0]['page-flags'] == PAGE_COMMUNITY)) {
|
if (($r[0]['rel'] && ($r[0]['rel'] != CONTACT_IS_SHARING)) || ($r[0]['page-flags'] == PAGE_COMMUNITY)) {
|
||||||
$perm = 'rw';
|
$perm = 'rw';
|
||||||
} else {
|
} else {
|
||||||
$perm = 'r';
|
$perm = 'r';
|
||||||
|
@ -362,5 +395,4 @@ function dfrn_notify_content(App $a) {
|
||||||
|
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1415,7 +1415,16 @@ class DFRN
|
||||||
|
|
||||||
$envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $fcontact['pubkey'], $public_batch);
|
$envelope = Diaspora::buildMessage($atom, $owner, $contact, $owner['uprvkey'], $fcontact['pubkey'], $public_batch);
|
||||||
|
|
||||||
$dest_url = ($public_batch ? $fcontact["batch"] : $contact["notify"]);
|
// Create the endpoint for public posts. This is some WIP and should later be added to the probing
|
||||||
|
if ($public_batch && empty($contact["batch"])) {
|
||||||
|
$parts = parse_url($contact["notify"]);
|
||||||
|
$path_parts = explode('/', $parts['path']);
|
||||||
|
array_pop($path_parts);
|
||||||
|
$parts['path'] = implode('/', $path_parts);
|
||||||
|
$contact["batch"] = Network::unparseURL($parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
$dest_url = ($public_batch ? $contact["batch"] : $contact["notify"]);
|
||||||
|
|
||||||
$content_type = ($public_batch ? "application/magic-envelope+xml" : "application/json");
|
$content_type = ($public_batch ? "application/magic-envelope+xml" : "application/json");
|
||||||
|
|
||||||
|
@ -2771,7 +2780,7 @@ class DFRN
|
||||||
logger('ignoring read-only contact '.$importer["id"]);
|
logger('ignoring read-only contact '.$importer["id"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($importer["uid"] == 0) {
|
if (($importer["uid"] == 0) && ($importer["importer_uid"] != 0)) {
|
||||||
logger("Contact ".$importer["id"]." isn't known to user ".$importer["importer_uid"].". The post will be ignored.", LOGGER_DEBUG);
|
logger("Contact ".$importer["id"]." isn't known to user ".$importer["importer_uid"].". The post will be ignored.", LOGGER_DEBUG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue