Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
zottel 2016-08-02 10:56:47 +02:00
commit dd83f6f356
10 changed files with 142 additions and 27 deletions

View File

@ -64,12 +64,16 @@ class Cron {
// delete expired access tokens
q("delete from atoken where atoken_expires != '%s' && atoken_expires < %s",
$r = q("select atoken_id from atoken where atoken_expires != '%s' && atoken_expires < %s",
dbesc(NULL_DATE),
db_utcnow()
);
if($r) {
require_once('include/security.php');
foreach($r as $rr) {
atoken_delete($rr['atoken_id']);
}
}
// Ensure that every channel pings a directory server once a month. This way we can discover
// channels and sites that quietly vanished and prevent the directory from accumulating stale

View File

@ -90,7 +90,7 @@ class Impel extends \Zotlabs\Web\Controller {
$mitem['mitem_link'] = str_replace('[channelurl]',z_root() . '/channel/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[pageurl]',z_root() . '/page/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[storeurl]',z_root() . '/store/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[cloudurl]',z_root() . '/cloud/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
$mitem['mitem_desc'] = escape_tags($it['desc']);

View File

@ -495,6 +495,8 @@ class Like extends \Zotlabs\Web\Controller {
$arr['deny_gid'] = $deny_gid;
$arr['item_private'] = $private;
call_hooks('post_local',$arr);
$post = item_store($arr);
$post_id = $post['item_id'];

View File

@ -2,7 +2,7 @@
namespace Zotlabs\Module; /** @file */
require_once('include/zot.php');
require_once('include/security.php');
class Settings extends \Zotlabs\Web\Controller {
@ -781,6 +781,8 @@ class Settings extends \Zotlabs\Web\Controller {
if((argc() > 1) && (argv(1) === 'tokens')) {
$atoken = null;
$atoken_xchan = '';
if(argc() > 2) {
$id = argv(2);
@ -793,12 +795,14 @@ class Settings extends \Zotlabs\Web\Controller {
$atoken = $atoken[0];
$atoken_xchan = substr($channel['channel_hash'],0,16) . '.' . $atoken['atoken_name'];
}
if($atoken && argc() > 3 && argv(3) === 'drop') {
$r = q("delete from atoken where atoken_id = %d",
intval($id)
);
atoken_delete($id);
$atoken = null;
$atoken_xchan = '';
}
}
$t = q("select * from atoken where atoken_uid = %d",
intval(local_channel())
);

View File

@ -57,6 +57,7 @@ function account_verify_password($login, $pass) {
);
if($x) {
$ret['xchan'] = atoken_xchan($x[0]);
atoken_create_xchan($ret['xchan']);
return $ret;
}
}

View File

@ -566,6 +566,7 @@ function contact_remove($channel_id, $abook_id) {
drop_item($rr['id'],false);
}
}
q("delete from abook where abook_id = %d and abook_channel = %d",
intval($abook['abook_id']),
@ -588,6 +589,11 @@ function contact_remove($channel_id, $abook_id) {
intval($channel_id)
);
$r = q("delete from abconfig where chan = %d and xchan = '%s'",
intval($channel_id),
dbesc($abook['abook_xchan'])
);
return true;
}

View File

@ -786,7 +786,7 @@ function import_menus($channel,$menus) {
$mitem['mitem_link'] = str_replace('[channelurl]',z_root() . '/channel/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[pageurl]',z_root() . '/page/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[storeurl]',z_root() . '/store/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[cloudurl]',z_root() . '/cloud/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
$mitem['mitem_desc'] = escape_tags($it['desc']);
@ -871,7 +871,7 @@ function sync_menus($channel,$menus) {
$mitem['mitem_link'] = str_replace('[channelurl]',z_root() . '/channel/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[pageurl]',z_root() . '/page/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[storeurl]',z_root() . '/store/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[cloudurl]',z_root() . '/cloud/' . $channel['channel_address'],$it['link']);
$mitem['mitem_link'] = str_replace('[baseurl]',z_root(),$it['link']);
$mitem['mitem_desc'] = escape_tags($it['desc']);

View File

@ -49,7 +49,7 @@ function menu_element($channel,$menu) {
$entry['link'] = str_replace(z_root() . '/channel/' . $channel['channel_address'],'[channelurl]',$it['mitem_link']);
$entry['link'] = str_replace(z_root() . '/page/' . $channel['channel_address'],'[pageurl]',$it['mitem_link']);
$entry['link'] = str_replace(z_root() . '/store/' . $channel['channel_address'],'[storeurl]',$it['mitem_link']);
$entry['link'] = str_replace(z_root() . '/cloud/' . $channel['channel_address'],'[cloudurl]',$it['mitem_link']);
$entry['link'] = str_replace(z_root(),'[baseurl]',$it['mitem_link']);
$entry['desc'] = $it['mitem_desc'];

View File

@ -122,13 +122,21 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
dbesc($observer_xchan)
);
if(! $x) {
// not in address book, see if they've got an xchan
$y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1",
dbesc($observer_xchan)
);
// no xchan either, see if they've got a guest access token
if(! $y)
$x = atoken_abook($uid,$observer_xchan);
// see if they've got a guest access token; these are treated as connections
$y = atoken_abook($uid,$observer_xchan);
if($y)
$x = array($y);
if(! $x) {
// not in address book and no guest token, see if they've got an xchan
// these *may* have individual (PERMS_SPECIFIC) permissions, but are not connections
$y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1",
dbesc($observer_xchan)
);
if($y) {
$x = array(pseudo_abook($y[0]));
}
}
}
$abook_checked = true;
@ -190,7 +198,7 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
// If we're still here, we have an observer, check the network.
if($channel_perm & PERMS_NETWORK) {
if(($x && $x[0]['xchan_network'] === 'zot') || ($y && $y[0]['xchan_network'] === 'zot')) {
if($x && $x[0]['xchan_network'] === 'zot') {
$ret[$perm_name] = true;
continue;
}
@ -238,6 +246,12 @@ function get_all_perms($uid, $observer_xchan, $internal_use = true) {
// They're a contact, so they have permission
if($channel_perm & PERMS_CONTACTS) {
// it was a fake abook entry, not really a connection
if(array_key_exists('abook_pseudo',$x[0]) && intval($x[0]['abook_pseudo'])) {
$ret[$perm_name] = false;
continue;
}
$ret[$perm_name] = true;
continue;
}
@ -334,13 +348,21 @@ function perm_is_allowed($uid, $observer_xchan, $permission) {
return false;
if(! $x) {
// not in address book, see if they've got an xchan
$y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1",
dbesc($observer_xchan)
);
// no xchan either, see if they've got a guest access token
if(! $y)
$x = atoken_abook($uid,$observer_xchan);
// see if they've got a guest access token
$y = atoken_abook($uid,$observer_xchan);
if($y)
$x = array($y);
if(! $x) {
// not in address book and no guest token, see if they've got an xchan
$y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1",
dbesc($observer_xchan)
);
if($y) {
$x = array(pseudo_abook($y[0]));
}
}
}
$abperms = load_abconfig($uid,$observer_xchan,'my_perms');
}
@ -410,6 +432,10 @@ function perm_is_allowed($uid, $observer_xchan, $permission) {
// They're a contact, so they have permission
if($channel_perm & PERMS_CONTACTS) {
// it was a fake abook entry, not really a connection
if(array_key_exists('abook_pseudo',$x[0]) && intval($x[0]['abook_pseudo'])) {
return false;
}
return true;
}

View File

@ -108,6 +108,7 @@ function atoken_xchan($atoken) {
'xchan_name' => $atoken['atoken_name'],
'xchan_addr' => t('guest:') . $atoken['atoken_name'] . '@' . \App::get_hostname(),
'xchan_network' => 'unknown',
'xchan_url' => z_root(),
'xchan_hidden' => 1,
'xchan_photo_mimetype' => 'image/jpeg',
'xchan_photo_l' => get_default_profile_photo(300),
@ -119,6 +120,62 @@ function atoken_xchan($atoken) {
return null;
}
function atoken_delete($atoken_id) {
$r = q("select * from atoken where atoken_id = %d",
intval($atoken_id)
);
if(! $r)
return;
$c = q("select channel_id, channel_hash from channel where channel_id = %d",
intval($r[0]['atoken_uid'])
);
if(! $c)
return;
$atoken_xchan = substr($c[0]['channel_hash'],0,16) . '.' . $r[0]['atoken_name'];
q("delete from atoken where atoken_id = %d",
intval($atoken_id)
);
q("delete from abconfig where chan = %d and xchan = '%s'",
intval($c[0]['channel_id']),
dbesc($atoken_xchan)
);
}
// in order for atoken logins to create content (such as posts) they need a stored xchan.
// we'll create one on the first atoken_login; it can't really ever go away but perhaps
// @fixme we should set xchan_deleted if it's expired or removed
function atoken_create_xchan($xchan) {
$r = q("select xchan_hash from xchan where xchan_hash = '%s'",
dbesc($xchan['xchan_hash'])
);
if($r)
return;
$r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_photo_mimetype, xchan_photo_l, xchan_photo_m, xchan_photo_s )
values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ",
dbesc($xchan['xchan_hash']),
dbesc($xchan['xchan_hash']),
dbesc($xchan['xchan_addr']),
dbesc($xchan['xchan_url']),
dbesc($xchan['xchan_name']),
dbesc($xchan['xchan_network']),
dbesc($xchan['xchan_photo_mimetype']),
dbesc($xchan['xchan_photo_l']),
dbesc($xchan['xchan_photo_m']),
dbesc($xchan['xchan_photo_s'])
);
return true;
}
function atoken_abook($uid,$xchan_hash) {
if(substr($xchan_hash,16,1) != '.')
@ -149,6 +206,21 @@ function atoken_abook($uid,$xchan_hash) {
}
function pseudo_abook($xchan) {
if(! $xchan)
return false;
// set abook_pseudo to flag that we aren't really connected.
$xchan['abook_pseudo'] = 1;
$xchan['abook_blocked'] = 0;
$xchan['abook_ignored'] = 0;
$xchan['abook_pending'] = 0;
return $xchan;
}
/**
* @brief Change to another channel with current logged-in account.
*
@ -424,7 +496,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 protekt 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).