From b17c58f17f845ad520857200403c549afe905e09 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 14 Oct 2024 23:40:58 +0900 Subject: [PATCH] Implement admin scopes --- modules/module/lang/en.php | 4 ++ modules/module/lang/ko.php | 4 ++ modules/module/models/Permission.php | 64 ++++++++++++++++++++++ modules/module/module.admin.controller.php | 7 ++- modules/module/module.class.php | 12 ++++ modules/module/module.controller.php | 10 +++- modules/module/module.model.php | 52 +++++++++++++++--- modules/module/queries/getModuleAdmin.xml | 3 + modules/module/queries/insertAdminId.xml | 1 + modules/module/schemas/module_admins.xml | 1 + modules/module/tpl/module_grants.html | 17 +++++- 11 files changed, 163 insertions(+), 12 deletions(-) create mode 100644 modules/module/models/Permission.php diff --git a/modules/module/lang/en.php b/modules/module/lang/en.php index 6a81ee07f..d9172183d 100644 --- a/modules/module/lang/en.php +++ b/modules/module/lang/en.php @@ -97,6 +97,10 @@ $lang->about_mobile_page_count = 'You can set the number of page links to move p $lang->about_admin_id = 'You can grant someone permission to manage this module. Please enter the user ID or email address of the person you wish to add.'; $lang->about_grant_deatil = 'Registered users mean users who signed-up to the virtual sites (e.g., cafeXE).'; $lang->about_module = 'Rhymix consists of modules except the basic library. [Module Manage] module will show all installed modules and help you to manage them.'; +$lang->admin_scope = 'Scope of Admin Powers'; +$lang->admin_scopes['moderate:document'] = 'Manage documents'; +$lang->admin_scopes['moderate:comment'] = 'Manage comments'; +$lang->admin_scopes['config:*'] = 'Change settings'; $lang->extra_vars_is_strict = 'Specified values only'; $lang->extra_vars_options = 'Options'; $lang->about_extra_vars_is_strict = 'In single and multiple choice fields, only allow the values specified below. If you change the allowed values, it may affect previous posts.'; diff --git a/modules/module/lang/ko.php b/modules/module/lang/ko.php index 4b4ffe96a..212f0a39a 100644 --- a/modules/module/lang/ko.php +++ b/modules/module/lang/ko.php @@ -96,6 +96,10 @@ $lang->about_mobile_page_count = '목록 하단, 페이지를 이동하는 링 $lang->about_admin_id = '특정 회원에게 이 모듈의 관리 권한을 부여할 수 있습니다. 권한을 부여할 회원의 아이디 또는 이메일 주소를 입력해 주세요.'; $lang->about_grant_deatil = '가입한 사용자는 cafeXE 등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다.'; $lang->about_module = 'Rhymix는 기본 라이브러리를 제외한 나머지는 모두 모듈로 구성되어 있습니다. 모듈 관리 모듈은 설치된 모든 모듈을 보여주고 관리를 돕습니다.'; +$lang->admin_scope = '관리자 권한 범위'; +$lang->admin_scopes['moderate:document'] = '문서 관리'; +$lang->admin_scopes['moderate:comment'] = '댓글 관리'; +$lang->admin_scopes['config:*'] = '모듈 설정 변경'; $lang->extra_vars_is_strict = '임의입력 금지'; $lang->extra_vars_options = '선택지'; $lang->about_extra_vars_is_strict = '단일/다중 선택에서 미리 주어진 선택지만 입력할 수 있도록 합니다. 선택지를 변경할 경우 기존 게시물에 영향을 줄 수 있습니다.'; diff --git a/modules/module/models/Permission.php b/modules/module/models/Permission.php new file mode 100644 index 000000000..5a3daa591 --- /dev/null +++ b/modules/module/models/Permission.php @@ -0,0 +1,64 @@ +{$scope}) && $scope !== 'scopes') + { + return boolval($this->{$scope}); + } + + if ($this->manager && $this->scopes && preg_match('/^(\w+):(.+)$/', $scope, $matches)) + { + if ($this->scopes === true) + { + return true; + } + if (is_array($this->scopes) && in_array($scope, $this->scopes)) + { + return true; + } + if (is_array($this->scopes) && in_array($matches[1] . ':*', $this->scopes)) + { + return true; + } + } + + return false; + } +} diff --git a/modules/module/module.admin.controller.php b/modules/module/module.admin.controller.php index cc7f6b577..8e4338cfb 100644 --- a/modules/module/module.admin.controller.php +++ b/modules/module/module.admin.controller.php @@ -292,6 +292,11 @@ class ModuleAdminController extends Module // Register Admin ID $oModuleController->deleteAdminId($module_srl); $admin_member = Context::get('admin_member'); + $scopes = Context::get('admin_scopes') ?: null; + if(is_string($scopes) && $scopes !== '') + { + $scopes = explode('|@|', $scopes); + } if($admin_member) { $admin_members = explode(',',$admin_member); @@ -299,7 +304,7 @@ class ModuleAdminController extends Module { $admin_id = trim($admin_id); if(!$admin_id) continue; - $oModuleController->insertAdminId($module_srl, $admin_id); + $oModuleController->insertAdminId($module_srl, $admin_id, $scopes); } } diff --git a/modules/module/module.class.php b/modules/module/module.class.php index e19fc2dbb..8845a2ddd 100644 --- a/modules/module/module.class.php +++ b/modules/module/module.class.php @@ -148,6 +148,12 @@ class Module extends ModuleObject { return true; } + + // check scope column on module_admins table + if (!$oDB->isColumnExists('module_admins', 'scopes')) + { + return true; + } } /** @@ -311,6 +317,12 @@ class Module extends ModuleObject return $output; } } + + // check scope column on module_admins table + if (!$oDB->isColumnExists('module_admins', 'scopes')) + { + $oDB->addColumn('module_admins', 'scopes', 'text', null, null, false, 'member_srl'); + } } /** diff --git a/modules/module/module.controller.php b/modules/module/module.controller.php index 1178cc8ce..93e76cfac 100644 --- a/modules/module/module.controller.php +++ b/modules/module/module.controller.php @@ -806,7 +806,7 @@ class ModuleController extends Module /** * @brief Specify the admin ID to a module */ - function insertAdminId($module_srl, $admin_id) + function insertAdminId($module_srl, $admin_id, $scopes = null) { if (strpos($admin_id, '@') !== false) { @@ -824,6 +824,14 @@ class ModuleController extends Module $args = new stdClass(); $args->module_srl = intval($module_srl); $args->member_srl = $member_info->member_srl; + if (is_array($scopes)) + { + $args->scopes = json_encode(array_values($scopes)); + } + else + { + $args->scopes = new Rhymix\Framework\Parsers\DBQuery\NullValue; + } $output = executeQuery('module.insertAdminId', $args); Rhymix\Framework\Cache::delete("site_and_module:module_admins:" . intval($module_srl)); diff --git a/modules/module/module.model.php b/modules/module/module.model.php index 473185703..4034a53e1 100644 --- a/modules/module/module.model.php +++ b/modules/module/module.model.php @@ -1853,7 +1853,9 @@ class ModuleModel extends Module } /** - * @brief Check if a member is a module administrator + * Check if a member is a module administrator + * + * @return array|bool */ public static function isModuleAdmin($member_info, $module_srl = null) { @@ -1882,14 +1884,22 @@ class ModuleModel extends Module $module_admins = array(); foreach ($output->data as $module_admin) { - $module_admins[$module_admin->member_srl] = true; + $module_admins[$module_admin->member_srl] = $module_admin->scopes ? json_decode($module_admin->scopes) : true; } if ($output->toBool()) { Rhymix\Framework\Cache::set("site_and_module:module_admins:$module_srl", $module_admins, 0, true); } } - return isset($module_admins[$member_info->member_srl]); + + if (isset($module_admins[$member_info->member_srl])) + { + return $module_admins[$member_info->member_srl]; + } + else + { + return false; + } } /** @@ -1900,8 +1910,14 @@ class ModuleModel extends Module $obj = new stdClass(); $obj->module_srl = $module_srl; $output = executeQueryArray('module.getAdminID', $obj); - if(!$output->toBool() || !$output->data) return; - + if (!$output->toBool() || !$output->data) + { + return; + } + foreach ($output->data as $row) + { + $row->scopes = !empty($row->scopes) ? json_decode($row->scopes) : null; + } return $output->data; } @@ -2129,7 +2145,12 @@ class ModuleModel extends Module } /** - * @brief Return privileges(granted) information by using module info, xml info and member info + * Get privileges(granted) information by using module info, xml info and member info + * + * @param object $module_info + * @param object $member_info + * @param ?object $xml_info + * @return Rhymix\Modules\Module\Models\Permission */ public static function getGrant($module_info, $member_info, $xml_info = null) { @@ -2148,8 +2169,6 @@ class ModuleModel extends Module } } - $grant = new stdClass; - // Get information of module.xml if(!$xml_info) { @@ -2172,6 +2191,7 @@ class ModuleModel extends Module $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 @@ -2180,7 +2200,7 @@ class ModuleModel extends Module $grant->{$val} = true; } // If a module manager, grant all (except 'root', 'is_admin') - else if($is_module_admin === true && $val !== 'root' && $val !== 'is_admin') + elseif ($is_module_admin && $val !== 'root' && $val !== 'is_admin') { $grant->{$val} = true; } @@ -2196,6 +2216,20 @@ class ModuleModel extends Module } } + // 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) { diff --git a/modules/module/queries/getModuleAdmin.xml b/modules/module/queries/getModuleAdmin.xml index 55f163796..ef91b3f6c 100644 --- a/modules/module/queries/getModuleAdmin.xml +++ b/modules/module/queries/getModuleAdmin.xml @@ -2,6 +2,9 @@ + + + diff --git a/modules/module/queries/insertAdminId.xml b/modules/module/queries/insertAdminId.xml index 60f1ab088..ed510fcb0 100644 --- a/modules/module/queries/insertAdminId.xml +++ b/modules/module/queries/insertAdminId.xml @@ -5,6 +5,7 @@ + diff --git a/modules/module/schemas/module_admins.xml b/modules/module/schemas/module_admins.xml index 7de4e5545..b98994a83 100644 --- a/modules/module/schemas/module_admins.xml +++ b/modules/module/schemas/module_admins.xml @@ -1,5 +1,6 @@
+
diff --git a/modules/module/tpl/module_grants.html b/modules/module/tpl/module_grants.html index 630c44748..7845360e6 100644 --- a/modules/module/tpl/module_grants.html +++ b/modules/module/tpl/module_grants.html @@ -8,7 +8,7 @@
- +

{$lang->module_admin}

@@ -34,6 +34,21 @@

{$lang->about_admin_id}

+
+ +
+ {@ $default_scopes = array_keys($lang->admin_scopes->getArrayCopy())} + {@ $admin_scopes = $admin_member ? (array_first($admin_member)->scopes ?? $default_scopes) : $default_scopes} + + + +
+