streams/Code/Nomad/NomadHandler.php

200 lines
5.2 KiB
PHP
Raw Normal View History

2018-04-23 01:51:46 +00:00
<?php
2022-02-16 04:50:35 +00:00
namespace Code\Nomad;
2018-04-23 01:51:46 +00:00
2022-02-16 04:08:28 +00:00
use Code\Lib\Libzot;
2018-06-01 02:42:13 +00:00
2022-02-16 04:50:35 +00:00
class NomadHandler implements IHandler
2021-12-02 23:02:31 +00:00
{
2018-04-23 01:51:46 +00:00
2021-12-02 23:02:31 +00:00
public function Notify($data, $hub)
{
return self::reply_notify($data, $hub);
}
2018-04-23 01:51:46 +00:00
2021-12-02 23:02:31 +00:00
public function Rekey($sender, $data, $hub)
{
return self::reply_rekey_request($sender, $data, $hub);
}
2018-04-23 01:51:46 +00:00
2021-12-02 23:02:31 +00:00
public function Refresh($sender, $recipients, $hub, $force)
{
return self::reply_refresh($sender, $recipients, $hub, $force);
}
2018-04-23 01:51:46 +00:00
2021-12-02 23:02:31 +00:00
public function Purge($sender, $recipients, $hub)
{
return self::reply_purge($sender, $recipients, $hub);
}
2018-06-01 02:42:13 +00:00
2018-07-10 23:42:16 +00:00
2021-12-02 23:02:31 +00:00
// Implementation of specific methods follows;
// These generally do a small amout of validation and call Libzot
// to do any heavy lifting
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
public static function reply_notify($data, $hub)
{
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$ret = ['success' => false];
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
logger('notify received from ' . $hub['hubloc_url']);
2018-06-01 02:42:13 +00:00
$x = Libzot::import($data, $hub);
2021-12-02 23:02:31 +00:00
$ret['delivery_report'] = $x;
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$ret['success'] = true;
return $ret;
}
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
/**
* @brief Remote channel info (such as permissions or photo or something)
* has been updated. Grab a fresh copy and sync it.
*
* The difference between refresh and force_refresh is that force_refresh
* unconditionally creates a directory update record, even if no changes were
* detected upon processing.
*
* @param array $sender
* @param array $recipients
*
2022-08-27 04:01:22 +00:00
* @return array
2021-12-02 23:02:31 +00:00
*/
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
public static function reply_refresh($sender, $recipients, $hub, $force)
{
$ret = array('success' => false);
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
if ($recipients) {
// This would be a permissions update, typically for one connection
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
foreach ($recipients as $recip) {
2021-12-03 03:01:39 +00:00
$r = q(
"select channel.*,xchan.* from channel
2018-06-01 02:42:13 +00:00
left join xchan on channel_hash = xchan_hash
2018-06-04 00:49:48 +00:00
where channel_hash ='%s' limit 1",
2021-12-02 23:02:31 +00:00
dbesc($recip)
);
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$x = Libzot::refresh(['hubloc_id_url' => $hub['hubloc_id_url']], $r[0], $force);
}
} else {
// system wide refresh
$x = Libzot::refresh(['hubloc_id_url' => $hub['hubloc_id_url']], null, $force);
}
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$ret['success'] = true;
return $ret;
}
2018-06-01 02:42:13 +00:00
2022-08-14 10:37:38 +00:00
public static function reply_rekey_request($sender, $data, $hub)
2021-12-02 23:02:31 +00:00
{
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$ret = array('success' => false);
2018-06-01 02:42:13 +00:00
2021-12-03 03:01:39 +00:00
// newsig is newkey signed with oldkey
2018-06-01 02:42:13 +00:00
2022-02-16 05:26:15 +00:00
// The original xchan will remain. In Nomad/Receiver we will have imported the new xchan and hubloc to verify
2021-12-02 23:02:31 +00:00
// the packet authenticity. What we will do now is verify that the keychange operation was signed by the
// oldkey, and if so change all the abook, abconfig, group, and permission elements which reference the
// old xchan_hash.
2018-06-01 02:42:13 +00:00
2021-12-03 03:01:39 +00:00
if ((!$data['old_key']) && (!$data['new_key']) && (!$data['new_sig'])) {
2021-12-02 23:02:31 +00:00
return $ret;
2021-12-03 03:01:39 +00:00
}
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$old = null;
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
if (Libzot::verify($data['old_guid'], $data['old_guid_sig'], $data['old_key'])) {
2022-08-14 10:37:38 +00:00
$oldhash = Libzot::make_xchan_hash($data['old_guid'], $data['old_key']);
2021-12-03 03:01:39 +00:00
$old = q(
"select * from xchan where xchan_hash = '%s' limit 1",
2021-12-02 23:02:31 +00:00
dbesc($oldhash)
);
2021-12-03 03:01:39 +00:00
} else {
2021-12-02 23:02:31 +00:00
return $ret;
2021-12-03 03:01:39 +00:00
}
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
if (!$old) {
return $ret;
}
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$xchan = $old[0];
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
if (!Libzot::verify($data['new_key'], $data['new_sig'], $xchan['xchan_pubkey'])) {
return $ret;
}
2018-06-01 02:42:13 +00:00
2021-12-03 03:01:39 +00:00
$r = q(
"select * from xchan where xchan_hash = '%s' limit 1",
2021-12-02 23:02:31 +00:00
dbesc($sender)
);
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$newxchan = $r[0];
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
// @todo
// if ! $update create a linked identity
2018-07-10 23:42:16 +00:00
2022-11-20 06:44:13 +00:00
xchan_change_key($xchan, $newxchan);
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$ret['success'] = true;
return $ret;
}
2018-04-23 01:51:46 +00:00
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
/**
* @brief
*
2022-08-27 04:01:22 +00:00
* @param string $sender
2021-12-02 23:02:31 +00:00
* @param array $recipients
*
* return json_return_and_die()
*/
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
public static function reply_purge($sender, $recipients, $hub)
{
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
$ret = array('success' => false);
2018-06-01 02:42:13 +00:00
2021-12-02 23:02:31 +00:00
if (!$sender) {
return $ret;
}
2019-06-05 00:53:21 +00:00
2021-12-02 23:02:31 +00:00
if ($recipients) {
// basically this means "unfriend"
foreach ($recipients as $recip) {
2021-12-03 03:01:39 +00:00
$channel = q(
"select channel.*,xchan.* from channel
2018-06-01 02:42:13 +00:00
left join xchan on channel_hash = xchan_hash
where channel_hash = '%s' limit 1",
2021-12-02 23:02:31 +00:00
dbesc($recip)
);
if ($channel) {
2021-12-03 03:01:39 +00:00
$abook = q(
"select abook_id from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
2021-12-02 23:02:31 +00:00
intval($channel[0]['channel_id']),
dbesc($sender)
);
if ($abook) {
contact_remove($channel[0]['channel_id'], $abook[0]['abook_id']);
}
}
}
$ret['success'] = true;
} else {
// Unfriend everybody - basically this means the channel has committed suicide
remove_all_xchan_resources($sender);
$ret['success'] = true;
}
return $ret;
}
2018-04-23 01:51:46 +00:00
}