aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Access/Permissions.php158
-rw-r--r--tests/unit/Access/PermissionsTest.php148
2 files changed, 254 insertions, 52 deletions
diff --git a/Zotlabs/Access/Permissions.php b/Zotlabs/Access/Permissions.php
index d51e4d0ea..74286934f 100644
--- a/Zotlabs/Access/Permissions.php
+++ b/Zotlabs/Access/Permissions.php
@@ -1,45 +1,52 @@
<?php
-
namespace Zotlabs\Access;
use Zotlabs\Lib as Zlib;
+/**
+ * @brief Extensible permissions.
+ *
+ * To add new permissions, add to the list of $perms below, with a simple description.
+ *
+ * Also visit PermissionRoles.php and add to the $ret['perms_connect'] property for any role
+ * if this permission should be granted to new connections.
+ *
+ * Next look at PermissionRoles::new_custom_perms() and provide a handler for updating custom
+ * permission roles. You will want to set a default PermissionLimit for each channel and also
+ * provide a sane default for any existing connections. You may or may not wish to provide a
+ * default auto permission. If in doubt, leave this alone as custom permissions by definition
+ * are the responsibility of the channel owner to manage. You just don't want to create any
+ * suprises or break things so you have an opportunity to provide sane settings.
+ *
+ * Update the version here and in PermissionRoles.
+ *
+ *
+ * Permissions with 'view' in the name are considered read permissions. Anything
+ * else requires authentication. Read permission limits are PERMS_PUBLIC and anything else
+ * is given PERMS_SPECIFIC.
+ *
+ * PermissionLimits::Std_limits() retrieves the standard limits. A permission role
+ * MAY alter an individual setting after retrieving the Std_limits if you require
+ * something different for a specific permission within the given role.
+ *
+ */
class Permissions {
- /**
- * Extensible permissions.
- * To add new permissions, add to the list of $perms below, with a simple description.
- *
- * Also visit PermissionRoles.php and add to the $ret['perms_connect'] property for any role
- * if this permission should be granted to new connections.
- *
- * Next look at PermissionRoles::new_custom_perms() and provide a handler for updating custom
- * permission roles. You will want to set a default PermissionLimit for each channel and also
- * provide a sane default for any existing connections. You may or may not wish to provide a
- * default auto permission. If in doubt, leave this alone as custom permissions by definition
- * are the responsibility of the channel owner to manage. You just don't want to create any
- * suprises or break things so you have an opportunity to provide sane settings.
- *
- * Update the version here and in PermissionRoles
- *
- *
- * Permissions with 'view' in the name are considered read permissions. Anything
- * else requires authentication. Read permission limits are PERMS_PUBLIC and anything else
- * is given PERMS_SPECIFIC.
- *
- * PermissionLimits::Std_limits() retrieves the standard limits. A permission role
- * MAY alter an individual setting after retrieving the Std_limits if you require
- * something different for a specific permission within the given role.
- *
- */
-
static public function version() {
// This must match the version in PermissionRoles.php before permission updates can run.
return 2;
}
-
+ /**
+ * @brief Return an array with Permissions.
+ *
+ * @hooks permissions_list
+ * * \e array \b permissions
+ * * \e string \b filter
+ * @param string $filter (optional) only passed to hook permission_list
+ * @return Associative array with permissions and short description.
+ */
static public function Perms($filter = '') {
$perms = [
@@ -63,18 +70,27 @@ class Permissions {
'delegate' => t('Can administer my channel')
];
- $x = array('permissions' => $perms, 'filter' => $filter);
- call_hooks('permissions_list',$x);
- return($x['permissions']);
+ $x = [
+ 'permissions' => $perms,
+ 'filter' => $filter
+ ];
+ call_hooks('permissions_list', $x);
+ return($x['permissions']);
}
+ /**
+ * @brief Perms from the above list that are blocked from anonymous observers.
+ *
+ * e.g. you must be authenticated.
+ *
+ * @hooks write_perms
+ * * \e array \b permissions
+ * @return Associative array with permissions and short description.
+ */
static public function BlockedAnonPerms() {
- // Perms from the above list that are blocked from anonymous observers.
- // e.g. you must be authenticated.
-
- $res = array();
+ $res = [];
$perms = PermissionLimits::Std_limits();
foreach($perms as $perm => $limit) {
if($limit != PERMS_PUBLIC) {
@@ -82,17 +98,22 @@ class Permissions {
}
}
- $x = array('permissions' => $res);
- call_hooks('write_perms',$x);
- return($x['permissions']);
+ $x = ['permissions' => $res];
+ call_hooks('write_perms', $x);
+ return($x['permissions']);
}
- // converts [ 0 => 'view_stream', ... ]
- // to [ 'view_stream' => 1 ]
- // for any permissions in $arr;
- // Undeclared permissions are set to 0
-
+ /**
+ * @brief Converts indexed perms array to associative perms array.
+ *
+ * Converts [ 0 => 'view_stream', ... ]
+ * to [ 'view_stream' => 1 ] for any permissions in $arr;
+ * Undeclared permissions which exist in Perms() are added and set to 0.
+ *
+ * @param array $arr
+ * @return array
+ */
static public function FilledPerms($arr) {
if(is_null($arr)) {
btlogger('FilledPerms: null');
@@ -101,15 +122,26 @@ class Permissions {
$everything = self::Perms();
$ret = [];
foreach($everything as $k => $v) {
- if(in_array($k,$arr))
+ if(in_array($k, $arr))
$ret[$k] = 1;
else
$ret[$k] = 0;
}
- return $ret;
+ return $ret;
}
+ /**
+ * @brief Convert perms array to indexed array.
+ *
+ * Converts [ 'view_stream' => 1 ] for any permissions in $arr
+ * to [ 0 => ['name' => 'view_stream', 'value' => 1], ... ]
+ *
+ * @param array $arr associative perms array 'view_stream' => 1
+ * @return Indexed array with elements that look like
+ * * \e string \b name the perm name (e.g. view_stream)
+ * * \e int \b value the value of the perm (e.g. 1)
+ */
static public function OPerms($arr) {
$ret = [];
if($arr) {
@@ -120,7 +152,12 @@ class Permissions {
return $ret;
}
-
+ /**
+ * @brief
+ *
+ * @param int $channel_id
+ * @return boolean|array
+ */
static public function FilledAutoperms($channel_id) {
if(! intval(get_pconfig($channel_id,'system','autoperms')))
return false;
@@ -137,16 +174,33 @@ class Permissions {
return $arr;
}
- static public function PermsCompare($p1,$p2) {
+ /**
+ * @brief Compares that all Permissions from $p1 exist also in $p2.
+ *
+ * @param array $p1 The perms that have to exist in $p2
+ * @param array $p2 The perms to compare against
+ * @return boolean true if all perms from $p1 exist also in $p2
+ */
+ static public function PermsCompare($p1, $p2) {
foreach($p1 as $k => $v) {
- if(! array_key_exists($k,$p2))
+ if(! array_key_exists($k, $p2))
return false;
+
if($p1[$k] != $p2[$k])
return false;
}
+
return true;
}
+ /**
+ * @brief
+ *
+ * @param int $channel_id A channel id
+ * @return associative array
+ * * \e array \b perms Permission array
+ * * \e int \b automatic 0 or 1
+ */
static public function connect_perms($channel_id) {
$my_perms = [];
@@ -155,7 +209,7 @@ class Permissions {
// If a default permcat exists, use that
- $pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default');
+ $pc = ((feature_enabled($channel_id,'permcats')) ? get_pconfig($channel_id,'system','default_permcat') : 'default');
if(! in_array($pc, [ '','default' ])) {
$pcp = new Zlib\Permcat($channel_id);
$permcat = $pcp->fetch($pc);
@@ -167,7 +221,7 @@ class Permissions {
}
// look up the permission role to see if it specified auto-connect
- // and if there was no permcat or a default permcat, set the perms
+ // and if there was no permcat or a default permcat, set the perms
// from the role
$role = get_pconfig($channel_id,'system','permissions_role');
@@ -195,7 +249,7 @@ class Permissions {
}
// If we reached this point with no permissions, the channel is using
- // custom perms but they are not automatic. They will be stored in abconfig with
+ // custom perms but they are not automatic. They will be stored in abconfig with
// the channel's channel_hash (the 'self' connection).
if(! $my_perms) {
diff --git a/tests/unit/Access/PermissionsTest.php b/tests/unit/Access/PermissionsTest.php
new file mode 100644
index 000000000..93c641fb1
--- /dev/null
+++ b/tests/unit/Access/PermissionsTest.php
@@ -0,0 +1,148 @@
+<?php
+/*
+ * Copyright (c) 2017 Hubzilla
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+namespace Zotlabs\Tests\Unit\Access;
+
+use Zotlabs\Tests\Unit\UnitTestCase;
+use Zotlabs\Access\Permissions;
+
+/**
+ * @brief Unit Test case for Permissions class.
+ *
+ * @covers Zotlabs\Access\Permissions
+ */
+class PermissionsTest extends UnitTestCase {
+
+ /**
+ * @dataProvider FilledPermsProvider
+ */
+ public function testFilledPerms($permarr, $expected) {
+ $this->markTestIncomplete(
+ 'Need to mock static function Permissions::Perms() ...'
+ );
+ //$this->assertEquals($expected, Permissions::FilledPerms($permarr));
+
+/* $perms = $this->getMockBuilder(Permissions::class)
+ ->setMethods(['Perms'])
+ ->getMock();
+ $perms->expects($this->once())
+ ->method('Perms');
+ // still calls the static self::Perms()
+ $perms->FilledPerms($permarr);
+*/
+ }
+ public function FilledPermsProvider() {
+ return [
+ 'empty' => [
+ [],
+ ['perm1' => 0, 'perm2' => 0]
+ ],
+ 'valild' => [
+ [['perm1' => 1]],
+ ['perm1' => 1, 'perm2' => 0]
+ ]
+ ];
+ }
+/* public function testFilledPermsNull() {
+ // need to mock global function btlogger();
+ Permissions::FilledPerms(null);
+ }
+*/
+ /**
+ * @dataProvider OPermsProvider
+ *
+ * @param array $permarr
+ * @param array $expected
+ */
+ public function testOPerms($permarr, $expected) {
+ $this->assertEquals($expected, Permissions::OPerms($permarr));
+ }
+ /**
+ * @return Associative array with test values for OPerms()
+ * * \e array Array to test
+ * * \e array Expect array
+ */
+ public function OPermsProvider() {
+ return [
+ 'empty' => [
+ [],
+ []
+ ],
+ 'valid' => [
+ ['perm1' => 1, 'perm2' => 0],
+ [['name' => 'perm1', 'value' => 1], ['name' => 'perm2', 'value' => 0]]
+ ],
+ 'null array' => [
+ null,
+ []
+ ]
+ ];
+ }
+
+
+ /**
+ * @dataProvider permsCompareProvider
+ *
+ * @param array $p1
+ * @param array $p2
+ * @param boolean $expectedresult
+ */
+ public function testPermsCompare($p1, $p2, $expectedresult) {
+ $this->assertEquals($expectedresult, Permissions::PermsCompare($p1, $p2));
+ }
+ /**
+ * @return Associative array with test values for PermsCompare()
+ * * \e array 1st array
+ * * \e array 2nd array
+ * * \e boolean expected result for the test
+ */
+ public function permsCompareProvider() {
+ return [
+ 'equal' => [
+ ['perm1' => 1, 'perm2' => 0],
+ ['perm1' => 1, 'perm2' => 0],
+ true
+ ],
+ 'different values' => [
+ ['perm1' => 1, 'perm2' => 0],
+ ['perm1' => 0, 'perm2' => 1],
+ false
+ ],
+ 'different order' => [
+ ['perm1' => 1, 'perm2' => 0],
+ ['perm2' => 0, 'perm1' => 1],
+ true
+ ],
+ 'partial first in second' => [
+ ['perm1' => 1],
+ ['perm1' => 1, 'perm2' => 0],
+ true
+ ],
+ 'partial second in first' => [
+ ['perm1' => 1, 'perm2' => 0],
+ ['perm1' => 1],
+ false
+ ]
+ ];
+ }
+} \ No newline at end of file