# $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)
/* 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']);
}
<td colspan="2"> </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 {
if (!isset($section)) {
$section = $perm;
}
-
+
if ($section != $perm && substr($perm, 0, strlen($section)) == $section) {
$indent = ' ';
$indentB = '';
} else {
$permname = $perm;
}
-
+
if (!serendipity_checkPermission($perm)) {
echo "<tr>\n";
echo "<td>$indent" . htmlspecialchars($permname) . "</td>\n";
echo "</tr>\n";
}
}
+
+ if ($serendipity['enablePluginACL']) {
+ $allplugins =& serendipity_plugin_api::get_event_plugins();
+ $allhooks = array();
+?>
+ <tr>
+ <td colspan="2"> </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"> </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"> </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 } ?>
'true' => true,
'false' => false
);
+ static $benchmark = false;
// highlight_string(var_export($sql, 1));
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']);
$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;
}
$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.
*
}
if ($returnMyGroups) {
- return $group[$authorid]['membership'];
+ if ($returnMyGroups === 'all') {
+ return $group[$authorid];
+ } else {
+ return $group[$authorid]['membership'];
+ }
}
if ($authorid == $serendipity['authorid'] && $serendipity['no_create']) {
* @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')) {
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') {
);
}
+ 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'])) {
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 : */
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
$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');
}
}
+ if ($serendipity['enablePluginACL'] && !serendipity_hasPluginPermissions($plugin)) {
+ continue;
+ }
$plugin_data['p']->event_hook($event_name, $bag, $eventData, $addData);
}
}
'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'] =
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);
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);
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'
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'
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),
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},
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);
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',
--- /dev/null
+ALTER TABLE {PREFIX}groupconfig CHANGE property property varchar(128) NULL DEFAULT NULL;
+ALTER TABLE {PREFIX}groupconfig CHANGE value value varchar(64) NULL DEFAULT NULL;
--- /dev/null
+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;