Commit eb55511e authored by Victor Emanouilov's avatar Victor Emanouilov

[ENH] revamp module permissions - get actually loaded permissions resolver and...

[ENH] revamp module permissions - get actually loaded permissions resolver and show the level of permissions actually applied - object, parent, category or global
parent 0f28a7f8
Pipeline #50914406 failed with stages
in 31 minutes and 21 seconds
...@@ -22,10 +22,6 @@ class Permissions ...@@ -22,10 +22,6 @@ class Permissions
public function getPagePermissions() public function getPagePermissions()
{ {
$url = $_SERVER['SCRIPT_NAME']; $url = $_SERVER['SCRIPT_NAME'];
$tikilib = TikiLib::lib('tiki');
$userlib = TikiLib::lib('user');
$allGroups = $userlib->list_all_groups();
$permissions = [];
if (null == $objectType = $this->findObjectType($url)) { if (null == $objectType = $this->findObjectType($url)) {
return null; return null;
...@@ -33,91 +29,58 @@ class Permissions ...@@ -33,91 +29,58 @@ class Permissions
switch ($objectType) { switch ($objectType) {
case 'wiki page': case 'wiki page':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups);
$objectId = ! empty($_REQUEST['page']) ? $_REQUEST['page'] : null; $objectId = ! empty($_REQUEST['page']) ? $_REQUEST['page'] : null;
if (isset($objectId)) {
$listPermissions = $this->listPermissions($objectId, $objectType, $objectId);
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
case 'file gallery': case 'file gallery':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups);
$filegallib = TikiLib::lib('filegal'); $filegallib = TikiLib::lib('filegal');
$object = ! empty($_REQUEST['galleryId']) ? $filegallib->get_file_gallery_info($_REQUEST['galleryId']) : null; $objectId = ! empty($_REQUEST['galleryId']) ? $_REQUEST['galleryId'] : null;
if (isset($object)) {
$listPermissions = $this->listPermissions($object['galleryId'], $objectType, $object['name']);
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
case 'tracker': case 'tracker':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups); $objectId = ! empty($_REQUEST['trackerId']) ? $_REQUEST['trackerId'] : null;
$trackerId = ! empty($_REQUEST['trackerId']) ? $_REQUEST['trackerId'] : null; $itemId = ! empty($_REQUEST['itemId']) ? $_REQUEST['itemId'] : null;
$item = ! empty($_REQUEST['itemId']) ? TikiLib::lib('trk')->get_tracker_item($_REQUEST['itemId']) : null; if ($itemId) {
if (isset($trackerId) || isset($item)) { $objectId = $itemId;
$objectId = isset($trackerId) ? $trackerId : $item['trackerId']; $objectType = 'trackeritem';
$object = TikiLib::lib('trk')->get_tracker($objectId);
$listPermissions = $this->listPermissions($objectId, $objectType, $object['name']);
$this->getOtherPermissions($permissions, $listPermissions);
} }
break; break;
case 'forum': case 'forum':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups); $objectId = ! empty($_REQUEST['forumId']) ? $_REQUEST['forumId'] : null;
$commentslib = TikiLib::lib('comments');
$object = ! empty($_REQUEST['forumId']) ? $commentslib->get_forum($_REQUEST['forumId']) : null;
if (! empty($object)) {
$listPermissions = $this->listPermissions($object['forumId'], $objectType, $object['name']);
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
case 'group': case 'group':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups); $objectId = ! empty($_REQUEST['group']) ? $_REQUEST['group'] : null;
$object = ! empty($_REQUEST['group']) ? $_REQUEST['group'] : null;
if (! empty($object)) {
$listPermissions = $this->listPermissions($object, $objectType, '');
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
case 'articles': case 'articles':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups); $objectId = ! empty($_REQUEST['articleId']) ? $_REQUEST['articleId'] : null;
$artlib = TikiLib::lib('art');
$object = ! empty($_REQUEST['articleId']) ? $artlib->get_article($_REQUEST['articleId']) : null;
if (! empty($object)) {
$listPermissions = $this->listPermissions($object['articleId'], $objectType, $object['title']);
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
case 'blog': case 'blog':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups); $objectId = ! empty($_REQUEST['blogId']) ? $_REQUEST['blogId'] : null;
$bloglib = TikiLib::lib('blog');
$object = ! empty($_REQUEST['blogId']) ? $bloglib->get_blog($_REQUEST['blogId']) : null;
if (! empty($object)) {
$listPermissions = $this->listPermissions($object['blogId'], $objectType, $object['title']);
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
case 'calendar': case 'calendar':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups); $objectId = ! empty($_REQUEST['calendarId']) ? $_REQUEST['calendarId'] : null;
$calendarlib = TikiLib::lib('calendar');
$object = ! empty($_REQUEST['calendarId']) ? $calendarlib->get_calendar($_REQUEST['calendarId']) : null;
if (! empty($object)) {
$listPermissions = $this->listPermissions($object['calendarId'], $objectType, $object['name']);
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
case 'sheet': case 'sheet':
$permissions = $this->getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups); $objectId = ! empty($_REQUEST['sheetId']) ? $_REQUEST['sheetId'] : null;
$sheetlib = TikiLib::lib('sheet');
$object = ! empty($_REQUEST['sheetId']) ? $sheetlib->get_sheet_info($_REQUEST['sheetId']) : null;
if (! empty($object)) {
$listPermissions = $this->listPermissions($object['sheetId'], $objectType, $object['title']);
$this->getOtherPermissions($permissions, $listPermissions);
}
break; break;
} }
ksort($permissions); $all = TikiLib::lib('user')->get_enabled_permissions();
return $permissions; $accessor = \Perms::get(['type' => $objectType, 'object' => $objectId]);
$loaded = $accessor->getResolver()->dump();
$results = [];
foreach ($all as $permName => $permDef) {
foreach ($loaded['perms'] as $perm => $groups) {
if ($perm != str_replace('tiki_p_', '', $permName)) {
continue;
}
$results[$permDef['type']][$perm] = $groups;
}
}
$loaded['perms'] = $results;
return $loaded;
} }
protected function findObjectType($url) protected function findObjectType($url)
...@@ -188,145 +151,4 @@ class Permissions ...@@ -188,145 +151,4 @@ class Permissions
return null; return null;
} }
/**
* Get global permission for a given object
*
* @param $objectType
* @param $tikilib
* @param $userlib
* @param $allGroups
* @return array
*/
protected function getGlobalPermissions($objectType, $tikilib, $userlib, $allGroups)
{
$globalPermissions = [];
$permissionGroup = $tikilib->get_permGroup_from_objectType($objectType);
$allPermissionGroup = $userlib->get_permissions(0, -1, 'permName_asc', '', $permissionGroup);
foreach ($allGroups as $group) {
$permissions = $userlib->get_group_permissions($group);
foreach ($allPermissionGroup['data'] as $permission) {
if (in_array($permission['permName'], $permissions)) {
if (! empty($globalPermissions[$permission['permName']]['global']) && ! in_array($group, $globalPermissions[$permission['permName']]['global'])) {
$globalPermissions[$permission['permName']]['global'][] = $group;
}
}
}
}
return $globalPermissions;
}
/**
* Get object and category permissions
*
* @param array $permissions
* @param array $listPermissions
*/
protected function getOtherPermissions(&$permissions, $listPermissions)
{
if (count($listPermissions['special']) > 0) {
foreach ($listPermissions['special'] as $objectInfo) {
$permissions[$objectInfo['perm']]['object'][] = $objectInfo;
}
}
if (count($listPermissions['category']) > 0) {
foreach ($listPermissions['category'] as $objectInfo) {
$permissions[$objectInfo['perm']]['category'][] = $objectInfo;
}
}
}
/**
* List permissions for a given object
*
* @param $objectId
* @param $objectType
* @param $objectName
* @param string $filterGroup
* @return array
*/
protected function listPermissions($objectId, $objectType, $objectName, $filterGroup = '')
{
global $prefs;
$userlib = TikiLib::lib('user');
$ret = [];
$cats = [];
$perms = $userlib->get_object_permissions($objectId, $objectType);
$allPermissions = $userlib->get_permissions();
if (! empty($perms)) {
foreach ($perms as $perm) {
if (empty($filterGroup) || in_array($perm['groupName'], $filterGroup)) {
$json = json_encode([
'group' => $perm['groupName'],
'perm' => $perm['permName'],
'objectId' => $objectId,
'objectType' => $objectType
]);
$ret[] = [
'group' => $perm['groupName'],
'perm' => $perm['permName'],
'reason' => 'Object',
'objectId' => $objectId,
'objectType' => $objectType,
'objectName' => $objectName,
'json' => $json
];
}
}
}
if ($prefs['feature_categories'] == 'y') {
$categlib = TikiLib::lib('categ');
$categs = $categlib->get_object_categories($objectType, $objectId);
if (! empty($categs)) {
foreach ($categs as $categId) {
$categoryObjectPermissions = $userlib->get_object_permissions($categId, 'category');
if (! empty($categoryObjectPermissions)) {
foreach ($categoryObjectPermissions as $categoryPermission) {
if ($this->isPermission($allPermissions, $categoryPermission['permName'], $objectType)) {
$cats[] = [
'group' => $categoryPermission['groupName'],
'perm' => $categoryPermission['permName'],
'reason' => 'Category',
'objectId' => $categId,
'objectType' => 'category',
'objectName' => $categlib->get_category_name($categId)
];
}
}
}
}
}
}
return [
'objectId' => $objectId,
'special' => $ret,
'category' => $cats
];
}
/**
* Check user has permission
*
* @param $permName
* @param $objectType
* @return bool
*/
protected function isPermission($allPermissions, $permName, $objectType)
{
global $tikilib;
if (! empty($allPermissions)) {
$permGroup = $tikilib->get_permGroup_from_objectType($objectType);
foreach ($allPermissions['data'] as $perm) {
if ($perm['permName'] == $permName) {
return $permGroup == $perm['type'];
}
}
}
return false;
}
} }
...@@ -32,4 +32,10 @@ interface Perms_Resolver ...@@ -32,4 +32,10 @@ interface Perms_Resolver
* @return array $ applicableGroups * @return array $ applicableGroups
*/ */
function applicableGroups(); function applicableGroups();
/*
* Dump useful resolve information for debugging purposes.
* @return array of resolved permissions
*/
function dump();
} }
...@@ -33,4 +33,16 @@ class Perms_Resolver_Default implements Perms_Resolver ...@@ -33,4 +33,16 @@ class Perms_Resolver_Default implements Perms_Resolver
{ {
return ['Anonymous', 'Registered']; return ['Anonymous', 'Registered'];
} }
function dump()
{
$result = [
'from' => $this->from(),
'perms' => [],
];
foreach ($this->applicableGroups as $group) {
$result['perms'][$this->value ? 'all' : 'none'][] = $group;
}
return $result;
}
} }
...@@ -48,8 +48,6 @@ class Perms_Resolver_Static implements Perms_Resolver ...@@ -48,8 +48,6 @@ class Perms_Resolver_Static implements Perms_Resolver
return false; return false;
} }
/* /*
* Get name of the object type the permissons to check belong to : i.e 'object', 'category' * Get name of the object type the permissons to check belong to : i.e 'object', 'category'
* @return $string name of object type * @return $string name of object type
...@@ -59,7 +57,6 @@ class Perms_Resolver_Static implements Perms_Resolver ...@@ -59,7 +57,6 @@ class Perms_Resolver_Static implements Perms_Resolver
return $this->from; return $this->from;
} }
/* /*
* Get array of applicable groups. * Get array of applicable groups.
* @return array $ applicableGroups * @return array $ applicableGroups
...@@ -68,4 +65,18 @@ class Perms_Resolver_Static implements Perms_Resolver ...@@ -68,4 +65,18 @@ class Perms_Resolver_Static implements Perms_Resolver
{ {
return array_keys($this->known); return array_keys($this->known);
} }
function dump()
{
$result = [
'from' => $this->from() ? $this->from() : 'global',
'perms' => [],
];
foreach ($this->known as $group => $perms) {
foreach ($perms as $perm => $_) {
$result['perms'][$perm][] = $group;
}
}
return $result;
}
} }
...@@ -2,54 +2,14 @@ ...@@ -2,54 +2,14 @@
{if isset($pagePermissions)} {if isset($pagePermissions)}
{tikimodule error=$module_params.error title=$tpl_module_title name="permissions" flip=$module_params.flip decorations=$module_params.decorations nobox=$module_params.nobox notitle=$module_params.notitle style=$module_params.style} {tikimodule error=$module_params.error title=$tpl_module_title name="permissions" flip=$module_params.flip decorations=$module_params.decorations nobox=$module_params.nobox notitle=$module_params.notitle style=$module_params.style}
{if $pagePermissions} {if $pagePermissions}
{foreach from=$pagePermissions key=permission item=info} <p>{tr}Permissions applied from:{/tr} <b>{$pagePermissions.from}</b> level</p>
{assign var="permissionName" value=$permission|replace:'tiki_p_':''} {foreach from=$pagePermissions.perms key=group item=perms}
{$permissionName} <b>{$group}</b><br/>
<span target="tikihelp" class="tikihelp" title="{$permissionName}<br/> {foreach from=$perms key=perm item=groups}
{if !empty($info["global"])} {$perm}
<br/> <span target="tikihelp" class="tikihelp" title="{', '|implode:$groups}">{icon name="help"}</span>
<b>{tr}Global permissions{/tr}</b> <br/>
<div> {/foreach}
{', '|implode:$info['global']}
</div>
<br/>
{/if}
{if !empty($info["object"])}
<b>{tr}Object permissions{/tr}</b>
<table class='table table-striped'>
<tr>
<td><b>{tr}Object{/tr}</b></td>
<td><b>{tr}Group{/tr}</b></td>
<td><b>{tr}Reason{/tr}</b></td>
</tr>
{foreach from=$info["object"] item=objectInfo}
<tr>
<td>{$objectInfo["objectName"]}</td>
<td>{$objectInfo["group"]}</td>
<td>{$objectInfo["reason"]}</td>
</tr>
{/foreach}
</table>
{/if}
{if !empty($info["category"])}
<b>{tr}Category permissions{/tr}</b>
<table class='table table-striped'>
<tr>
<td><b>{tr}Object{/tr}</b></td>
<td><b>{tr}Group{/tr}</b></td>
<td><b>{tr}Reason{/tr}</b></td>
</tr>
{foreach from=$info["object"] item=objectInfo}
<tr>
<td>{$objectInfo["objectName"]}</td>
<td>{$objectInfo["group"]}</td>
<td>{$objectInfo["reason"]}</td>
</tr>
{/foreach}
</table>
{/if}
">{icon name="help"}</span>
<br/> <br/>
{/foreach} {/foreach}
{else} {else}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment