get permission discovery working - guid sigs were getting truncated in db

This commit is contained in:
friendica 2012-10-31 20:53:02 -07:00
parent 0dd06b736a
commit 78f64c90a3
4 changed files with 82 additions and 120 deletions

View File

@ -29,7 +29,7 @@
* @returns: array of all permissions, key is permission name, value is integer 0 or 1
*/
function get_all_perms($uid,$observer) {
function get_all_perms($uid,$observer,$internal_use = true) {
global $global_perms;
@ -61,21 +61,21 @@ function get_all_perms($uid,$observer) {
}
if(! $r) {
$ret[$perm_name] = 0;
$ret[$perm_name] = false;
continue;
}
// Check if this $uid is actually the $observer
if($r[0]['channel_hash'] === $observer) {
$ret[$perm_name] = 1;
$ret[$perm_name] = true;
continue;
}
// If it's an unauthenticated observer, we only need to see if PERMS_PUBLIC is set
if(! $observer) {
$ret[$perm_name] = (($r[0][$channel_perm] & PERMS_PUBLIC) ? 1 : 0);
$ret[$perm_name] = (($r[0][$channel_perm] & PERMS_PUBLIC) ? true : false);
continue;
}
@ -83,7 +83,7 @@ function get_all_perms($uid,$observer) {
// If we're still here, we have an observer, which means they're in the network.
if($r[0][$channel_perm] & PERMS_NETWORK) {
$ret[$perm_name] = 1;
$ret[$perm_name] = true;
continue;
}
@ -99,9 +99,9 @@ function get_all_perms($uid,$observer) {
}
if($c)
$ret[$perm_name] = 1;
$ret[$perm_name] = true;
else
$ret[$perm_name] = 0;
$ret[$perm_name] = false;
continue;
}
@ -122,7 +122,7 @@ function get_all_perms($uid,$observer) {
// If they're blocked - they can't read or write
if((! $x) || ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED)) {
$ret[$perm_name] = 0;
$ret[$perm_name] = false;
continue;
}
@ -131,15 +131,16 @@ function get_all_perms($uid,$observer) {
if($r && $r[0][$channel_perm] & PERMS_CONTACTS) {
// Check if this is a write permission and they are being ignored
// This flag is only visible internally.
if((! $global_perms[$permission][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED)) {
$ret[$perm_name] = 0;
if(($internal_use) && (! $global_perms[$permission][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED)) {
$ret[$perm_name] = false;
continue;
}
// Otherwise they're a contact, so they have permission
$ret[$perm_name] = 1;
$ret[$perm_name] = true;
continue;
}
@ -147,14 +148,14 @@ function get_all_perms($uid,$observer) {
if(($r) && ($r[0][$channel_perm] & PERMS_SPECIFIC)) {
if(($x) && ($x[0]['abook_my_perms'] & $global_perms[$permission][1])) {
$ret[$perm_name] = 1;
$ret[$perm_name] = true;
continue;
}
}
// No permissions allowed.
$ret[$perm_name] = 0;
$ret[$perm_name] = false;
continue;
}
@ -249,98 +250,3 @@ function perm_is_allowed($uid,$observer,$permission) {
function map_perms($channel,$zguid,$zsig) {
$is_contact = false;
$is_site = false;
$is_network = false;
$is_anybody = true;
// To avoid sending the lengthy target_sig with each request,
// We should provide an array of results for each target
// and let the sender match the signature.
if(strlen($zguid) && strlen($zsig)) {
$is_network = true;
$r = q("select * from contact where guid = '%s' and uid = %d limit 1",
dbesc($zguid),
intval($channel['channel_id'])
);
if($r && count($r)) {
$is_contact = true;
$contact = $r[0];
}
$r = q("select * from channel where channel_guid = '%s'",
dbesc($zguid)
);
if($r && count($r)) {
foreach($r as $rr) {
if(base64url_encode(rsa_sign($rr['channel_guid'],$rr['channel_prvkey'])) === $zsig) {
$is_site = true;
break;
}
}
}
}
$perms = array(
'view_stream' => array('channel_r_stream', PERMS_R_STREAM ),
'view_profile' => array('channel_r_profile', PERMS_R_PROFILE),
'view_photos' => array('channel_r_photos', PERMS_R_PHOTOS),
'view_contacts' => array('channel_r_abook', PERMS_R_ABOOK),
'send_stream' => array('channel_w_stream', PERMS_W_STREAM),
'post_wall' => array('channel_w_wall', PERMS_W_WALL),
'tag_deliver' => array('channel_w_tagwall', PERMS_W_TAGWALL),
'post_comments' => array('channel_w_comment', PERMS_W_COMMENT),
'post_mail' => array('channel_w_mail', PERMS_W_MAIL),
'post_photos' => array('channel_w_photos', PERMS_W_PHOTOS),
'chat' => array('channel_w_chat', PERMS_W_CHAT),
);
$ret = array();
foreach($perms as $k => $v) {
$ret[$k] = z_check_perms($k,$v,$channel,$contact,$is_contact,$is_site,$is_network,$is_anybody);
}
return $ret;
}
function z_check_perms($k,$v,$channel,$contact,$is_contact,$is_site,$is_network,$is_anybody) {
$allow = (($contact['self']) ? true : false);
switch($channel[$v[0]]) {
case PERMS_PUBLIC:
if($is_anybody)
$allow = true;
break;
case PERMS_NETWORK:
if($is_network)
$allow = true;
break;
case PERMS_SITE:
if($is_site)
$allow = true;
break;
case PERMS_CONTACTS:
if($is_contact)
$allow = true;
break;
case PERMS_SPECIFIC:
if($is_contact && is_array($contact) && ($contact['my_perms'] & $v[1]))
$allow = true;
break;
default:
break;
}
return $allow;
}

View File

@ -72,6 +72,57 @@ function zot_notify($channel,$url) {
return($x);
}
function zot_finger($webbie,$channel) {
if(strpos($webbie,'@') === false) {
$address = $webbie;
$host = get_app()->get_hostname();
}
else {
$address = substr($webbie,0,strpos($webbie,'@'));
$host = substr($webbie,strpos($webbie,'@')+1);
}
$xchan_addr = $address . '@' . $host;
$r = q("select xchan.*, hubloc.* from xchan
left join hubloc on xchan_hash = hubloc_hash
where xchan_addr = '%s' and (hubloc_flags & %d) limit 1",
dbesc($xchan_address),
intval(HUBLOC_FLAGS_PRIMARY)
);
if($r) {
$url = $r[0]['hubloc_url'];
}
else {
$url = 'https://' . $host;
}
$rhs = '/.well-known/zot-guid';
if($channel) {
$postvars = array(
'address' => $address,
'target' => $channel['channel_guid'],
'target_sig' => $channel['channel_guid_sig']
);
$result = z_post_url($url . $rhs,$postvars);
if(! $result['success'])
$result = z_post_url('http://' . $host . $rhs,$postvars);
}
else {
$rhs .= 'address=' . urlencode($address);
$result = z_fetch_url($url . $rhs);
if(! $result['success'])
$result = z_fetch_url('http://' . $host . $rhs);
}
return $result;
}
function zot_gethub($arr) {

View File

@ -128,7 +128,7 @@ CREATE TABLE IF NOT EXISTS `channel` (
`channel_name` char(255) NOT NULL DEFAULT '',
`channel_address` char(255) NOT NULL DEFAULT '',
`channel_guid` char(255) NOT NULL DEFAULT '',
`channel_guid_sig` char(255) NOT NULL DEFAULT '',
`channel_guid_sig` text NOT NULL,
`channel_hash` char(255) NOT NULL DEFAULT '',
`channel_timezone` char(128) NOT NULL DEFAULT 'UTC',
`channel_location` char(255) NOT NULL DEFAULT '',
@ -183,7 +183,6 @@ CREATE TABLE IF NOT EXISTS `channel` (
KEY `channel_w_photos` (`channel_w_photos`),
KEY `channel_w_chat` (`channel_w_chat`),
KEY `channel_guid` (`channel_guid`),
KEY `channel_guid_sig` (`channel_guid_sig`),
KEY `channel_hash` (`channel_hash`),
KEY `channel_expire_days` (`channel_expire_days`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

View File

@ -7,10 +7,11 @@ function zfinger_init(&$a) {
$ret = array('success' => false);
$zguid = ((x($_REQUEST,'guid')) ? $_REQUEST['guid'] : '');
$zaddr = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : '');
$ztarget = ((x($_REQUEST,'target')) ? $_REQUEST['target'] : '');
$zsig = ((x($_REQUEST,'target_sig')) ? $_REQUEST['target_sig'] : '');
$zguid = ((x($_REQUEST,'guid')) ? $_REQUEST['guid'] : '');
$zaddr = ((x($_REQUEST,'address')) ? $_REQUEST['address'] : '');
$ztarget = ((x($_REQUEST,'target')) ? trim($_REQUEST['target']) : '');
$zsig = ((x($_REQUEST,'target_sig')) ? trim($_REQUEST['target_sig']) : '');
$r = null;
@ -63,23 +64,28 @@ function zfinger_init(&$a) {
$ret['photo_updated'] = $e['xchan_photo_date'];
$ret['target'] = $ztarget;
$ret['target_sig'] = $zsig;
$ret['permissions'] = map_perms($r[0],$ztarget,$zsig);
$ret['permissions'] = get_all_perms($e['channel_id'],(($ztarget && $zsig)
? base64url_encode(hash('whirlpool',$ztarget . $zsig,true))
: '' ),false);
// $ret['profile'] = $profile;
// array of (verified) hubs this channel uses
$ret['hubs'] = array();
$ret['locations'] = array();
$x = zot_get_hubloc(array($e['channel_hash']));
if($x && count($x)) {
foreach($x as $hub) {
if(! ($hub['hubloc_flags'] & HUBLOC_FLAGS_UNVERIFIED)) {
$ret['hubs'][] = array(
$ret['locations'][] = array(
'host' => $hub['hubloc_host'],
'address' => $hub['hubloc_addr'],
'primary' => (($hub['hubloc_flags'] & HUBLOC_FLAGS_PRIMARY) ? true : false),
'url' => $hub['hubloc_url'],
'url_sig' => $hub['hubloc_url_sig'],
'host' => $hub['hubloc_host'],
'address' => $hub['hubloc_addr'],
'callback' => $hub['hubloc_callback'],
'sitekey' => $hub['hubloc_sitekey']
);