Merge branch 'dev'
This commit is contained in:
commit
f1fee1239b
@ -85,6 +85,7 @@ class Cron_daily {
|
||||
Master::Summon(array('Cli_suggest'));
|
||||
|
||||
remove_obsolete_hublocs();
|
||||
z6_discover();
|
||||
|
||||
call_hooks('cron_daily',datetime_convert());
|
||||
|
||||
|
@ -199,6 +199,7 @@ class Poller {
|
||||
set_config('system','lastpoll',datetime_convert());
|
||||
|
||||
//All done - clear the lockfile
|
||||
|
||||
@unlink($lockfile);
|
||||
|
||||
return;
|
||||
|
@ -319,7 +319,10 @@ class ActivityStreams {
|
||||
function get_compound_property($property, $base = '', $namespace = '', $first = false) {
|
||||
$x = $this->get_property_obj($property, $base, $namespace);
|
||||
if($this->is_url($x)) {
|
||||
$x = $this->fetch_property($x);
|
||||
$y = $this->fetch_property($x);
|
||||
if (is_array($y)) {
|
||||
$x = $y;
|
||||
}
|
||||
}
|
||||
|
||||
// verify and unpack JSalmon signature if present
|
||||
|
@ -328,6 +328,7 @@ class Apps {
|
||||
'Bookmarks' => t('Bookmarks'),
|
||||
'Chatrooms' => t('Chatrooms'),
|
||||
'Content Filter' => t('Content Filter'),
|
||||
'Content Import' => t('Content Import'),
|
||||
'Connections' => t('Connections'),
|
||||
'Remote Diagnostics' => t('Remote Diagnostics'),
|
||||
'Suggest Channels' => t('Suggest Channels'),
|
||||
|
@ -1197,12 +1197,14 @@ class Libzot {
|
||||
|
||||
//logger($AS->debug());
|
||||
|
||||
$r = q("select hubloc_hash from hubloc where hubloc_id_url = '%s' and hubloc_network = 'zot6' limit 1",
|
||||
$r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s' ",
|
||||
dbesc($AS->actor['id'])
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$arr['author_xchan'] = $r[0]['hubloc_hash'];
|
||||
// selects a zot6 hash if available, otherwise use whatever we have
|
||||
$r = self::zot_record_preferred($r);
|
||||
$arr['author_xchan'] = $r['hubloc_hash'];
|
||||
}
|
||||
|
||||
|
||||
@ -3096,4 +3098,22 @@ class Libzot {
|
||||
return(($x) ? true : false);
|
||||
}
|
||||
|
||||
|
||||
static public function zot_record_preferred($arr, $check = 'hubloc_network') {
|
||||
|
||||
if(! $arr) {
|
||||
return $arr;
|
||||
}
|
||||
|
||||
foreach($arr as $v) {
|
||||
if($v[$check] === 'zot6') {
|
||||
|
||||
return $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $arr[0];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -848,7 +848,7 @@ class Connedit extends \Zotlabs\Web\Controller {
|
||||
$locstr = unpunify($contact['xchan_url']);
|
||||
|
||||
$clone_warn = '';
|
||||
$clonable = (in_array($contact['xchan_network'],['zot','rss']) ? true : false);
|
||||
$clonable = (in_array($contact['xchan_network'],['zot', 'zot6', 'rss']) ? true : false);
|
||||
if(! $clonable) {
|
||||
$clone_warn = '<strong>';
|
||||
$clone_warn .= ((intval($contact['abook_not_here']))
|
||||
|
@ -40,56 +40,78 @@ class Item extends Controller {
|
||||
|
||||
function init() {
|
||||
|
||||
if(Libzot::is_zot_request()) {
|
||||
if (Libzot::is_zot_request()) {
|
||||
|
||||
$conversation = false;
|
||||
|
||||
$item_id = argv(1);
|
||||
|
||||
if(! $item_id)
|
||||
if (! $item_id)
|
||||
http_status_exit(404, 'Not found');
|
||||
|
||||
|
||||
$portable_id = EMPTY_STR;
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 ";
|
||||
|
||||
$i = null;
|
||||
|
||||
// do we have the item (at all)?
|
||||
|
||||
$r = q("select * from item where mid = '%s' $item_normal limit 1",
|
||||
dbesc(z_root() . '/item/' . $item_id)
|
||||
);
|
||||
|
||||
if (! $r) {
|
||||
http_status_exit(404,'Not found');
|
||||
}
|
||||
|
||||
// process an authenticated fetch
|
||||
|
||||
$sigdata = HTTPSig::verify(EMPTY_STR);
|
||||
if($sigdata['portable_id'] && $sigdata['header_valid']) {
|
||||
$portable_id = $sigdata['portable_id'];
|
||||
observer_auth($portable_id);
|
||||
|
||||
// first see if we have a copy of this item's parent owned by the current signer
|
||||
// include xchans for all zot-like networks - these will have the same guid and public key
|
||||
|
||||
$x = q("select * from xchan where xchan_hash = '%s'",
|
||||
dbesc($sigdata['portable_id'])
|
||||
);
|
||||
|
||||
if ($x) {
|
||||
$xchans = q("select xchan_hash from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ",
|
||||
dbesc($sigdata['portable_id']),
|
||||
dbesc($x[0]['xchan_guid']),
|
||||
dbesc($x[0]['xchan_pubkey'])
|
||||
);
|
||||
|
||||
if ($xchans) {
|
||||
$hashes = ids_to_querystr($xchans,'xchan_hash',true);
|
||||
$i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan in ( " . protect_sprintf($hashes) . " ) limit 1",
|
||||
dbesc($r[0]['parent_mid'])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 ";
|
||||
// if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access
|
||||
|
||||
$sql_extra = item_permissions_sql(0);
|
||||
|
||||
$r = q("select * from item where mid = '%s' $item_normal $sql_extra limit 1",
|
||||
dbesc(z_root() . '/item/' . $item_id)
|
||||
);
|
||||
if(! $r) {
|
||||
|
||||
|
||||
$r = q("select * from item where mid = '%s' $item_normal limit 1",
|
||||
dbesc(z_root() . '/item/' . $item_id)
|
||||
if (! $i) {
|
||||
$i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra limit 1",
|
||||
dbesc($r[0]['parent_mid'])
|
||||
);
|
||||
if($r) {
|
||||
http_status_exit(403, 'Forbidden');
|
||||
}
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
|
||||
|
||||
$items = q("select parent as item_id from item where mid = '%s' and uid = %d $item_normal $sql_extra ",
|
||||
dbesc($r[0]['parent_mid']),
|
||||
intval($r[0]['uid'])
|
||||
);
|
||||
if(! $items) {
|
||||
http_status_exit(404, 'Not found');
|
||||
if(! $i) {
|
||||
http_status_exit(403,'Forbidden');
|
||||
}
|
||||
|
||||
$r = $items;
|
||||
$parents_str = ids_to_querystr($i,'item_id');
|
||||
|
||||
$parents_str = ids_to_querystr($r,'item_id');
|
||||
|
||||
$items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal $sql_extra ",
|
||||
$items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent IN ( %s ) $item_normal ",
|
||||
dbesc($parents_str)
|
||||
);
|
||||
|
||||
@ -97,9 +119,8 @@ class Item extends Controller {
|
||||
http_status_exit(404, 'Not found');
|
||||
}
|
||||
|
||||
$r = $items;
|
||||
xchan_query($r,true);
|
||||
$items = fetch_post_tags($r,true);
|
||||
xchan_query($items,true);
|
||||
$items = fetch_post_tags($items,true);
|
||||
|
||||
$observer = App::get_observer();
|
||||
$parent = $items[0];
|
||||
|
@ -305,3 +305,39 @@ function ping_site($url) {
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
function z6_discover() {
|
||||
|
||||
// find unregistered zot6 clone hublocs
|
||||
|
||||
$c = q("select channel_hash, portable_id from channel where channel_deleted = 0");
|
||||
if ($c) {
|
||||
foreach ($c as $entry) {
|
||||
$q1 = q("select * from hubloc left join site on hubloc_url = site_url where hubloc_deleted = 0 and site_dead = 0 and hubloc_hash = '%s' and hubloc_url != '%s'",
|
||||
dbesc($entry['channel_hash']),
|
||||
dbesc(z_root())
|
||||
);
|
||||
if (! $q1) {
|
||||
// channel has no zot clones
|
||||
continue;
|
||||
}
|
||||
// does this particular server have a zot6 clone registered on our site for this channel?
|
||||
foreach ($q1 as $q) {
|
||||
$q2 = q("select * from hubloc left join site on hubloc_url = site_url where hubloc_deleted = 0 and site_dead = 0 and hubloc_hash = '%s' and hubloc_url = '%s'",
|
||||
dbesc($entry['portable_id']),
|
||||
dbesc($q['hubloc_url'])
|
||||
);
|
||||
if ($q2) {
|
||||
continue;
|
||||
}
|
||||
// zot6 hubloc not found.
|
||||
if(strpos($entry['site_project'],'hubzilla') !== false && version_compare($entry['site_version'],'4.0') >= 0) {
|
||||
// probe and store results - only for zot6 (over-ride the zot default)
|
||||
discover_by_webbie($entry['hubloc_addr'],'zot6');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -763,11 +763,11 @@ function get_item_elements($x,$allow_code = false) {
|
||||
// check the supplied signature against the supplied content.
|
||||
// Note that we will purify the content which could change it.
|
||||
|
||||
$r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1",
|
||||
$r = q("select xchan_pubkey, xchan_network from xchan where xchan_hash = '%s' limit 1",
|
||||
dbesc($arr['author_xchan'])
|
||||
);
|
||||
if($r) {
|
||||
if($r[0]['xchan_pubkey']) {
|
||||
if($r[0]['xchan_pubkey'] && $r[0]['xchan_network'] === 'zot') {
|
||||
if(rsa_verify($x['body'],base64url_decode($arr['sig']),$r[0]['xchan_pubkey'])) {
|
||||
$arr['item_verified'] = 1;
|
||||
}
|
||||
@ -914,6 +914,16 @@ function import_author_xchan($x) {
|
||||
if(array_key_exists('network',$x) && $x['network'] === 'zot')
|
||||
return $y;
|
||||
|
||||
// perform zot6 discovery
|
||||
|
||||
if($x['url']) {
|
||||
$y = discover_by_webbie($x['url'],'zot6');
|
||||
|
||||
if($y) {
|
||||
return $y;
|
||||
}
|
||||
}
|
||||
|
||||
if($x['network'] === 'rss') {
|
||||
$y = import_author_rss($x);
|
||||
}
|
||||
|
@ -306,6 +306,7 @@ function change_channel($change_channel) {
|
||||
*
|
||||
* @return string additional SQL where statement
|
||||
*/
|
||||
|
||||
function permissions_sql($owner_id, $remote_observer = null, $table = '') {
|
||||
|
||||
$local_channel = local_channel();
|
||||
@ -316,7 +317,7 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
|
||||
* default permissions - anonymous user
|
||||
*/
|
||||
|
||||
if($table)
|
||||
if ($table)
|
||||
$table .= '.';
|
||||
|
||||
$sql = " AND {$table}allow_cid = ''
|
||||
@ -329,38 +330,63 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
|
||||
* Profile owner - everything is visible
|
||||
*/
|
||||
|
||||
if(($local_channel) && ($local_channel == $owner_id)) {
|
||||
$sql = '';
|
||||
if (($local_channel) && ($local_channel == $owner_id)) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticated visitor. Unless pre-verified,
|
||||
* check that the contact belongs to this $owner_id
|
||||
* and load the groups the visitor belongs to.
|
||||
* If pre-verified, the caller is expected to have already
|
||||
* done this and passed the groups into this function.
|
||||
* Authenticated visitor.
|
||||
*/
|
||||
|
||||
else {
|
||||
|
||||
$observer = ((! is_null($remote_observer)) ? $remote_observer : get_observer_hash());
|
||||
if($observer) {
|
||||
$groups = init_groups_visitor($observer);
|
||||
|
||||
$gs = '<<>>'; // should be impossible to match
|
||||
if ($observer) {
|
||||
|
||||
if(is_array($groups) && count($groups)) {
|
||||
foreach($groups as $g)
|
||||
$gs .= '|<' . $g . '>';
|
||||
$sec = get_security_ids($owner_id,$observer);
|
||||
|
||||
// always allow the channel owner, even if authenticated as a visitor
|
||||
|
||||
if ($sec['channel_id']) {
|
||||
foreach ($sec['channel_id'] as $ch) {
|
||||
if ($observer === $ch) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) {
|
||||
$ca = [];
|
||||
foreach ($sec['allow_cid'] as $c) {
|
||||
$ca[] = '<' . $c . '>';
|
||||
}
|
||||
$cs = implode('|',$ca);
|
||||
}
|
||||
else {
|
||||
$cs = '<<>>'; // should be impossible to match
|
||||
}
|
||||
|
||||
if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) {
|
||||
$ga = [];
|
||||
foreach ($sec['allow_gid'] as $g) {
|
||||
$ga[] = '<' . $g . '>';
|
||||
}
|
||||
$gs = implode('|',$ga);
|
||||
}
|
||||
else {
|
||||
$gs = '<<>>'; // should be impossible to match
|
||||
}
|
||||
|
||||
$regexop = db_getfunc('REGEXP');
|
||||
$sql = sprintf(
|
||||
" AND ( NOT ({$table}deny_cid like '%s' OR {$table}deny_gid $regexop '%s')
|
||||
AND ( {$table}allow_cid like '%s' OR {$table}allow_gid $regexop '%s' OR ( {$table}allow_cid = '' AND {$table}allow_gid = '') )
|
||||
" AND ( NOT ({$table}deny_cid $regexop '%s' OR {$table}deny_gid $regexop '%s')
|
||||
AND ( {$table}allow_cid $regexop '%s' OR {$table}allow_gid $regexop '%s' OR ( {$table}allow_cid = '' AND {$table}allow_gid = '') )
|
||||
)
|
||||
",
|
||||
dbesc(protect_sprintf( '%<' . $observer . '>%')),
|
||||
dbesc($cs),
|
||||
dbesc($gs),
|
||||
dbesc(protect_sprintf( '%<' . $observer . '>%')),
|
||||
dbesc($cs),
|
||||
dbesc($gs)
|
||||
);
|
||||
}
|
||||
@ -377,6 +403,7 @@ function permissions_sql($owner_id, $remote_observer = null, $table = '') {
|
||||
*
|
||||
* @return string additional SQL where statement
|
||||
*/
|
||||
|
||||
function item_permissions_sql($owner_id, $remote_observer = null) {
|
||||
|
||||
$local_channel = local_channel();
|
||||
@ -398,37 +425,59 @@ function item_permissions_sql($owner_id, $remote_observer = null) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticated visitor. Unless pre-verified,
|
||||
* check that the contact belongs to this $owner_id
|
||||
* and load the groups the visitor belongs to.
|
||||
* If pre-verified, the caller is expected to have already
|
||||
* done this and passed the groups into this function.
|
||||
* Authenticated visitor.
|
||||
*/
|
||||
|
||||
else {
|
||||
$observer = (($remote_observer) ? $remote_observer : get_observer_hash());
|
||||
|
||||
if($observer) {
|
||||
$observer = (($remote_observer) ? $remote_observer : get_observer_hash());
|
||||
|
||||
$s = scopes_sql($owner_id,$observer);
|
||||
if($observer) {
|
||||
|
||||
$groups = init_groups_visitor($observer);
|
||||
$scope = scopes_sql($owner_id,$observer);
|
||||
$sec = get_security_ids($owner_id,$observer);
|
||||
|
||||
$gs = '<<>>'; // should be impossible to match
|
||||
// always allow the channel owner, even if authenticated as a visitor
|
||||
|
||||
if(is_array($groups) && count($groups)) {
|
||||
foreach($groups as $g)
|
||||
$gs .= '|<' . $g . '>';
|
||||
if($sec['channel_id']) {
|
||||
foreach($sec['channel_id'] as $ch) {
|
||||
if($observer === $ch) {
|
||||
return EMPTY_STR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) {
|
||||
$ca = [];
|
||||
foreach ($sec['allow_cid'] as $c) {
|
||||
$ca[] = '<' . $c . '>';
|
||||
}
|
||||
$cs = implode('|',$ca);
|
||||
}
|
||||
else {
|
||||
$cs = '<<>>'; // should be impossible to match
|
||||
}
|
||||
|
||||
if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) {
|
||||
$ga = [];
|
||||
foreach ($sec['allow_gid'] as $g) {
|
||||
$ga[] = '<' . $g . '>';
|
||||
}
|
||||
$gs = implode('|',$ga);
|
||||
}
|
||||
else {
|
||||
$gs = '<<>>'; // should be impossible to match
|
||||
}
|
||||
|
||||
$regexop = db_getfunc('REGEXP');
|
||||
$sql = sprintf(
|
||||
" AND (( NOT (deny_cid like '%s' OR deny_gid $regexop '%s')
|
||||
AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ))
|
||||
) OR ( item_private = 1 $s ))
|
||||
" AND (( NOT (deny_cid $regexop '%s' OR deny_gid $regexop '%s')
|
||||
AND ( allow_cid $regexop '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ))
|
||||
) OR ( item_private = 1 $scope ))
|
||||
",
|
||||
dbesc(protect_sprintf( '%<' . $observer . '>%')),
|
||||
dbesc($cs),
|
||||
dbesc($gs),
|
||||
dbesc(protect_sprintf( '%<' . $observer . '>%')),
|
||||
dbesc($cs),
|
||||
dbesc($gs)
|
||||
);
|
||||
}
|
||||
@ -465,40 +514,57 @@ function scopes_sql($uid,$observer) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $observer_hash
|
||||
*
|
||||
* @return string additional SQL where statement
|
||||
*/
|
||||
|
||||
function public_permissions_sql($observer_hash) {
|
||||
|
||||
$groups = init_groups_visitor($observer_hash);
|
||||
$owner_id = 0;
|
||||
|
||||
$gs = '<<>>'; // should be impossible to match
|
||||
if ($observer_hash) {
|
||||
|
||||
$sec = get_security_ids($owner_id,$observer_hash);
|
||||
|
||||
if (is_array($sec['allow_cid']) && count($sec['allow_cid'])) {
|
||||
$ca = [];
|
||||
foreach ($sec['allow_cid'] as $c) {
|
||||
$ca[] = '<' . $c . '>';
|
||||
}
|
||||
$cs = implode('|',$ca);
|
||||
}
|
||||
else {
|
||||
$cs = '<<>>'; // should be impossible to match
|
||||
}
|
||||
|
||||
if (is_array($sec['allow_gid']) && count($sec['allow_gid'])) {
|
||||
$ga = [];
|
||||
foreach ($sec['allow_gid'] as $g) {
|
||||
$ga[] = '<' . $g . '>';
|
||||
}
|
||||
$gs = implode('|',$ga);
|
||||
}
|
||||
else {
|
||||
$gs = '<<>>'; // should be impossible to match
|
||||
}
|
||||
|
||||
if(is_array($groups) && count($groups)) {
|
||||
foreach($groups as $g)
|
||||
$gs .= '|<' . $g . '>';
|
||||
}
|
||||
$sql = '';
|
||||
if($observer_hash) {
|
||||
$regexop = db_getfunc('REGEXP');
|
||||
$sql = sprintf(
|
||||
" OR (( NOT (deny_cid like '%s' OR deny_gid $regexop '%s')
|
||||
AND ( allow_cid like '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0 ) )
|
||||
))
|
||||
" AND ( NOT (deny_cid $regexop '%s' OR deny_gid $regexop '%s')
|
||||
AND ( allow_cid $regexop '%s' OR allow_gid $regexop '%s' OR ( allow_cid = '' AND allow_gid = '' AND item_private = 0) )
|
||||
)
|
||||
",
|
||||
dbesc(protect_sprintf( '%<' . $observer_hash . '>%')),
|
||||
dbesc($cs),
|
||||
dbesc($gs),
|
||||
dbesc(protect_sprintf( '%<' . $observer_hash . '>%')),
|
||||
dbesc($cs),
|
||||
dbesc($gs)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$sql = EMPTY_STR;
|
||||
}
|
||||
|
||||
return $sql;
|
||||
}
|
||||
@ -510,7 +576,7 @@ function public_permissions_sql($observer_hash) {
|
||||
* In this implementation, a security token is reusable (if the user submits a form, goes back and resubmits the form, maybe with small changes;
|
||||
* or if the security token is used for ajax-calls that happen several times), but only valid for a certain amout of time (3hours).
|
||||
* The "typename" seperates the security tokens of different types of forms. This could be relevant in the following case:
|
||||
* A security token is used to protekt a link from CSRF (e.g. the "delete this profile"-link).
|
||||
* A security token is used to protect a link from CSRF (e.g. the "delete this profile"-link).
|
||||
* If the new page contains by any chance external elements, then the used security token is exposed by the referrer.
|
||||
* Actually, important actions should not be triggered by Links / GET-Requests at all, but somethimes they still are,
|
||||
* so this mechanism brings in some damage control (the attacker would be able to forge a request to a form of this type, but not to forms of other types).
|
||||
@ -564,24 +630,40 @@ function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'f
|
||||
function init_groups_visitor($contact_id) {
|
||||
$groups = [];
|
||||
|
||||
// private profiles are treated as a virtual group
|
||||
|
||||
$r = q("SELECT abook_profile from abook where abook_xchan = '%s' and abook_profile != '' ",
|
||||
$x = q("select * from xchan where xchan_hash = '%s'",
|
||||
dbesc($contact_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rv) {
|
||||
|
||||
if (! $x) {
|
||||
return $groups;
|
||||
}
|
||||
|
||||
// include xchans for all zot-like networks
|
||||
|
||||
$xchans = q("select xchan_hash from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ",
|
||||
dbesc($contact_id),
|
||||
dbesc($x[0]['xchan_guid']),
|
||||
dbesc($x[0]['xchan_pubkey'])
|
||||
);
|
||||
|
||||
if($xchans) {
|
||||
$hashes = ids_to_querystr($xchans,'xchan_hash',true);
|
||||
}
|
||||
|
||||
// private profiles are treated as a virtual group
|
||||
|
||||
$r = q("SELECT abook_profile from abook where abook_xchan in ( " . protect_sprintf($hashes) . " ) and abook_profile != '' ");
|
||||
if ($r) {
|
||||
foreach ($r as $rv) {
|
||||
$groups[] = 'vp.' . $rv['abook_profile'];
|
||||
}
|
||||
}
|
||||
|
||||
// physical groups this channel is a member of
|
||||
// physical groups this identity is a member of
|
||||
|
||||
$r = q("SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan = '%s' ",
|
||||
dbesc($contact_id)
|
||||
);
|
||||
if($r) {
|
||||
foreach($r as $rr)
|
||||
$r = q("SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan in ( " . protect_sprintf($hashes) . " ) ");
|
||||
if ($r) {
|
||||
foreach ($r as $rr)
|
||||
$groups[] = $rr['hash'];
|
||||
}
|
||||
return $groups;
|
||||
@ -589,6 +671,70 @@ function init_groups_visitor($contact_id) {
|
||||
|
||||
|
||||
|
||||
|
||||
function get_security_ids($channel_id, $ob_hash) {
|
||||
|
||||
$ret = [
|
||||
'channel_id' => [],
|
||||
'allow_cid' => [],
|
||||
'allow_gid' => []
|
||||
];
|
||||
|
||||
if($channel_id) {
|
||||
$ch = q("select channel_hash, channel_portable_id from channel where channel_id = %d",
|
||||
intval($channel_id)
|
||||
);
|
||||
if($ch) {
|
||||
$ret['channel_id'][] = $ch[0]['channel_hash'];
|
||||
$ret['channel_id'][] = $ch[0]['channel_portable_id'];
|
||||
}
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
|
||||
$x = q("select * from xchan where xchan_hash = '%s'",
|
||||
dbesc($ob_hash)
|
||||
);
|
||||
|
||||
if ($x) {
|
||||
|
||||
// include xchans for all zot-like networks
|
||||
|
||||
$xchans = q("select xchan_hash from xchan where xchan_hash = '%s' OR ( xchan_guid = '%s' AND xchan_pubkey = '%s' ) ",
|
||||
dbesc($ob_hash),
|
||||
dbesc($x[0]['xchan_guid']),
|
||||
dbesc($x[0]['xchan_pubkey'])
|
||||
);
|
||||
|
||||
if ($xchans) {
|
||||
$ret['allow_cid'] = ids_to_array($xchans,'xchan_hash');
|
||||
$hashes = ids_to_querystr($xchans,'xchan_hash',true);
|
||||
|
||||
// private profiles are treated as a virtual group
|
||||
|
||||
$r = q("SELECT abook_profile from abook where abook_xchan in ( " . protect_sprintf($hashes) . " ) and abook_profile != '' ");
|
||||
if($r) {
|
||||
foreach ($r as $rv) {
|
||||
$groups[] = 'vp.' . $rv['abook_profile'];
|
||||
}
|
||||
}
|
||||
|
||||
// physical groups this identity is a member of
|
||||
|
||||
$r = q("SELECT hash FROM pgrp left join pgrp_member on pgrp.id = pgrp_member.gid WHERE xchan in ( " . protect_sprintf($hashes) . " ) ");
|
||||
if($r) {
|
||||
foreach ($r as $rv) {
|
||||
$groups[] = $rv['hash'];
|
||||
}
|
||||
}
|
||||
$ret['allow_gid'] = $groups;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
// This is used to determine which uid have posts which are visible to the logged in user (from the API) for the
|
||||
// public_timeline, and we can use this in a community page by making
|
||||
// $perms = (PERMS_NETWORK|PERMS_PUBLIC) unless logged in.
|
||||
|
@ -352,3 +352,51 @@ function owt_init($token) {
|
||||
|
||||
logger('OpenWebAuth: auth success from ' . $hubloc['xchan_addr']);
|
||||
}
|
||||
|
||||
|
||||
function observer_auth($ob_hash) {
|
||||
|
||||
if($ob_hash === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
$r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
||||
where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc",
|
||||
dbesc($ob_hash),
|
||||
dbesc($ob_hash),
|
||||
dbesc($ob_hash)
|
||||
);
|
||||
|
||||
if(! $r) {
|
||||
// finger them if they can't be found.
|
||||
$wf = discover_by_webbie($ob_hash);
|
||||
if($wf) {
|
||||
$r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
||||
where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc",
|
||||
dbesc($ob_hash),
|
||||
dbesc($ob_hash),
|
||||
dbesc($ob_hash)
|
||||
);
|
||||
}
|
||||
}
|
||||
if(! $r) {
|
||||
logger('unable to finger ' . $ob_hash);
|
||||
return;
|
||||
}
|
||||
|
||||
$hubloc = $r[0];
|
||||
|
||||
$_SESSION['authenticated'] = 1;
|
||||
|
||||
// normal visitor (remote_channel) login session credentials
|
||||
$_SESSION['visitor_id'] = $hubloc['xchan_hash'];
|
||||
$_SESSION['my_url'] = $hubloc['xchan_url'];
|
||||
$_SESSION['my_address'] = $hubloc['hubloc_addr'];
|
||||
$_SESSION['remote_hub'] = $hubloc['hubloc_url'];
|
||||
$_SESSION['DNT'] = 1;
|
||||
|
||||
\App::set_observer($hubloc);
|
||||
require_once('include/security.php');
|
||||
\App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user