From 52a4da4c428ddf9c4f085e3dce406d57b3d2b8de Mon Sep 17 00:00:00 2001 From: garvinhicking Date: Wed, 23 Aug 2006 13:51:56 +0000 Subject: [PATCH] Major new feature: Allow to restrict plugin hooks and plugins to only specific usergroups --- docs/NEWS | 10 ++- include/admin/groups.inc.php | 72 +++++++++++++++++-- include/db/mysql.inc.php | 31 ++++++-- include/functions_config.inc.php | 67 ++++++++++++++++- include/plugin_api.inc.php | 8 +++ include/tpl/config_local.inc.php | 7 ++ serendipity_config.inc.php | 2 +- sql/db.sql | 35 +++++++-- sql/db_update_1.1-beta3_1.1-beta4_mysql.sql | 2 + ...db_update_1.1-beta3_1.1-beta4_postgres.sql | 0 sql/db_update_1.1-beta3_1.1-beta4_sqlite.sql | 20 ++++++ 11 files changed, 231 insertions(+), 23 deletions(-) create mode 100644 sql/db_update_1.1-beta3_1.1-beta4_mysql.sql create mode 100644 sql/db_update_1.1-beta3_1.1-beta4_postgres.sql create mode 100644 sql/db_update_1.1-beta3_1.1-beta4_sqlite.sql diff --git a/docs/NEWS b/docs/NEWS index 720e106..9d4d28e 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 aebf749..7277c9c 100644 --- a/include/admin/groups.inc.php +++ b/include/admin/groups.inc.php @@ -20,16 +20,16 @@ if (isset($_POST['DELETE_YES']) && serendipity_checkFormToken()) { /* Save new group */ 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']); + $perms = serendipity_getAllPermissionNames(); + serendipity_updateGroupConfig($serendipity['POST']['group'], $perms, $serendipity['POST'], false, $serendipity['POST']['forbidden_plugins'], $serendipity['POST']['forbidden_hooks']); printf('
' . CREATED_GROUP . '
', '#' . $serendipity['POST']['group'] . ', ' . $serendipity['POST']['name']); } /* Edit a group */ if (isset($_POST['SAVE_EDIT']) && serendipity_checkFormToken()) { - $perms = serendipity_getAllPermissionNames(); - serendipity_updateGroupConfig($serendipity['POST']['group'], $perms, $serendipity['POST']); + $perms = serendipity_getAllPermissionNames(); + serendipity_updateGroupConfig($serendipity['POST']['group'], $perms, $serendipity['POST'], false, $serendipity['POST']['forbidden_plugins'], $serendipity['POST']['forbidden_hooks']); printf('
' . MODIFIED_GROUP . '
', $serendipity['POST']['name']); } @@ -132,9 +132,13 @@ foreach($allusers AS $user) {   $userlevels) { + if (substr($perm, 0, 2) == 'f_') { + continue; + } + if (isset($from[$perm]) && $from[$perm] === 'true') { $selected = 'checked="checked"'; } else { @@ -144,7 +148,7 @@ foreach($allusers AS $user) { if (!isset($section)) { $section = $perm; } - + if ($section != $perm && substr($perm, 0, strlen($section)) == $section) { $indent = '  '; $indentB = ''; @@ -159,7 +163,7 @@ foreach($allusers AS $user) { } else { $permname = $perm; } - + if (!serendipity_checkPermission($perm)) { echo "\n"; echo "$indent" . htmlspecialchars($permname) . "\n"; @@ -172,12 +176,66 @@ foreach($allusers AS $user) { echo "\n"; } } + + if ($serendipity['enablePluginACL']) { + $allplugins =& serendipity_plugin_api::get_event_plugins(); + $allhooks = array(); +?> + +   + + + + + + + + + +   + + + + + + + + + +   + + + + + + + + diff --git a/include/db/mysql.inc.php b/include/db/mysql.inc.php index 7056da4..56c474c 100644 --- a/include/db/mysql.inc.php +++ b/include/db/mysql.inc.php @@ -67,6 +67,7 @@ function &serendipity_db_query($sql, $single = false, $result_type = "both", $re 'true' => true, 'false' => false ); + static $benchmark = false; // highlight_string(var_export($sql, 1)); @@ -74,11 +75,18 @@ function &serendipity_db_query($sql, $single = false, $result_type = "both", $re return false; } + if ($benchmark) { + $start = microtime_float(); + } if ($expectError) { $c = @mysql_query($sql, $serendipity['dbConn']); } else { $c = mysql_query($sql, $serendipity['dbConn']); } + if ($benchmark) { + $end = microtime_float(); + echo "[bench: " . ($end-$start) . "s] $sql
\n"; + } if (!$expectError && mysql_error($serendipity['dbConn']) != '') { $msg = '
' . $sql . '
/ ' . mysql_error($serendipity['dbConn']); @@ -118,9 +126,13 @@ function &serendipity_db_query($sql, $single = false, $result_type = "both", $re $rows = array(); while (($row = mysql_fetch_array($c, $result_type))) { - if (!empty($assocKey) && !empty($assocVal)) { + if (!empty($assocKey)) { // You can fetch a key-associated array via the two function parameters assocKey and assocVal - $rows[$row[$assocKey]] = $row[$assocVal]; + if (empty($assocVal)) { + $rows[$row[$assocKey]] = $row; + } else { + $rows[$row[$assocKey]] = $row[$assocVal]; + } } else { $rows[] = $row; } @@ -250,13 +262,22 @@ function serendipity_db_connect() { $serendipity['dbConn'] = $function($serendipity['dbHost'], $serendipity['dbUser'], $serendipity['dbPass']); mysql_select_db($serendipity['dbName']); - if (defined('SQL_CHARSET') && $serendipity['dbNames']) { - mysql_query("SET NAMES " . SQL_CHARSET, $serendipity['dbConn']); - } + serendipity_db_reconnect(); return $serendipity['dbConn']; } +function serendipity_db_reconnect() { + global $serendipity; + + if (isset($serendipity['dbCharset'])) { + mysql_query("SET NAMES " . $serendipity['dbCharset'], $serendipity['dbConn']); + define('SQL_CHARSET_INIT', true); + } elseif (defined('SQL_CHARSET') && $serendipity['dbNames'] && !defined('SQL_CHARSET_INIT')) { + mysql_query("SET NAMES " . SQL_CHARSET, $serendipity['dbConn']); + } +} + /** * Prepares a Serendipty query input to fully valid SQL. Replaces certain "template" variables. * diff --git a/include/functions_config.inc.php b/include/functions_config.inc.php index ae6dab9..71be6a7 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 cd10b28..66f4780 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 66c09af..402eec9 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 233c76b..c3361f8 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 18d31ce..76d0a2f 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); @@ -120,10 +120,12 @@ create table {PREFIX}references ( id {AUTOINCREMENT} {PRIMARY}, entry_id int(10) {UNSIGNED} not null default '0', link text, - name text + name text, + type varchar(128) not null default '' ) {UTF_8}; CREATE INDEX refentry_idx ON {PREFIX}references (entry_id); +CREATE INDEX reftype_idx ON {PREFIX}references (type); # # Table structure for table '{PREFIX}exits' @@ -138,10 +140,10 @@ CREATE TABLE {PREFIX}exits ( port varchar(5), path varchar(255), query varchar(255), - PRIMARY KEY (host,day,entry_id) + PRIMARY KEY (host,path,day,entry_id) ) {UTF_8}; -CREATE INDEX exits_idx ON {PREFIX}exits (entry_id,day); +CREATE INDEX exits_idx ON {PREFIX}exits (entry_id,day,host); # # Table structure for table '{PREFIX}referrers' @@ -173,6 +175,14 @@ create table {PREFIX}config ( CREATE INDEX configauthorid_idx ON {PREFIX}config (authorid); +create table {PREFIX}options ( + name varchar(255) not null, + value text not null, + okey varchar(64) not null default '' +) {UTF_8}; + +CREATE INDEX options_idx ON {PREFIX}options (okey); + CREATE TABLE {PREFIX}suppress ( ip varchar(15) default NULL, scheme varchar(5), @@ -197,6 +207,7 @@ CREATE TABLE {PREFIX}plugins ( CREATE INDEX pluginauthorid_idx ON {PREFIX}plugins (authorid); CREATE INDEX pluginplace_idx ON {PREFIX}plugins (placement); +CREATE INDEX pluginretr_idx ON {PREFIX}plugins (placement, sort_order); CREATE TABLE {PREFIX}category ( categoryid {AUTOINCREMENT} {PRIMARY}, @@ -225,7 +236,8 @@ CREATE TABLE {PREFIX}images ( thumbnail_name varchar(255) not null default '', authorid int(11) default '0', path text, - hotlink int(1) + hotlink int(1), + realname varchar(255) not null default '' ) {UTF_8}; CREATE INDEX imagesauthorid_idx ON {PREFIX}images (authorid); @@ -247,6 +259,17 @@ create table {PREFIX}entryproperties ( CREATE INDEX entrypropid_idx ON {PREFIX}entryproperties (entryid); CREATE UNIQUE INDEX prop_idx ON {PREFIX}entryproperties (entryid, property); +create table {PREFIX}mediaproperties ( + mediaid int(11) not null, + property varchar(128) not null, + property_group varchar(50) not null default '', + property_subgroup varchar(50) not null default '', + value text +) {UTF_8}; + +CREATE INDEX mediapropid_idx ON {PREFIX}mediaproperties (mediaid); +CREATE UNIQUE INDEX media_idx ON {PREFIX}mediaproperties (mediaid, property, property_group, property_subgroup); + CREATE TABLE {PREFIX}permalinks ( permalink varchar(255) not null default '', entry_id int(10) {UNSIGNED} not null default '0', 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 0000000..8c28a28 --- /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 0000000..e69de29 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 0000000..120d660 --- /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; -- 2.39.5