Now have a solid permissions model. Create a few functions to enumerate them and then we're off to the races.
This commit is contained in:
parent
1a9ab12748
commit
4bcf19632b
27
boot.php
27
boot.php
@ -8,6 +8,7 @@ require_once('include/datetime.php');
|
|||||||
require_once('include/language.php');
|
require_once('include/language.php');
|
||||||
require_once('include/nav.php');
|
require_once('include/nav.php');
|
||||||
require_once('include/cache.php');
|
require_once('include/cache.php');
|
||||||
|
require_once('include/permissions.php');
|
||||||
require_once('library/Mobile_Detect/Mobile_Detect.php');
|
require_once('library/Mobile_Detect/Mobile_Detect.php');
|
||||||
require_once('include/BaseObject.php');
|
require_once('include/BaseObject.php');
|
||||||
|
|
||||||
@ -182,6 +183,14 @@ define ( 'PERMS_CONTACTS' , 0x0008 );
|
|||||||
define ( 'PERMS_SPECIFIC' , 0x0080 );
|
define ( 'PERMS_SPECIFIC' , 0x0080 );
|
||||||
|
|
||||||
|
|
||||||
|
// Address book flags
|
||||||
|
|
||||||
|
define ( 'ABOOK_FLAG_BLOCKED' , 0x0001);
|
||||||
|
define ( 'ABOOK_FLAG_IGNORED' , 0x0002);
|
||||||
|
define ( 'ABOOK_FLAG_HIDDEN' , 0x0004);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of "people who like (or don't like) this" that we will list by name
|
* Maximum number of "people who like (or don't like) this" that we will list by name
|
||||||
*/
|
*/
|
||||||
@ -394,11 +403,11 @@ if(! class_exists('App')) {
|
|||||||
class App {
|
class App {
|
||||||
|
|
||||||
|
|
||||||
public $account = null; // account record
|
public $account = null; // account record
|
||||||
|
private $channel = null; // channel record
|
||||||
private $channel = null; // channel record
|
private $observer = null; // xchan record
|
||||||
private $observer = null; // xchan record
|
private $perms = null; // observer permissions
|
||||||
private $widgets = array(); // widgets for this page
|
private $widgets = array(); // widgets for this page
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -654,6 +663,14 @@ if(! class_exists('App')) {
|
|||||||
return $this->observer;
|
return $this->observer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function set_perms($perms) {
|
||||||
|
$this->perms = $perms;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_perms() {
|
||||||
|
return $this->perms;
|
||||||
|
}
|
||||||
|
|
||||||
function get_apps() {
|
function get_apps() {
|
||||||
return $this->apps;
|
return $this->apps;
|
||||||
}
|
}
|
||||||
|
@ -1,100 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
338
include/permissions.php
Normal file
338
include/permissions.php
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$global_perms = array(
|
||||||
|
// Read only permissions
|
||||||
|
'view_stream' => array('channel_r_stream', PERMS_R_STREAM, true),
|
||||||
|
'view_profile' => array('channel_r_profile', PERMS_R_PROFILE, true),
|
||||||
|
'view_photos' => array('channel_r_photos', PERMS_R_PHOTOS, true),
|
||||||
|
'view_contacts' => array('channel_r_abook', PERMS_R_ABOOK, true),
|
||||||
|
|
||||||
|
// Write permissions
|
||||||
|
'send_stream' => array('channel_w_stream', PERMS_W_STREAM, false),
|
||||||
|
'post_wall' => array('channel_w_wall', PERMS_W_WALL, false),
|
||||||
|
'tag_deliver' => array('channel_w_tagwall', PERMS_W_TAGWALL, false),
|
||||||
|
'post_comments' => array('channel_w_comment', PERMS_W_COMMENT, false),
|
||||||
|
'post_mail' => array('channel_w_mail', PERMS_W_MAIL, false),
|
||||||
|
'post_photos' => array('channel_w_photos', PERMS_W_PHOTOS, false),
|
||||||
|
'chat' => array('channel_w_chat', PERMS_W_CHAT, false),
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function get_all_perms($uid,$observer) {
|
||||||
|
|
||||||
|
global $global_perms;
|
||||||
|
|
||||||
|
// Save lots of individual lookups
|
||||||
|
|
||||||
|
$r = null;
|
||||||
|
$c = null;
|
||||||
|
$x = null;
|
||||||
|
|
||||||
|
$channel_checked = false;
|
||||||
|
$onsite_checked = false;
|
||||||
|
$abook_checked = false;
|
||||||
|
|
||||||
|
$ret = array();
|
||||||
|
|
||||||
|
foreach($global_perms as $perm_name => $permission) {
|
||||||
|
|
||||||
|
// First find out what the channel owner declared permissions to be.
|
||||||
|
|
||||||
|
$channel_perm = $permission[0];
|
||||||
|
|
||||||
|
if(! $channel_checked) {
|
||||||
|
$r = q("select %s, channel_hash from channel where channel_id = %d limit 1",
|
||||||
|
dbesc($channel_perm),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
|
||||||
|
$channel_checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! $r) {
|
||||||
|
$ret[$perm_name] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this $uid is actually the $observer
|
||||||
|
|
||||||
|
if($r[0]['channel_hash'] === $observer) {
|
||||||
|
$ret[$perm_name] = 1;
|
||||||
|
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);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If PERMS_SITE is specified, find out if they've got an account on this hub
|
||||||
|
|
||||||
|
if($r[0][$channel_perm] & PERMS_SITE) {
|
||||||
|
if(! $onsite_checked) {
|
||||||
|
$c = q("select channel_hash from channel where channel_hash = '%s' limit 1",
|
||||||
|
dbesc($observer)
|
||||||
|
);
|
||||||
|
|
||||||
|
$onsite_checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($c)
|
||||||
|
$ret[$perm_name] = 1;
|
||||||
|
else
|
||||||
|
$ret[$perm_name] = 0;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If PERMS_CONTACTS or PERMS_SPECIFIC, they need to be in your address book
|
||||||
|
// and not blocked/ignored
|
||||||
|
|
||||||
|
if(! $abook_checked) {
|
||||||
|
$x = q("select abook_my_perms, abook_flags from abook
|
||||||
|
where abook_channel = %d and abook_xchan = '%s' limit 1",
|
||||||
|
intval($uid),
|
||||||
|
dbesc($observer)
|
||||||
|
);
|
||||||
|
$abook_checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If they're blocked - they can't read or write
|
||||||
|
|
||||||
|
if((! $x) || ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED)) {
|
||||||
|
$ret[$perm_name] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're still going, they are a contact
|
||||||
|
|
||||||
|
if($r && $r[0][$channel_perm] & PERMS_CONTACTS) {
|
||||||
|
|
||||||
|
// Check if this is a write permission and they are being ignored
|
||||||
|
|
||||||
|
if((! $global_perms[$permission][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED)) {
|
||||||
|
$ret[$perm_name] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise they're a contact, so they have permission
|
||||||
|
|
||||||
|
$ret[$perm_name] = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permission granted to certain channels. Let's see if the observer is one of them
|
||||||
|
|
||||||
|
if(($r) && ($r[0][$channel_perm] & PERMS_SPECIFIC)) {
|
||||||
|
if(($x) && ($x[0]['abook_my_perms'] & $global_perms[$permission][1])) {
|
||||||
|
$ret[$perm_name] = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No permissions allowed.
|
||||||
|
|
||||||
|
$ret[$perm_name] = 0;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function perm_is_allowed($uid,$observer,$perm_to_check) {
|
||||||
|
|
||||||
|
global $global_perms;
|
||||||
|
|
||||||
|
// First find out what the channel owner declared permissions to be.
|
||||||
|
|
||||||
|
$channel_perm = $global_perms[$permission][0];
|
||||||
|
|
||||||
|
$r = q("select %s, channel_hash from channel where channel_id = %d limit 1",
|
||||||
|
dbesc($channel_perm),
|
||||||
|
intval($uid)
|
||||||
|
);
|
||||||
|
if(! $r)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if this $uid is actually the $observer
|
||||||
|
|
||||||
|
if($r[0]['channel_hash'] === $observer)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If it's an unauthenticated observer, we only need to see if PERMS_PUBLIC is set
|
||||||
|
|
||||||
|
if(! $observer) {
|
||||||
|
return(($r[0][$channel_perm] & PERMS_PUBLIC) ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're still here, we have an observer, which means they're in the network.
|
||||||
|
|
||||||
|
if($r[0][$channel_perm] & PERMS_NETWORK)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
|
||||||
|
// If PERMS_SITE is specified, find out if they've got an account on this hub
|
||||||
|
|
||||||
|
if($r[0][$channel_perm] & PERMS_SITE) {
|
||||||
|
$c = q("select channel_hash from channel where channel_hash = '%s' limit 1",
|
||||||
|
dbesc($observer)
|
||||||
|
);
|
||||||
|
if($c)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If PERMS_CONTACTS or PERMS_SPECIFIC, they need to be in your address book
|
||||||
|
// and not blocked/ignored
|
||||||
|
|
||||||
|
$x = q("select abook_my_perms, abook_flags from abook where abook_channel = %d and abook_xchan = '%s' limit 1",
|
||||||
|
intval($uid),
|
||||||
|
dbesc($observer)
|
||||||
|
);
|
||||||
|
|
||||||
|
// If they're blocked - they can't read or write
|
||||||
|
|
||||||
|
if((! $x) || ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If we're still going, they are a contact
|
||||||
|
|
||||||
|
if($r[0][$channel_perm] & PERMS_CONTACTS) {
|
||||||
|
|
||||||
|
// Check if this is a write permission and they are being ignored
|
||||||
|
|
||||||
|
if((! $global_perms[$permission][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Otherwise they're a contact, so they have permission
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permission granted to certain channels. Let's see if the observer is one of them
|
||||||
|
|
||||||
|
if($r[0][$channel_perm] & PERMS_SPECIFIC) {
|
||||||
|
if($x[0]['abook_my_perms'] & $global_perms[$permission][1])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No permissions allowed.
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -210,7 +210,7 @@ function change_channel($change_channel) {
|
|||||||
intval($change_channel),
|
intval($change_channel),
|
||||||
intval(get_account_id())
|
intval(get_account_id())
|
||||||
);
|
);
|
||||||
if($r && count($r)) {
|
if($r) {
|
||||||
$hash = $r[0]['channel_hash'];
|
$hash = $r[0]['channel_hash'];
|
||||||
$_SESSION['uid'] = intval($r[0]['channel_id']);
|
$_SESSION['uid'] = intval($r[0]['channel_id']);
|
||||||
get_app()->set_channel($r[0]);
|
get_app()->set_channel($r[0]);
|
||||||
@ -221,8 +221,10 @@ function change_channel($change_channel) {
|
|||||||
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
|
$x = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||||
dbesc($hash)
|
dbesc($hash)
|
||||||
);
|
);
|
||||||
if($x && count($x))
|
if($x) {
|
||||||
get_app()->set_observer($x[0]);
|
get_app()->set_observer($x[0]);
|
||||||
|
get_app()->set_perms(get_all_perms(local_user(),$hash));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
|
@ -28,6 +28,8 @@ function item_post(&$a) {
|
|||||||
if((! local_user()) && (! remote_user()) && (! x($_REQUEST,'commenter')))
|
if((! local_user()) && (! remote_user()) && (! x($_REQUEST,'commenter')))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
logger('get_perms: ' . print_r($a->get_perms(),true));
|
||||||
|
|
||||||
require_once('include/security.php');
|
require_once('include/security.php');
|
||||||
|
|
||||||
$uid = local_user();
|
$uid = local_user();
|
||||||
|
@ -1 +1 @@
|
|||||||
2012-10-26.119
|
2012-10-28.121
|
||||||
|
Reference in New Issue
Block a user