diff --git a/docs/NEWS b/docs/NEWS index 720e1063..9d4d28e4 100644 --- a/docs/NEWS +++ b/docs/NEWS @@ -1,11 +1,17 @@ # $Id$ -Version 1.1-beta2 () +Version 1.1-beta4 () +------------------------------------------------------------------------ + + * Group management now allows to disallow certain plugins or even + specific plugin hooks per usergroup (garvinhicking) + +Version 1.1-beta3 () ------------------------------------------------------------------------ * Change permalinks to allow "%" in URLS. Fix templatedropdown plugin to remove double "//". Fix bad htmlspecialchars of the - RDF ident link. + RDF ident link. (garvinhicking) * Allow to apply current permissions of a directory to all sub- directories (Matthew Groeninger) diff --git a/include/admin/groups.inc.php b/include/admin/groups.inc.php index 30b34df9..7277c9c2 100644 --- a/include/admin/groups.inc.php +++ b/include/admin/groups.inc.php @@ -21,7 +21,7 @@ if (isset($_POST['DELETE_YES']) && serendipity_checkFormToken()) { if (isset($_POST['SAVE_NEW']) && serendipity_checkFormToken()) { $serendipity['POST']['group'] = serendipity_addGroup($serendipity['POST']['name']); $perms = serendipity_getAllPermissionNames(); - serendipity_updateGroupConfig($serendipity['POST']['group'], $perms, $serendipity['POST']); + serendipity_updateGroupConfig($serendipity['POST']['group'], $perms, $serendipity['POST'], false, $serendipity['POST']['forbidden_plugins'], $serendipity['POST']['forbidden_hooks']); printf('
' . $sql . '/ ' . mysql_error($serendipity['dbConn']); return $msg; diff --git a/include/functions_config.inc.php b/include/functions_config.inc.php index ae6dab9b..71be6a77 100644 --- a/include/functions_config.inc.php +++ b/include/functions_config.inc.php @@ -990,7 +990,11 @@ function serendipity_checkPermission($permName, $authorid = null, $returnMyGroup } if ($returnMyGroups) { - return $group[$authorid]['membership']; + if ($returnMyGroups === 'all') { + return $group[$authorid]; + } else { + return $group[$authorid]['membership']; + } } if ($authorid == $serendipity['authorid'] && $serendipity['no_create']) { @@ -1322,9 +1326,11 @@ function serendipity_intersectGroup($checkuser = null, $myself = null) { * @param array The associative array of permission names * @param array The associative array of new values for the permissions. Needs the same associative keys like the $perms array. * @param bool Indicates if an all new privilege should be inserted (true) or if an existing privilege is going to be checked + * @param array The associative array of plugin permission names + * @param array The associative array of plugin permission hooks * @return true */ -function serendipity_updateGroupConfig($groupid, &$perms, &$values, $isNewPriv = false) { +function serendipity_updateGroupConfig($groupid, &$perms, &$values, $isNewPriv = false, $forbidden_plugins = null, $forbidden_hooks = null) { global $serendipity; if (!serendipity_checkPermission('adminUsersGroups')) { @@ -1343,6 +1349,10 @@ function serendipity_updateGroupConfig($groupid, &$perms, &$values, $isNewPriv = serendipity_db_query("DELETE FROM {$serendipity['dbPrefix']}groupconfig WHERE id = " . (int)$groupid); foreach ($perms AS $perm => $userlevels) { + if (substr($perm, 0, 2) == 'f_') { + continue; + } + if (isset($values[$perm]) && $values[$perm] == 'true') { $value = 'true'; } elseif (isset($values[$perm]) && $values[$perm] === 'false') { @@ -1370,6 +1380,28 @@ function serendipity_updateGroupConfig($groupid, &$perms, &$values, $isNewPriv = ); } + if (is_array($forbidden_plugins)) { + foreach($forbidden_plugins AS $plugid) { + serendipity_db_query( + sprintf("INSERT INTO {$serendipity['dbPrefix']}groupconfig (id, property, value) VALUES (%d, '%s', 'true')", + (int)$groupid, + serendipity_db_escape_string('f_' . urldecode($plugid)) + ) + ); + } + } + + if (is_array($forbidden_hooks)) { + foreach($forbidden_hooks AS $hook) { + serendipity_db_query( + sprintf("INSERT INTO {$serendipity['dbPrefix']}groupconfig (id, property, value) VALUES (%d, '%s', 'true')", + (int)$groupid, + serendipity_db_escape_string('f_' . urldecode($hook)) + ) + ); + } + } + serendipity_db_query("UPDATE {$serendipity['dbPrefix']}groups SET name = '" . serendipity_db_escape_string($values['name']) . "' WHERE id = " . (int)$groupid); if (is_array($values['members'])) { @@ -1824,4 +1856,35 @@ function &serendipity_loadThemeOptions(&$template_config) { return $template_vars; } + +function serendipity_hasPluginPermissions($plugin) { + static $forbidden = null; + global $serendipity; + + if (empty($serendipity['authorid'])) { + return true; + } + + if ($forbidden === null) { + $forbidden = array(); + $groups =& serendipity_checkPermission(null, null, 'all'); + foreach($groups AS $idx => $group) { + if ($idx == 'membership') { + continue; + } + foreach($group AS $key => $val) { + if (substr($key, 0, 2) == 'f_') { + $forbidden[$key] = true; + } + } + } + } + + if (isset($forbidden['f_' . $plugin])) { + return false; + } else { + return true; + } +} + /* vim: set sts=4 ts=4 expandtab : */ diff --git a/include/plugin_api.inc.php b/include/plugin_api.inc.php index cd10b288..66f47802 100644 --- a/include/plugin_api.inc.php +++ b/include/plugin_api.inc.php @@ -972,6 +972,10 @@ class serendipity_plugin_api { return false; } + if ($serendipity['enablePluginACL'] && !serendipity_hasPluginPermissions($event_name)) { + return false; + } + // We can NOT use a "return by reference" here, because then when // a plugin executes another event_hook, the referenced variable within // that call will overwrite the previous original plugin listing and @@ -985,6 +989,7 @@ class serendipity_plugin_api { $bag = &$plugin_data['b']; $phooks = &$bag->get('event_hooks'); if (isset($phooks[$event_name])) { + // Check for cachable events. if (isset($eventData['is_cached']) && $eventData['is_cached']) { $chooks = &$bag->get('cachable_events'); @@ -993,6 +998,9 @@ class serendipity_plugin_api { } } + if ($serendipity['enablePluginACL'] && !serendipity_hasPluginPermissions($plugin)) { + continue; + } $plugin_data['p']->event_hook($event_name, $bag, $eventData, $addData); } } diff --git a/include/tpl/config_local.inc.php b/include/tpl/config_local.inc.php index 66c09af0..402eec9c 100644 --- a/include/tpl/config_local.inc.php +++ b/include/tpl/config_local.inc.php @@ -377,6 +377,13 @@ 'type' => 'bool', 'default' => false, 'permission' => 'blogConfiguration'), + + array('var' => 'enablePluginACL', + 'title' => PERMISSION_FORBIDDEN_ENABLE, + 'description' => PERMISSION_FORBIDDEN_ENABLE_DESC, + 'type' => 'bool', + 'default' => false, + 'permission' => 'blogConfiguration'), )); $res['display'] = diff --git a/serendipity_config.inc.php b/serendipity_config.inc.php index 233c76b7..c3361f80 100644 --- a/serendipity_config.inc.php +++ b/serendipity_config.inc.php @@ -27,7 +27,7 @@ if (IS_installed === true && !defined('IN_serendipity')) { include(S9Y_INCLUDE_PATH . 'include/compat.inc.php'); // The version string -$serendipity['version'] = '1.1-beta3'; +$serendipity['version'] = '1.1-beta4'; // Setting this to 'false' will enable debugging output. All alpa/beta/cvs snapshot versions will emit debug information by default. To increase the debug level (to enable Smarty debugging), set this flag to 'debug'. $serendipity['production'] = (preg_match('@\-(alpha|beta|cvs)@', $serendipity['version']) ? false : true); diff --git a/sql/db.sql b/sql/db.sql index 197dab6f..76d0a2fb 100644 --- a/sql/db.sql +++ b/sql/db.sql @@ -30,8 +30,8 @@ create table {PREFIX}groups ( create table {PREFIX}groupconfig ( id int(10) {UNSIGNED} not null default '0', - property varchar(64) default null, - value varchar(128) default null + property varchar(128) default null, + value varchar(32) default null ) {UTF_8}; CREATE INDEX groupid_idx ON {PREFIX}groupconfig (id); diff --git a/sql/db_update_1.1-beta3_1.1-beta4_mysql.sql b/sql/db_update_1.1-beta3_1.1-beta4_mysql.sql new file mode 100644 index 00000000..8c28a288 --- /dev/null +++ b/sql/db_update_1.1-beta3_1.1-beta4_mysql.sql @@ -0,0 +1,2 @@ +ALTER TABLE {PREFIX}groupconfig CHANGE property property varchar(128) NULL DEFAULT NULL; +ALTER TABLE {PREFIX}groupconfig CHANGE value value varchar(64) NULL DEFAULT NULL; diff --git a/sql/db_update_1.1-beta3_1.1-beta4_postgres.sql b/sql/db_update_1.1-beta3_1.1-beta4_postgres.sql new file mode 100644 index 00000000..e69de29b diff --git a/sql/db_update_1.1-beta3_1.1-beta4_sqlite.sql b/sql/db_update_1.1-beta3_1.1-beta4_sqlite.sql new file mode 100644 index 00000000..120d660b --- /dev/null +++ b/sql/db_update_1.1-beta3_1.1-beta4_sqlite.sql @@ -0,0 +1,20 @@ +create table {PREFIX}tempgroupconfig ( + id int(10) {UNSIGNED} not null default '0', + property varchar(128) default null, + value varchar(32) default null +) {UTF_8}; + +INSERT INTO {PREFIX}tempgroupconfig (id,property,value) SELECT id,property,value FROM {PREFIX}groupconfig; +DROP TABLE {PREFIX}groupconfig; + +create table {PREFIX}groupconfig ( + id int(10) {UNSIGNED} not null default '0', + property varchar(128) default null, + value varchar(32) default null +) {UTF_8}; + +CREATE INDEX groupid_idx ON {PREFIX}groupconfig (id); +CREATE INDEX groupprop_idx ON {PREFIX}groupconfig (id, property); + +INSERT INTO {PREFIX}groupconfig (id,property,value) SELECT id,property,value FROM {PREFIX}tempgroupconfig; +DROP TABLE {PREFIX}tempgroupconfig;