mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-20 01:15:13 +00:00
337 lines
11 KiB
PHP
337 lines
11 KiB
PHP
<?php
|
|
|
|
use Code\Lib\Libzot;
|
|
use Code\Lib\Time;
|
|
use Code\Web\HTTPSig;
|
|
use Code\Lib\Channel;
|
|
|
|
function xchan_store_lowlevel($arr)
|
|
{
|
|
|
|
$store = [
|
|
'xchan_hash' => ((array_key_exists('xchan_hash', $arr)) ? $arr['xchan_hash'] : ''),
|
|
'xchan_guid' => ((array_key_exists('xchan_guid', $arr)) ? $arr['xchan_guid'] : ''),
|
|
'xchan_guid_sig' => ((array_key_exists('xchan_guid_sig', $arr)) ? $arr['xchan_guid_sig'] : ''),
|
|
'xchan_pubkey' => ((array_key_exists('xchan_pubkey', $arr)) ? $arr['xchan_pubkey'] : ''),
|
|
'xchan_epubkey' => ((array_key_exists('xchan_epubkey', $arr)) ? $arr['xchan_epubkey'] : ''),
|
|
'xchan_photo_mimetype' => ((array_key_exists('xchan_photo_mimetype', $arr)) ? $arr['xchan_photo_mimetype'] : ''),
|
|
'xchan_photo_l' => ((array_key_exists('xchan_photo_l', $arr)) ? $arr['xchan_photo_l'] : ''),
|
|
'xchan_photo_m' => ((array_key_exists('xchan_photo_m', $arr)) ? $arr['xchan_photo_m'] : ''),
|
|
'xchan_photo_s' => ((array_key_exists('xchan_photo_s', $arr)) ? $arr['xchan_photo_s'] : ''),
|
|
'xchan_addr' => ((array_key_exists('xchan_addr', $arr)) ? $arr['xchan_addr'] : ''),
|
|
'xchan_url' => ((array_key_exists('xchan_url', $arr)) ? $arr['xchan_url'] : ''),
|
|
'xchan_connurl' => ((array_key_exists('xchan_connurl', $arr)) ? $arr['xchan_connurl'] : ''),
|
|
'xchan_follow' => ((array_key_exists('xchan_follow', $arr)) ? $arr['xchan_follow'] : ''),
|
|
'xchan_connpage' => ((array_key_exists('xchan_connpage', $arr)) ? $arr['xchan_connpage'] : ''),
|
|
'xchan_name' => ((array_key_exists('xchan_name', $arr)) ? $arr['xchan_name'] : ''),
|
|
'xchan_network' => ((array_key_exists('xchan_network', $arr)) ? $arr['xchan_network'] : ''),
|
|
'xchan_created' => ((array_key_exists('xchan_created', $arr)) ? Time::convert('UTC', 'UTC', $arr['xchan_created']) : Time::convert()),
|
|
'xchan_updated' => ((array_key_exists('xchan_updated', $arr)) ? Time::convert('UTC', 'UTC', $arr['xchan_updated']) : Time::convert()),
|
|
'xchan_photo_date' => ((array_key_exists('xchan_photo_date', $arr)) ? Time::convert('UTC', 'UTC', $arr['xchan_photo_date']) : NULL_DATE),
|
|
'xchan_name_date' => ((array_key_exists('xchan_name_date', $arr)) ? Time::convert('UTC', 'UTC', $arr['xchan_name_date']) : NULL_DATE),
|
|
'xchan_hidden' => ((array_key_exists('xchan_hidden', $arr)) ? intval($arr['xchan_hidden']) : 0),
|
|
'xchan_orphan' => ((array_key_exists('xchan_orphan', $arr)) ? intval($arr['xchan_orphan']) : 0),
|
|
'xchan_censored' => ((array_key_exists('xchan_censored', $arr)) ? intval($arr['xchan_censored']) : 0),
|
|
'xchan_selfcensored' => ((array_key_exists('xchan_selfcensored', $arr)) ? intval($arr['xchan_selfcensored']) : 0),
|
|
'xchan_system' => ((array_key_exists('xchan_system', $arr)) ? intval($arr['xchan_system']) : 0),
|
|
'xchan_type' => ((array_key_exists('xchan_type', $arr)) ? intval($arr['xchan_type']) : XCHAN_TYPE_PERSON),
|
|
'xchan_deleted' => ((array_key_exists('xchan_deleted', $arr)) ? intval($arr['xchan_deleted']) : 0)
|
|
];
|
|
|
|
return create_table_from_array('xchan', $store);
|
|
}
|
|
|
|
// called from the zot api
|
|
// Anybody can enter an identity into the system, but zot or zot6 identities must be validated
|
|
// and existing zot6 identities cannot be altered via API
|
|
|
|
function xchan_store($arr)
|
|
{
|
|
$update_photo = false;
|
|
$update_name = false;
|
|
|
|
if (! ($arr['guid'] || $arr['hash'])) {
|
|
$arr = json_decode(file_get_contents('php://input'), true);
|
|
}
|
|
|
|
logger('xchan_store: ' . print_r($arr, true));
|
|
|
|
if (! $arr['hash']) {
|
|
$arr['hash'] = $arr['guid'];
|
|
}
|
|
if (! $arr['hash']) {
|
|
return false;
|
|
}
|
|
$r = q(
|
|
"select * from xchan where xchan_hash = '%s' limit 1",
|
|
dbesc($arr['hash'])
|
|
);
|
|
if (! $r) {
|
|
$update_photo = true;
|
|
|
|
if (! $arr['network']) {
|
|
$arr['network'] = 'unknown';
|
|
}
|
|
if (! $arr['name']) {
|
|
$arr['name'] = 'unknown';
|
|
}
|
|
if (! $arr['url']) {
|
|
$arr['url'] = z_root();
|
|
}
|
|
if (! $arr['photo']) {
|
|
$arr['photo'] = z_root() . '/' . Channel::get_default_profile_photo();
|
|
}
|
|
|
|
if (in_array($arr['network'], [ 'nomad','zot6' ])) {
|
|
if ((! $arr['key']) || (! Libzot::verify($arr['id'], $arr['id_sig'], $arr['key']))) {
|
|
logger('Unable to verify signature for ' . $arr['hash']);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ($arr['network'] === 'zot') {
|
|
if ((! $arr['key']) || (! Libzot::verify($arr['id'], 'sha256.' . $arr['id_sig'], $arr['key']))) {
|
|
logger('Unable to verify signature for ' . $arr['hash']);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
$columns = db_columns('xchan');
|
|
|
|
$x = [];
|
|
foreach ($arr as $k => $v) {
|
|
if ($k === 'key') {
|
|
$x['xchan_pubkey'] = HTTPSig::convertKey(escape_tags($v));
|
|
continue;
|
|
}
|
|
if ($k === 'photo') {
|
|
continue;
|
|
}
|
|
|
|
if (in_array('xchan_' . $k, $columns)) {
|
|
$x['xchan_' . $k] = escape_tags($v);
|
|
}
|
|
}
|
|
|
|
$x['xchan_updated'] = Time::convert();
|
|
$x['xchan_name_date'] = Time::convert();
|
|
$x['xchan_photo_date'] = Time::convert();
|
|
$x['xchan_system'] = false;
|
|
|
|
$result = xchan_store_lowlevel($x);
|
|
|
|
if (! $result) {
|
|
return $result;
|
|
}
|
|
} else {
|
|
if (in_array($r[0]['network'] , [ 'zot6', 'nomad' ])) {
|
|
return true;
|
|
}
|
|
if ($r[0]['xchan_photo_date'] < Time::convert('UTC', 'UTC', $arr['photo_date'])) {
|
|
$update_photo = true;
|
|
}
|
|
if ($r[0]['xchan_name_date'] < Time::convert('UTC', 'UTC', $arr['name_date'])) {
|
|
$update_name = true;
|
|
}
|
|
}
|
|
|
|
if ($update_photo && $arr['photo']) {
|
|
$photos = import_remote_xchan_photo($arr['photo'], $arr['hash']);
|
|
if ($photos) {
|
|
$x = q(
|
|
"update xchan set xchan_updated = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'",
|
|
dbesc(Time::convert()),
|
|
dbesc(Time::convert()),
|
|
dbesc($photos[0]),
|
|
dbesc($photos[1]),
|
|
dbesc($photos[2]),
|
|
dbesc($photos[3]),
|
|
dbesc($arr['hash'])
|
|
);
|
|
}
|
|
}
|
|
if ($update_name && $arr['name']) {
|
|
$x = q(
|
|
"update xchan set xchan_updated = '%s', xchan_name = '%s', xchan_name_date = '%s' where xchan_hash = '%s'",
|
|
dbesc(Time::convert()),
|
|
dbesc(escape_tags($arr['name'])),
|
|
dbesc(Time::convert()),
|
|
dbesc($arr['hash'])
|
|
);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function xchan_project($xchan)
|
|
{
|
|
if (!empty($xchan['xchan_url'])) {
|
|
$parsed = parse_url($xchan['xchan_url']);
|
|
if ($parsed) {
|
|
$url = $parsed['scheme'] . '://' . $parsed['host'];
|
|
$record = q("select site_project from site where site_url = '%s'",
|
|
dbesc($url)
|
|
);
|
|
if ($record) {
|
|
return $record[0]['site_project'];
|
|
}
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function xchan_match($arr)
|
|
{
|
|
|
|
if (! $arr) {
|
|
return false;
|
|
}
|
|
|
|
$str = '';
|
|
|
|
foreach ($arr as $k => $v) {
|
|
if ($str) {
|
|
$str .= " AND ";
|
|
}
|
|
$str .= " " . TQUOT . dbesc($k) . TQUOT . " = '" . dbesc($v) . "' ";
|
|
}
|
|
|
|
$r = q("select * from xchan where $str limit 1");
|
|
|
|
return (($r) ? $r[0] : false);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function xchan_fetch($arr)
|
|
{
|
|
|
|
|
|
$key = '';
|
|
if ($arr['hash']) {
|
|
$key = 'xchan_hash';
|
|
$v = dbesc($arr['hash']);
|
|
} elseif ($arr['guid']) {
|
|
$key = 'xchan_guid';
|
|
$v = dbesc($arr['guid']);
|
|
} elseif ($arr['address']) {
|
|
$key = 'xchan_addr';
|
|
$v = dbesc($arr['address']);
|
|
}
|
|
|
|
if (! $key) {
|
|
return false;
|
|
}
|
|
|
|
$r = q("select * from xchan where $key = '$v' limit 1");
|
|
if (! $r) {
|
|
return false;
|
|
}
|
|
|
|
$ret = [];
|
|
foreach ($r[0] as $k => $v) {
|
|
if ($k === 'xchan_addr') {
|
|
$ret['address'] = $v;
|
|
} else {
|
|
$ret[str_replace('xchan_', '', $k)] = $v;
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
|
|
function xchan_keychange_table($table, $column, $oldxchan, $newxchan)
|
|
{
|
|
$r = q(
|
|
"update $table set $column = '%s' where $column = '%s'",
|
|
dbesc($newxchan['xchan_hash']),
|
|
dbesc($oldxchan['xchan_hash'])
|
|
);
|
|
return $r;
|
|
}
|
|
|
|
function xchan_keychange_acl($table, $column, $oldxchan, $newxchan)
|
|
{
|
|
|
|
$allow = (($table === 'channel') ? 'channel_allow_cid' : 'allow_cid');
|
|
$deny = (($table === 'channel') ? 'channel_deny_cid' : 'deny_cid');
|
|
|
|
|
|
$r = q(
|
|
"select $column, $allow, $deny from $table where ($allow like '%s' or $deny like '%s') ",
|
|
dbesc('<' . $oldxchan['xchan_hash'] . '>'),
|
|
dbesc('<' . $oldxchan['xchan_hash'] . '>')
|
|
);
|
|
|
|
if ($r) {
|
|
foreach ($r as $rv) {
|
|
$z = q(
|
|
"update $table set $allow = '%s', $deny = '%s' where $column = %d",
|
|
dbesc(str_replace(
|
|
'<' . $oldxchan['xchan_hash'] . '>',
|
|
'<' . $newxchan['xchan_hash'] . '>',
|
|
$rv[$allow]
|
|
)),
|
|
dbesc(str_replace(
|
|
'<' . $oldxchan['xchan_hash'] . '>',
|
|
'<' . $newxchan['xchan_hash'] . '>',
|
|
$rv[$deny]
|
|
)),
|
|
intval($rv[$column])
|
|
);
|
|
}
|
|
}
|
|
return $z;
|
|
}
|
|
|
|
|
|
function xchan_change_key($oldx, $newx)
|
|
{
|
|
|
|
$tables = [
|
|
'abook' => 'abook_xchan',
|
|
'abconfig' => 'xchan',
|
|
'pgrp_member' => 'xchan',
|
|
'chat' => 'chat_xchan',
|
|
'chatpresence' => 'cp_xchan',
|
|
'event' => 'event_xchan',
|
|
'item' => 'owner_xchan',
|
|
'item' => 'author_xchan',
|
|
'item' => 'source_xchan',
|
|
'shares' => 'share_xchan',
|
|
'source' => 'src_channel_xchan',
|
|
'source' => 'src_xchan',
|
|
'xchat' => 'xchat_xchan',
|
|
'xconfig' => 'xchan',
|
|
'xign' => 'xchan',
|
|
'xlink' => 'xlink_xchan',
|
|
'xprof' => 'xprof_hash',
|
|
'xtag' => 'xtag_hash'
|
|
];
|
|
|
|
|
|
$acls = [
|
|
'channel' => 'channel_id',
|
|
'attach' => 'id',
|
|
'chatroom' => 'cr_id',
|
|
'event' => 'id',
|
|
'item' => 'id',
|
|
'menu_item' => 'mitem_id',
|
|
'obj' => 'obj_id',
|
|
'photo' => 'id'
|
|
];
|
|
|
|
|
|
foreach ($tables as $k => $v) {
|
|
xchan_keychange_table($k, $v, $oldx, $newx);
|
|
}
|
|
|
|
foreach ($acls as $k => $v) {
|
|
xchan_keychange_acl($k, $v, $oldx, $newx);
|
|
}
|
|
}
|
|
|
|
|