Merge pull request #765 from conory/pr/grant

모듈 권한 정리 및 퍼미션 체크 지원
This commit is contained in:
CONORY 2017-04-06 21:58:53 +09:00 committed by GitHub
commit 87131a1b93
60 changed files with 1850 additions and 1671 deletions

View file

@ -1,36 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="0.2">
<title xml:lang="ko">모듈</title>
<title xml:lang="zh-CN">模块列表</title>
<title xml:lang="jp">モジュール</title>
<title xml:lang="en">Module</title>
<title xml:lang="vi">Module</title>
<title xml:lang="es">Módulo</title>
<title xml:lang="ru">Модули</title>
<title xml:lang="zh-TW">模組</title>
<title xml:lang="tr">Modül</title>
<description xml:lang="ko">모듈을 생성하고 관리합니다.</description>
<description xml:lang="zh-CN">生成及管理模块的模块。</description>
<description xml:lang="jp">モジュールの生成、管理するモジュールです。</description>
<description xml:lang="en">Creating/managering the other modules.</description>
<description xml:lang="vi">Module cho phép tạo và quản lý những Module khác.</description>
<description xml:lang="es">Este módulo is para crear y manejar los otros módulos.</description>
<description xml:lang="ru">Этот модуль служит для создания/управления другими модулями.</description>
<description xml:lang="zh-TW">用於建立與管理其他模組。</description>
<description xml:lang="tr">Bu modül, başka modüller oluşturmak ve yönetmek içindir.</description>
<version>1.7</version>
<date>2013-11-27</date>
<category>system</category>
<title xml:lang="ko">모듈</title>
<title xml:lang="zh-CN">模块列表</title>
<title xml:lang="jp">モジュール</title>
<title xml:lang="en">Module</title>
<title xml:lang="vi">Module</title>
<title xml:lang="es">Módulo</title>
<title xml:lang="ru">Модули</title>
<title xml:lang="zh-TW">模組</title>
<title xml:lang="tr">Modül</title>
<description xml:lang="ko">모듈을 생성하고 관리합니다.</description>
<description xml:lang="zh-CN">生成及管理模块的模块。</description>
<description xml:lang="jp">モジュールの生成、管理するモジュールです。</description>
<description xml:lang="en">Creating/managering the other modules.</description>
<description xml:lang="vi">Module cho phép tạo và quản lý những Module khác.</description>
<description xml:lang="es">Este módulo is para crear y manejar los otros módulos.</description>
<description xml:lang="ru">Этот модуль служит для создания/управления другими модулями.</description>
<description xml:lang="zh-TW">用於建立與管理其他模組。</description>
<description xml:lang="tr">Bu modül, başka modüller oluşturmak ve yönetmek içindir.</description>
<version>1.7</version>
<date>2013-11-27</date>
<category>system</category>
<author email_address="developers@xpressengine.com" link="http://xpressengine.com/">
<name xml:lang="ko">NAVER</name>
<name xml:lang="vi">NAVER</name>
<name xml:lang="zh-CN">NAVER</name>
<name xml:lang="jp">NAVER</name>
<name xml:lang="en">NAVER</name>
<name xml:lang="es">NAVER</name>
<name xml:lang="ru">NAVER</name>
<name xml:lang="zh-TW">NAVER</name>
<name xml:lang="tr">NAVER</name>
</author>
<author email_address="developers@xpressengine.com" link="http://xpressengine.com/">
<name xml:lang="ko">NAVER</name>
<name xml:lang="vi">NAVER</name>
<name xml:lang="zh-CN">NAVER</name>
<name xml:lang="jp">NAVER</name>
<name xml:lang="en">NAVER</name>
<name xml:lang="es">NAVER</name>
<name xml:lang="ru">NAVER</name>
<name xml:lang="zh-TW">NAVER</name>
<name xml:lang="tr">NAVER</name>
</author>
</module>

View file

@ -2,71 +2,73 @@
<module>
<grants />
<permissions>
<permission action="dispModuleSelectList" target="member" />
<permission action="dispModuleSelectList" target="root" />
<permission action="dispModuleSkinInfo" target="all-managers" />
<permission action="dispModuleFileBox" target="root" />
<permission action="dispModuleFileBoxAdd" target="root" />
<permission action="getModuleSkinInfoList" target="root" />
<permission action="getFileBoxListHtml" target="root" />
<permission action="getModuleInfoByMenuItemSrl" target="root" />
<permission action="getLangListByLangcodeForAutoComplete" target="manager" />
<permission action="getLangByLangcode" target="manager" />
<permission action="getModuleAdminMultilingualHtml" target="manager" />
<permission action="getModuleAdminGrant" target="manager" />
<permission action="procModuleAdminInsertGrant" target="manager" />
<permission action="procModuleFileBoxAdd" target="root" />
<permission action="procModuleFileBoxDelete" target="root" />
<permission action="getModuleAdminLangCode" target="manager" />
<permission action="getModuleAdminLangListHtml" target="manager" />
<permission action="getModuleAdminLangListByName" target="manager" />
<permission action="getModuleAdminLangListByValue" target="manager" />
<permission action="getModuleAdminMultilingualHtml" target="manager" />
<permission action="getModuleAdminLangListHtml" target="manager" />
<permission action="procModuleAdminInsertGrant" target="manager" check_var="module_srl" />
<permission action="procModuleAdminUpdateSkinInfo" target="manager" check_var="module_srl" />
<permission action="procModuleAdminInsertLang" target="manager" />
<permission action="procModuleAdminUpdateSkinInfo" target="manager" />
</permissions>
<actions>
<action name="dispModuleSelectList" type="view" />
<action name="dispModuleSkinInfo" type="view" />
<action name="dispModuleFileBox" type="view" />
<action name="dispModuleFileBoxAdd" type="view" />
<action name="procModuleFileBoxAdd" type="controller" />
<action name="dispModuleChangeLang" type="mobile" />
<action name="getModuleSkinInfoList" type="model" />
<action name="getFileBoxListHtml" type="model" />
<action name="getModuleInfoByMenuItemSrl" type="model" />
<action name="getLangListByLangcodeForAutoComplete" type="model" />
<action name="getLangByLangcode" type="model" />
<action name="procModuleFileBoxAdd" type="controller" />
<action name="procModuleFileBoxDelete" type="controller" />
<action name="getModuleSkinInfoList" type="model" />
<action name="getModuleAdminModuleList" type="model" />
<action name="getModuleAdminLangCode" type="model" />
<action name="getModuleAdminLangListByName" type="model" />
<action name="getModuleAdminLangListByValue" type="model" />
<action name="getLangListByLangcodeForAutoComplete" type="model" />
<action name="getFileBoxListHtml" type="model" />
<action name="getLangByLangcode" type="model" />
<action name="getModuleInfoByMenuItemSrl" type="model" />
<action name="dispModuleChangeLang" type="mobile" />
<!-- admin -->
<action name="dispModuleAdminContent" type="view" menu_name="installedModule" menu_index="true" admin_index="true" />
<action name="dispModuleAdminList" type="view" />
<action name="dispModuleAdminContent" type="view" menu_name="installedModule" menu_index="true" admin_index="true" />
<action name="dispModuleAdminCategory" type="view" menu_name="installedModule" />
<action name="dispModuleAdminInfo" type="view" />
<action name="dispModuleAdminModuleSetup" type="view" />
<action name="dispModuleAdminModuleAdditionSetup" type="view" />
<action name="dispModuleAdminModuleGrantSetup" type="view" />
<action name="dispModuleAdminCopyModule" type="view" />
<action name="dispModuleAdminLangcode" type="view" menu_name="multilingual" menu_index="true" />
<action name="dispModuleAdminFileBox" type="view" menu_name="filebox" menu_index="true" />
<action name="dispModuleAdminLangcode" type="view" menu_name="multilingual" menu_index="true" />
<action name="getModuleAdminModuleList" type="model" />
<action name="getModuleAdminModuleInfo" type="model" />
<action name="getModuleAdminGrant" type="model" />
<action name="getModuleAdminLangCode" type="model" />
<action name="getModuleAdminLangListByName" type="model" />
<action name="getModuleAdminLangListByValue" type="model" />
<action name="getModuleAdminModuleSearcherHtml" type="model" />
<action name="getModuleAdminMultilingualHtml" type="model" />
<action name="getModuleAdminLangListHtml" type="model" />
<action name="getModuleAdminModuleSearcherHtml" type="model" />
<action name="getModuleAdminModuleInfo" type="model" />
<action name="procModuleAdminInsertCategory" type="controller" ruleset="insertCategory" />
<action name="procModuleAdminUpdateCategory" type="controller" ruleset="updateCategory" />
<action name="procModuleAdminDeleteCategory" type="controller" ruleset="deleteCategory" />
<action name="procModuleAdminModuleSetup" type="controller" ruleset="insertModuleSetup" />
<action name="procModuleAdminModuleGrantSetup" type="controller" ruleset="insertModulesGrant" />
<action name="procModuleAdminCopyModule" type="controller" ruleset="copyModule" />
<action name="procModuleAdminInsertGrant" type="controller" />
<action name="procModuleAdminUpdateSkinInfo" type="controller" />
<action name="procModuleAdminModuleSetup" type="controller" ruleset="insertModuleSetup" />
<action name="procModuleAdminModuleGrantSetup" type="controller" ruleset="insertModulesGrant" />
<action name="procModuleAdminInsertLang" type="controller" />
<action name="procModuleAdminDeleteLang" type="controller" />
<action name="procModuleAdminGetList" type="controller" />

View file

@ -858,8 +858,12 @@ class moduleModel extends module
$target = $permission->attrs->target;
$info->permission->{$action} = $target;
$info->permission_check->{$action}->key = $permission->attrs->check_var ?: '';
$info->permission_check->{$action}->type = $permission->attrs->check_type ?: '';
$buff[] = sprintf('$info->permission->%s = \'%s\';', $action, $target);
$buff[] = sprintf('$info->permission_check->%s->key = \'%s\';', $action, $info->permission_check->{$action}->key);
$buff[] = sprintf('$info->permission_check->%s->type = \'%s\';', $action, $info->permission_check->{$action}->type);
}
}
// for admin menus
@ -1910,165 +1914,257 @@ class moduleModel extends module
$module_info->{$val->name} = $val->value;
}
}
/**
* @brief Return permission by using module info, xml info and member info
* @brief Return privileges(granted) information by using module info, xml info and member info
*/
function getGrant($module_info, $member_info, $xml_info = '')
{
if (!$xml_info && isset($GLOBALS['__MODULE_GRANT__'][intval($module_info->module_srl)][intval($member_info->member_srl)]))
$__cache = &$GLOBALS['__MODULE_GRANT__'][$module_info->module][intval($module_info->module_srl)][intval($member_info->member_srl)];
if (!$xml_info && is_object($__cache))
{
return $GLOBALS['__MODULE_GRANT__'][intval($module_info->module_srl)][intval($member_info->member_srl)];
return $__cache;
}
$grant = new stdClass();
$grant = new stdClass;
// Get information of module.xml
if(!$xml_info)
{
$module = $module_info->module;
$xml_info = $this->getModuleActionXml($module);
$xml_info = $this->getModuleActionXml($module_info->module);
}
// Set variables to grant group permission
$module_srl = $module_info->module_srl;
$grant_info = $xml_info->grant;
if($member_info->member_srl)
// Get group information of member
if(is_array($member_info->group_list))
{
if(is_array($member_info->group_list)) $group_list = array_keys($member_info->group_list);
else $group_list = array();
$member_group = array_keys($member_info->group_list);
}
else
{
$group_list = array();
$member_group = array();
}
// If module_srl doesn't exist(if unable to set permissions)
if(!$module_srl)
$is_module_admin = $module_info->module_srl ? $this->isModuleAdmin($member_info, $module_info->module_srl) : false;
// Get 'privilege name' list from module.xml
$privilege_list = array_keys((array) $xml_info->grant);
// Prepend default 'privilege name'
// is_admin, 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
foreach($privilege_list as $val)
{
$grant->access = true;
$grant->is_admin = $grant->manager = $grant->is_site_admin = ($member_info->is_admin == 'Y') ? true : false;
}
else
{
// If module_srl exists
// Get a type of granted permission
$grant->access = $grant->is_admin = $grant->manager = $grant->is_site_admin = ($member_info->is_admin == 'Y') ? true : false;
// If a just logged-in member is, check if the member is a module administrator
if (!$grant->manager && $member_info->member_srl && $this->isModuleAdmin($member_info, $module_srl))
// If an administrator, grant all
if($member_info->is_admin == 'Y')
{
$grant->manager = true;
$grant->{$val} = true;
}
// If not an administrator, get information from the DB and grant manager privilege.
if(!$grant->manager)
// If a module manager, grant all (except 'root')
else if($is_module_admin === true && $val !== 'root')
{
$args = new stdClass();
// If planet, get permission settings from the planet home
if($module_info->module == 'planet')
$grant->{$val} = true;
}
// If module_srl doesn't exist, grant access
else if(!$module_info->module_srl && $val === 'access')
{
$grant->{$val} = true;
}
// Default : not grant
else
{
$grant->{$val} = false;
}
}
// If access were not granted, check more
if(!$grant->access)
{
$checked = array();
// Grant privileges by information that get from the DB
foreach($this->getModuleGrants($module_info->module_srl)->data as $val)
{
if(isset($checked[$val->name]))
{
$output = executeQueryArray('module.getPlanetGrants', $args);
continue;
}
else
$checked[$val->name] = true;
// All user
if($val->group_srl == 0)
{
$output = $this->getModuleGrants($module_srl);
$grant->{$val->name} = true;
continue;
}
$grant_exists = $granted = array();
if($output->data)
// Log-in member only
if($member_info->member_srl)
{
// Arrange names and groups who has privileges
foreach($output->data as $val)
if($val->group_srl == -1)
{
$grant_exists[$val->name] = true;
if($granted[$val->name]) continue;
// Log-in member only
if($val->group_srl == -1)
$grant->{$val->name} = true;
}
// Site-joined member only
else if($val->group_srl == -2)
{
// Grant if no information of the currently connected site exists
if(!Context::get('site_module_info')->site_srl)
{
$granted[$val->name] = true;
if($member_info->member_srl) $grant->{$val->name} = true;
// Site-joined member only
}
elseif($val->group_srl == -2)
{
$granted[$val->name] = true;
// Do not grant any permission for non-logged member
if(!$member_info->member_srl) $grant->{$val->name} = false;
// Log-in member
else
{
$site_module_info = Context::get('site_module_info');
// Permission granted if no information of the currently connected site exists
if(!$site_module_info->site_srl) $grant->{$val->name} = true;
// Permission is not granted if information of the currently connected site exists
elseif(count($group_list)) $grant->{$val->name} = true;
}
// All of non-logged members
}
elseif($val->group_srl == 0)
{
$granted[$val->name] = true;
$grant->{$val->name} = true;
// If a target is a group
}
else
else if(count($member_group))
{
if($group_list && count($group_list) && in_array($val->group_srl, $group_list))
{
$grant->{$val->name} = true;
$granted[$val->name] = true;
}
$grant->{$val->name} = true;
}
}
}
// Separate processing for the virtual group access
if(!$grant_exists['access']) $grant->access = true;
if(count($grant_info))
{
foreach($grant_info as $grant_name => $grant_item)
// If a target is a group
else if(count($member_group) && in_array($val->group_srl, $member_group))
{
if($grant_exists[$grant_name]) continue;
switch($grant_item->default)
{
case 'guest' :
$grant->{$grant_name} = true;
break;
case 'member' :
if($member_info->member_srl) $grant->{$grant_name} = true;
else $grant->{$grant_name} = false;
break;
case 'site' :
$site_module_info = Context::get('site_module_info');
if($member_info->member_srl && (($site_module_info->site_srl && count($group_list)) || !$site_module_info->site_srl)) $grant->{$grant_name} = true;
else $grant->{$grant_name} = false;
break;
case 'manager' :
case 'root' :
if($member_info->is_admin == 'Y') $grant->{$grant_name} = true;
else $grant->{$grant_name} = false;
break;
}
$grant->{$val->name} = true;
}
}
}
// Set true to grant all privileges if an administrator is
if($grant->manager)
// Grant access by default
if(!isset($checked['access']))
{
$grant->access = true;
if(count($grant_info))
}
// Grant privileges by default information of module
if(is_array($xml_info->grant))
{
foreach($xml_info->grant as $name => $item)
{
foreach($grant_info as $key => $val)
if(isset($checked[$name]))
{
$grant->{$key} = true;
continue;
}
// All user
if($item->default == 'guest')
{
$grant->{$name} = true;
continue;
}
// Log-in member only
if($member_info->member_srl)
{
if($item->default == 'member')
{
$grant->{$name} = true;
}
else if($item->default == 'site')
{
// Grant if no information of the currently connected site exists
if(!Context::get('site_module_info')->site_srl)
{
$grant->{$name} = true;
}
else if(count($member_group))
{
$grant->{$name} = true;
}
}
}
}
}
}
$GLOBALS['__MODULE_GRANT__'][intval($module_info->module_srl)][intval($member_info->member_srl)] = $grant;
return $grant;
return $__cache = $grant;
}
/**
* Get privileges(granted) information of the member for target module by target_srl
* @param string $target_srl as module_srl. It may be a reference serial number
* @param string $type module name. get module_srl from module
* @param object $member_info member information
* @return mixed success : object, fail : false
* */
function getPrivilegesBySrl($target_srl, $type = null, $member_info = null)
{
if(empty($target_srl = trim($target_srl)) || !preg_match('/^([0-9]+)$/', $target_srl) && $type != 'module')
{
return false;
}
if($type)
{
if($type == 'document')
{
$target_srl = getModel('document')->getDocument($target_srl, false, false)->get('module_srl');
}
else if($type == 'comment')
{
$target_srl = getModel('comment')->getComment($target_srl)->get('module_srl');
}
else if($type == 'file')
{
$target_srl = getModel('file')->getFile($target_srl)->module_srl;
}
else if($type == 'module')
{
$module_info = $this->getModuleInfoByMid($target_srl);
}
}
if(!isset($module_info))
{
$module_info = $this->getModuleInfoByModuleSrl($target_srl);
}
if(!$module_info->module_srl)
{
return false;
}
if(!$member_info)
{
$member_info = Context::get('logged_info');
}
return $this->getGrant($module_info, $member_info);
}
/**
* @brief Search all modules to find manager privilege of the member
* @param object $member_info member information
* @param string $module module name. if used, search scope is same module
* @return mixed success : object, fail : false
*/
function findManagerPrivilege($member_info, $module = null)
{
if(!$member_info->member_srl || empty($mid_list = $this->getMidList()))
{
return false;
}
foreach($mid_list as $module_info)
{
if($module && $module_info->module != $module)
{
continue;
}
if(($grant = $this->getGrant($module_info, $member_info)) && $grant->manager)
{
return $grant;
}
}
return false;
}
/**
* @brief Get module grants
*/