This checkin should make all permission modes work correctly with atokens (they should be able to post content if allowed to). It also removes the strict linkage between permissions and connections so any individual permission can be set for any xchan; even those for which you have no connections.
This commit is contained in:
parent
4c76b31684
commit
3a7d3e3a54
@ -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
|
||||
|
@ -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())
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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).
|
||||
|
Reference in New Issue
Block a user