]> git.mjollnir.org Git - s9y.git/commitdiff
Major new feature: Allow to restrict plugin hooks and plugins to only specific usergroups
authorgarvinhicking <garvinhicking>
Wed, 23 Aug 2006 13:51:56 +0000 (13:51 +0000)
committergarvinhicking <garvinhicking>
Wed, 23 Aug 2006 13:51:56 +0000 (13:51 +0000)
docs/NEWS
include/admin/groups.inc.php
include/db/mysql.inc.php
include/functions_config.inc.php
include/plugin_api.inc.php
include/tpl/config_local.inc.php
serendipity_config.inc.php
sql/db.sql
sql/db_update_1.1-beta3_1.1-beta4_mysql.sql [new file with mode: 0644]
sql/db_update_1.1-beta3_1.1-beta4_postgres.sql [new file with mode: 0644]
sql/db_update_1.1-beta3_1.1-beta4_sqlite.sql [new file with mode: 0644]

index 720e10637692c140b9578391b189f3d27b7d8e70..9d4d28e4867c4f576b8fdcd1c6c2abcda5478c07 100644 (file)
--- 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)
index aebf74986f6b02e409638e753b29615cff722d3d..7277c9c20dc946ce1110900e97ac8fe03d161bce 100644 (file)
@@ -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('<div class="serendipityAdminMsgSuccess">' . CREATED_GROUP . '</div>', '#' . $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('<div class="serendipityAdminMsgSuccess">' . MODIFIED_GROUP . '</div>', $serendipity['POST']['name']);
 }
 
@@ -132,9 +132,13 @@ foreach($allusers AS $user) {
         <td colspan="2">&nbsp;</td>
     </tr>
 <?php
-    $perms = serendipity_getAllPermissionNames();    
+    $perms = serendipity_getAllPermissionNames();
     ksort($perms);
     foreach($perms AS $perm => $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  = '&nbsp;&nbsp;';
             $indentB = '';
@@ -159,7 +163,7 @@ foreach($allusers AS $user) {
         } else {
             $permname = $perm;
         }
-        
+
         if (!serendipity_checkPermission($perm)) {
             echo "<tr>\n";
             echo "<td>$indent" . htmlspecialchars($permname) . "</td>\n";
@@ -172,12 +176,66 @@ foreach($allusers AS $user) {
             echo "</tr>\n";
         }
     }
+
+    if ($serendipity['enablePluginACL']) {
+        $allplugins =& serendipity_plugin_api::get_event_plugins();
+        $allhooks   = array();
+?>
+    <tr>
+        <td colspan="2">&nbsp;</td>
+    </tr>
+    <tr>
+        <td valign="top"><?php echo PERMISSION_FORBIDDEN_PLUGINS; ?></td>
+        <td>
+            <select name="serendipity[forbidden_plugins][]" multiple="multiple" size="5">
+            <?php
+                foreach($allplugins AS $plugid => $currentplugin) {
+                    foreach($currentplugin['b']->properties['event_hooks'] AS $hook => $set) {
+                        $allhooks[$hook] = true;
+                    }
+                    echo '<option value="' . urlencode($plugid) . '" ' . (serendipity_hasPluginPermissions($plugid) ? '' : 'selected="selected"') . '>' . htmlspecialchars($currentplugin['b']->properties['name']) . '</option>' . "\n";
+                }
+                ksort($allhooks);
+            ?>
+            </select>
+        </td>
+    </tr>
+
+    <tr>
+        <td colspan="2">&nbsp;</td>
+    </tr>
+    <tr>
+        <td valign="top"><?php echo PERMISSION_FORBIDDEN_HOOKS; ?></td>
+        <td>
+            <select name="serendipity[forbidden_hooks][]" multiple="multiple" size="5">
+            <?php
+                foreach($allhooks AS $hook => $set) {
+                    echo '<option value="' . urlencode($hook) . '" ' . (serendipity_hasPluginPermissions($hook) ? '' : 'selected="selected"') . '>' . htmlspecialchars($hook) . '</option>' . "\n";
+                }
+            ?>
+            </select>
+        </td>
+    </tr>
+<?php
+    } else {
+?>
+    <tr>
+        <td colspan="2">&nbsp;</td>
+    </tr>
+
+    <tr>
+        <td colspan="2"><?php echo PERMISSION_FORBIDDEN_ENABLE_DESC; ?></td>
+    </tr>
+<?php
+    }
 ?>
 </table>
 
 <?php
 if ($serendipity['GET']['adminAction'] == 'edit') { ?>
         <input type="submit" name="SAVE_EDIT"   value="<?php echo SAVE; ?>" class="serendipityPrettyButton" />
+        <?php echo ' - ' . WORD_OR . ' - ' ?>
+        <input type="submit" name="SAVE_NEW"   value="<?php echo CREATE_NEW_GROUP; ?>" class="serendipityPrettyButton" />
 <?php } else { ?>
         <input type="submit" name="SAVE_NEW" value="<?php echo CREATE_NEW_GROUP; ?>" class="serendipityPrettyButton" />
 <?php } ?>
index 7056da4d263fe96b4baeda0f506b89a86e3b7384..56c474c1d0bb707901edbb92292965ad2005cf03 100644 (file)
@@ -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<br />\n";
+    }
 
     if (!$expectError && mysql_error($serendipity['dbConn']) != '') {
         $msg = '<pre>' . $sql . '</pre> / ' . 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.
  *
index ae6dab9b4d8e795ea94f04d5698b5fb3fd69d585..71be6a77ec94e2a217f1b1a829ed1846fa77b706 100644 (file)
@@ -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 : */
index cd10b28857f7e6c3c48d168303ebdb2aafb68ba4..66f47802d85dbf0cce71f3c863ed9a5ee30d804e 100644 (file)
@@ -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);
                 }
             }
index 66c09af02bed16ed8b0cf1203360e7eab84413c2..402eec9c9da8a9d9e55e77abd74d6b4128dc471f 100644 (file)
                                           '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'] =
index 233c76b7b30540f77c5d59899aa38bfeaff5b923..c3361f80138204e64fabff31fcc7013ae0cf416f 100644 (file)
@@ -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);
index 18d31ce7e487dc319b842141092cdd23a95e5895..76d0a2fb032b1e58fe92170fc67d92e35d0731a7 100644 (file)
@@ -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 (file)
index 0000000..8c28a28
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..120d660
--- /dev/null
@@ -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;