aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfriendica <info@friendica.com>2012-10-28 18:50:35 -0700
committerfriendica <info@friendica.com>2012-10-28 18:50:35 -0700
commit4bcf19632bc5158095a5d2d5d63dea1b25b146b7 (patch)
tree362ccfbd661b779bd864fa6c7416c9a7b1c15069
parent1a9ab127482ee4eb17e3d2bd0ffa222f7053715b (diff)
downloadvolse-hubzilla-4bcf19632bc5158095a5d2d5d63dea1b25b146b7.tar.gz
volse-hubzilla-4bcf19632bc5158095a5d2d5d63dea1b25b146b7.tar.bz2
volse-hubzilla-4bcf19632bc5158095a5d2d5d63dea1b25b146b7.zip
Now have a solid permissions model. Create a few functions to enumerate them and then we're off to the races.
-rw-r--r--boot.php27
-rw-r--r--include/Contact.php93
-rw-r--r--include/permissions.php338
-rw-r--r--include/security.php6
-rw-r--r--mod/item.php2
-rw-r--r--version.inc2
6 files changed, 367 insertions, 101 deletions
diff --git a/boot.php b/boot.php
index 10f1cddc7..d7b51867f 100644
--- a/boot.php
+++ b/boot.php
@@ -8,6 +8,7 @@ require_once('include/datetime.php');
require_once('include/language.php');
require_once('include/nav.php');
require_once('include/cache.php');
+require_once('include/permissions.php');
require_once('library/Mobile_Detect/Mobile_Detect.php');
require_once('include/BaseObject.php');
@@ -182,6 +183,14 @@ define ( 'PERMS_CONTACTS' , 0x0008 );
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
*/
@@ -394,11 +403,11 @@ if(! class_exists('App')) {
class App {
- public $account = null; // account record
-
- private $channel = null; // channel record
- private $observer = null; // xchan record
- private $widgets = array(); // widgets for this page
+ public $account = null; // account record
+ private $channel = null; // channel record
+ private $observer = null; // xchan record
+ private $perms = null; // observer permissions
+ private $widgets = array(); // widgets for this page
@@ -654,6 +663,14 @@ if(! class_exists('App')) {
return $this->observer;
}
+ function set_perms($perms) {
+ $this->perms = $perms;
+ }
+
+ function get_perms() {
+ return $this->perms;
+ }
+
function get_apps() {
return $this->apps;
}
diff --git a/include/Contact.php b/include/Contact.php
index fc0a6dd25..f442f112c 100644
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -1,100 +1,7 @@
<?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;
-}
diff --git a/include/permissions.php b/include/permissions.php
new file mode 100644
index 000000000..162f8a71c
--- /dev/null
+++ b/include/permissions.php
@@ -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;
+}
+
diff --git a/include/security.php b/include/security.php
index 50c2337bf..dbeeb9177 100644
--- a/include/security.php
+++ b/include/security.php
@@ -210,7 +210,7 @@ function change_channel($change_channel) {
intval($change_channel),
intval(get_account_id())
);
- if($r && count($r)) {
+ if($r) {
$hash = $r[0]['channel_hash'];
$_SESSION['uid'] = intval($r[0]['channel_id']);
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",
dbesc($hash)
);
- if($x && count($x))
+ if($x) {
get_app()->set_observer($x[0]);
+ get_app()->set_perms(get_all_perms(local_user(),$hash));
+ }
}
return $ret;
diff --git a/mod/item.php b/mod/item.php
index 98541b570..1373f48b6 100644
--- a/mod/item.php
+++ b/mod/item.php
@@ -28,6 +28,8 @@ function item_post(&$a) {
if((! local_user()) && (! remote_user()) && (! x($_REQUEST,'commenter')))
return;
+ logger('get_perms: ' . print_r($a->get_perms(),true));
+
require_once('include/security.php');
$uid = local_user();
diff --git a/version.inc b/version.inc
index 1c422ffa2..860f87211 100644
--- a/version.inc
+++ b/version.inc
@@ -1 +1 @@
-2012-10-26.119
+2012-10-28.121