mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 01:01:41 +09:00
Store all grant-related information in Permission class
This commit is contained in:
parent
d97eb36bbd
commit
c89af17410
2 changed files with 191 additions and 155 deletions
|
|
@ -7,31 +7,146 @@ class Permission
|
|||
{
|
||||
/**
|
||||
* Default properties.
|
||||
*
|
||||
* Note that $is_admin is an alias to $root,
|
||||
* and $is_site_admin is an alias to $manager.
|
||||
*/
|
||||
public $access;
|
||||
public $root;
|
||||
public $manager;
|
||||
public $scopes;
|
||||
|
||||
/**
|
||||
* Alias to $root, kept for backward compatibility only.
|
||||
*
|
||||
* @deprecated
|
||||
* Requirements for this module.
|
||||
*/
|
||||
public $is_admin;
|
||||
protected $_spec = [];
|
||||
|
||||
/**
|
||||
* Alias to $manager, kept for backward compatibility only.
|
||||
*
|
||||
* @deprecated
|
||||
* Scopes for module managers.
|
||||
*/
|
||||
public $is_site_admin;
|
||||
protected $_scopes = [];
|
||||
|
||||
/**
|
||||
* Primary method to determine whether a user is allowed to do something.
|
||||
* Constructor will be called from ModuleModel::getGrant().
|
||||
*
|
||||
* @param array $xml_grant_list
|
||||
* @param array $module_grants
|
||||
* @param ?object $module_info
|
||||
* @param ?object $member_info
|
||||
*/
|
||||
public function __construct(array $xml_grant_list, array $module_grants, ?object $module_info = null, ?object $member_info = null)
|
||||
{
|
||||
// Collect additional information from module and member info.
|
||||
$is_module_admin = !empty($module_info->module_srl) ? \ModuleModel::isModuleAdmin($member_info, $module_info->module_srl) : false;
|
||||
$member_groups = !empty($member_info->group_list) ? array_keys($member_info->group_list) : [];
|
||||
|
||||
// Generate the list of default permissions.
|
||||
$defaults = [
|
||||
'access' => '',
|
||||
'root' => 'root',
|
||||
'manager' => 'manager',
|
||||
'is_admin' => 'root',
|
||||
'is_site_admin' => 'root',
|
||||
];
|
||||
foreach ($xml_grant_list as $key => $val)
|
||||
{
|
||||
$defaults[$key] = $val->default ?? '';
|
||||
}
|
||||
|
||||
// Generate the combined spec for this module.
|
||||
$this->_spec = $defaults;
|
||||
foreach ($module_grants as $row)
|
||||
{
|
||||
$key = $row->name;
|
||||
if ($row->group_srl == 0)
|
||||
{
|
||||
$this->_spec[$key] = 'guest';
|
||||
continue;
|
||||
}
|
||||
if ($row->group_srl == -1 || $row->group_srl == -2)
|
||||
{
|
||||
$this->_spec[$key] = 'member';
|
||||
continue;
|
||||
}
|
||||
if ($row->group_srl == -3)
|
||||
{
|
||||
$this->_spec[$key] = 'manager';
|
||||
continue;
|
||||
}
|
||||
if ($row->group_srl > 0)
|
||||
{
|
||||
if (!isset($this->_spec[$key]) || !is_array($this->_spec[$key]))
|
||||
{
|
||||
$this->_spec[$key] = [];
|
||||
}
|
||||
$this->_spec[$key][] = $row->group_srl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If the spec says nothing about access permissions, it is 'guest' by default.
|
||||
if (!$this->_spec['access'])
|
||||
{
|
||||
$this->_spec['access'] = 'guest';
|
||||
}
|
||||
|
||||
// If the member is an administrator, grant all possible permissions.
|
||||
if ($member_info && $member_info->is_admin === 'Y')
|
||||
{
|
||||
$this->_scopes = true;
|
||||
foreach ($defaults as $key => $default)
|
||||
{
|
||||
$this->{$key} = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
elseif ($is_module_admin)
|
||||
{
|
||||
$this->_scopes = $is_module_admin;
|
||||
foreach ($defaults as $key => $default)
|
||||
{
|
||||
$this->{$key} = ($default !== 'root');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if each permission is granted to the current user.
|
||||
foreach ($this->_spec as $key => $requirement)
|
||||
{
|
||||
if ($requirement === 'guest')
|
||||
{
|
||||
$this->{$key} = true;
|
||||
}
|
||||
elseif ($requirement === 'member')
|
||||
{
|
||||
$this->{$key} = ($member_info && $member_info->member_srl);
|
||||
}
|
||||
elseif ($requirement === 'manager')
|
||||
{
|
||||
$this->{$key} = $this->manager ? true : false;
|
||||
}
|
||||
elseif ($requirement === 'root')
|
||||
{
|
||||
$this->{$key} = $this->root ? true : false;
|
||||
}
|
||||
elseif (is_array($requirement))
|
||||
{
|
||||
if (array_intersect($member_groups, $requirement))
|
||||
{
|
||||
$this->{$key} = true;
|
||||
if ($key === 'manager' && $is_module_admin && !$this->_scopes)
|
||||
{
|
||||
$this->_scopes = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->{$key} = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out whether the current user is allowed to do something.
|
||||
*
|
||||
* This is more portable than accessing object attributes directly,
|
||||
* and also supports manager scopes.
|
||||
*
|
||||
* @param string $scope
|
||||
* @return bool
|
||||
|
|
@ -43,17 +158,17 @@ class Permission
|
|||
return boolval($this->{$scope});
|
||||
}
|
||||
|
||||
if ($this->manager && $this->scopes && preg_match('/^(\w+):(.+)$/', $scope, $matches))
|
||||
if ($this->manager && $this->_scopes && preg_match('/^(\w+):(.+)$/', $scope, $matches))
|
||||
{
|
||||
if ($this->scopes === true)
|
||||
if ($this->_scopes === true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (is_array($this->scopes) && in_array($scope, $this->scopes))
|
||||
if (is_array($this->_scopes) && in_array($scope, $this->_scopes))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (is_array($this->scopes) && in_array($matches[1] . ':*', $this->scopes))
|
||||
if (is_array($this->_scopes) && in_array($matches[1] . ':*', $this->_scopes))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -61,4 +176,57 @@ class Permission
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out who is allowed to do something.
|
||||
*
|
||||
* This method returns 'root', 'manager', 'member', 'guest',
|
||||
* or an array of group_srls whose members are allowed.
|
||||
*
|
||||
* If you pass the name of a scope, the result might vary
|
||||
* depending on whether you are a module manager.
|
||||
*
|
||||
* @param string key
|
||||
* @return string|array
|
||||
*/
|
||||
public function whocan(string $key)
|
||||
{
|
||||
if (isset($this->_spec[$key]))
|
||||
{
|
||||
return $this->_spec[$key];
|
||||
}
|
||||
elseif (preg_match('/^(\w+):(\w+)$/', $key))
|
||||
{
|
||||
if ($this->manager)
|
||||
{
|
||||
return $this->can($key) ? 'manager' : 'root';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'manager';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'nobody';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to provide deprecated aliases.
|
||||
*
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get(string $key)
|
||||
{
|
||||
if ($key === 'is_admin' || $key === 'is_site_admin')
|
||||
{
|
||||
return $this->root;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2186,7 +2186,7 @@ class ModuleModel extends Module
|
|||
*/
|
||||
public static function getGrant($module_info, $member_info, $xml_info = null)
|
||||
{
|
||||
if(empty($module_info->module))
|
||||
if (empty($module_info->module))
|
||||
{
|
||||
$module_info = new stdClass;
|
||||
$module_info->module = $module_info->module_srl = 0;
|
||||
|
|
@ -2201,148 +2201,16 @@ class ModuleModel extends Module
|
|||
}
|
||||
}
|
||||
|
||||
// Get information of module.xml
|
||||
if(!$xml_info)
|
||||
// Get module grant information
|
||||
if (!$xml_info)
|
||||
{
|
||||
$xml_info = self::getModuleActionXml($module_info->module);
|
||||
}
|
||||
$xml_grant_list = isset($xml_info->grant) ? (array)$xml_info->grant : array();
|
||||
$module_grants = self::getModuleGrants($module_info->module_srl)->data ?: [];
|
||||
|
||||
// Get group information of member
|
||||
$member_group = !empty($member_info->group_list) ? array_keys($member_info->group_list) : array();
|
||||
$is_module_admin = !empty($module_info->module_srl) ? self::isModuleAdmin($member_info, $module_info->module_srl) : false;
|
||||
|
||||
// Get 'privilege name' list from module.xml
|
||||
$privilege_list = array_keys($xml_grant_list);
|
||||
|
||||
// Prepend default 'privilege name'
|
||||
// manager, is_site_admin not distinguish because of compatibility.
|
||||
array_unshift($privilege_list, 'access', 'is_admin', 'manager', 'is_site_admin', 'root');
|
||||
|
||||
// Unique
|
||||
$privilege_list = array_unique($privilege_list, SORT_STRING);
|
||||
|
||||
// Grant first
|
||||
$grant = new Rhymix\Modules\Module\Models\Permission;
|
||||
foreach($privilege_list as $val)
|
||||
{
|
||||
// If an administrator, grant all
|
||||
if($member_info && $member_info->is_admin == 'Y')
|
||||
{
|
||||
$grant->{$val} = true;
|
||||
}
|
||||
// If a module manager, grant all (except 'root', 'is_admin')
|
||||
elseif ($is_module_admin && $val !== 'root' && $val !== 'is_admin')
|
||||
{
|
||||
$grant->{$val} = true;
|
||||
}
|
||||
// If module_srl doesn't exist, grant access
|
||||
else if(empty($module_info->module_srl) && $val === 'access')
|
||||
{
|
||||
$grant->{$val} = true;
|
||||
}
|
||||
// Default : not grant
|
||||
else
|
||||
{
|
||||
$grant->{$val} = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If module admin, add scopes
|
||||
if ($member_info && $member_info->is_admin == 'Y')
|
||||
{
|
||||
$grant->scopes = true;
|
||||
}
|
||||
elseif ($is_module_admin)
|
||||
{
|
||||
$grant->scopes = $is_module_admin;
|
||||
}
|
||||
else
|
||||
{
|
||||
$grant->scopes = [];
|
||||
}
|
||||
|
||||
// If access were not granted, check more
|
||||
if(!$grant->access)
|
||||
{
|
||||
$checked = array();
|
||||
|
||||
// Grant privileges by information that get from the DB
|
||||
foreach(self::getModuleGrants($module_info->module_srl)->data as $val)
|
||||
{
|
||||
$checked[$val->name] = true;
|
||||
if($grant->{$val->name})
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// All user
|
||||
if($val->group_srl == 0)
|
||||
{
|
||||
$grant->{$val->name} = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Log-in member only
|
||||
if($member_info && $member_info->member_srl)
|
||||
{
|
||||
if($val->group_srl == -1 || $val->group_srl == -2)
|
||||
{
|
||||
$grant->{$val->name} = true;
|
||||
}
|
||||
// Manager only
|
||||
else if($val->group_srl == -3)
|
||||
{
|
||||
if($grant->manager)
|
||||
{
|
||||
$grant->{$val->name} = true;
|
||||
}
|
||||
}
|
||||
// If a target is a group
|
||||
else if(count($member_group) && in_array($val->group_srl, $member_group))
|
||||
{
|
||||
$grant->{$val->name} = true;
|
||||
if ($val->name === 'manager' && !$grant->scopes)
|
||||
{
|
||||
$grant->scopes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Grant access by default
|
||||
if(!isset($checked['access']))
|
||||
{
|
||||
$grant->access = true;
|
||||
}
|
||||
|
||||
// Grant privileges by default information of module
|
||||
foreach($xml_grant_list as $name => $item)
|
||||
{
|
||||
if(isset($checked[$name]) || $grant->{$name})
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// All user
|
||||
if($item->default == 'guest')
|
||||
{
|
||||
$grant->{$name} = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Log-in member only
|
||||
if($member_info && $member_info->member_srl)
|
||||
{
|
||||
if($item->default == 'member' || $item->default == 'site')
|
||||
{
|
||||
$grant->{$name} = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate grant
|
||||
$grant = new Rhymix\Modules\Module\Models\Permission($xml_grant_list, $module_grants, $module_info, $member_info);
|
||||
return $__cache = $grant;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue