# HG changeset patch # User Dan # Date 1182639256 14400 # Node ID 5d003b6c9e89ad2221c29202c84d6208c4c2eb48 # Parent edfc244087696ea274955586d936580b31d993dd Added demo mode functionality to various parts of Enano (unlocked only with a plugin) and fixed groups table diff -r edfc24408769 -r 5d003b6c9e89 includes/functions.php --- a/includes/functions.php Sat Jun 23 10:38:24 2007 -0400 +++ b/includes/functions.php Sat Jun 23 18:54:16 2007 -0400 @@ -906,7 +906,14 @@ { ob_start(); echo '
';
-  debug_print_backtrace();
+  if ( function_exists('debug_print_backtrace') )
+  {
+    debug_print_backtrace();
+  }
+  else
+  {
+    echo 'Warning: No debug_print_backtrace() support!';
+  }
   echo '
'; $c = ob_get_contents(); ob_end_clean(); diff -r edfc24408769 -r 5d003b6c9e89 includes/pageutils.php --- a/includes/pageutils.php Sat Jun 23 10:38:24 2007 -0400 +++ b/includes/pageutils.php Sat Jun 23 18:54:16 2007 -0400 @@ -1784,6 +1784,10 @@ break; case 'save_new': case 'save_edit': + if ( defined('ENANO_DEMO_MODE') ) + { + return Array('mode'=>'error','error'=>'Editing access control lists is disabled in the administration demo.'); + } $q = $db->sql_query('DELETE FROM '.table_prefix.'acl WHERE target_type='.intval($parms['target_type']).' AND target_id='.intval($parms['target_id']).' '.$page_where_clause_lite.';'); if(!$q) @@ -1811,6 +1815,10 @@ ); break; case 'delete': + if ( defined('ENANO_DEMO_MODE') ) + { + return Array('mode'=>'error','error'=>'Editing access control lists is disabled in the administration demo.'); + } $q = $db->sql_query('DELETE FROM '.table_prefix.'acl WHERE target_type='.intval($parms['target_type']).' AND target_id='.intval($parms['target_id']).' '.$page_where_clause_lite.';'); if(!$q) diff -r edfc24408769 -r 5d003b6c9e89 plugins/SpecialAdmin.php --- a/plugins/SpecialAdmin.php Sat Jun 23 10:38:24 2007 -0400 +++ b/plugins/SpecialAdmin.php Sat Jun 23 18:54:16 2007 -0400 @@ -10,7 +10,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.0 release candidate 2 + * Version 1.0 release candidate 3 * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -58,8 +58,15 @@ Using the links on the left you can control every aspect of your website\'s look and feel, plus you can manage users, work with pages, and install plugins to make your Enano installation even better.'); + // Demo mode + if ( defined('ENANO_DEMO_MODE') ) + { + echo '

Enano is running in demo mode.

+

If you borked something up, or if you\'re done testing, you can reset this site. The site is reset automatically once every two hours. When a reset is performed, all custom modifications to the site are lost and replaced with default values.

'; + } + // Check for the installer scripts - if(file_exists(ENANO_ROOT.'/install.php') || file_exists(ENANO_ROOT.'/schema.sql')) + if( ( file_exists(ENANO_ROOT.'/install.php') || file_exists(ENANO_ROOT.'/schema.sql') ) && !defined('ENANO_DEMO_MODE') ) { echo '
NOTE: It appears that your install.php and/or schema.sql files still exist. It is HIGHLY RECOMMENDED that you delete or rename these files, to prevent getting your server hacked.
'; } @@ -141,7 +148,8 @@ return; } - if(isset($_POST['submit'])) { + if(isset($_POST['submit']) && !defined('ENANO_DEMO_MODE') ) + { // Global site options setConfig('site_name', $_POST['site_name']); @@ -214,6 +222,10 @@ echo '
Your changes to the site configuration have been saved.

'; } + else if ( isset($_POST['submit']) && defined('ENANO_DEMO_MODE') ) + { + echo '
Saving the general site configuration is blocked in the administration demo.
'; + } echo('
'); ?>
@@ -461,7 +473,14 @@ if(file_exists($_POST['imagemagick_path'])) setConfig('imagemagick_path', $_POST['imagemagick_path']); else echo 'Warning: the file "'.$_POST['imagemagick_path'].'" was not found, and the ImageMagick file path was not updated.'; $max_upload = floor((float)$_POST['max_file_size'] * (int)$_POST['fs_units']); - setConfig('max_file_size', $max_upload.''); + if ( $max_upload > 1048576 && defined('ENANO_DEMO_MODE') ) + { + echo '
Wouldn\'t want the server DoS\'ed now. Stick to under a megabyte for the demo, please.
'; + } + else + { + setConfig('max_file_size', $max_upload.''); + } } echo ''; ?> @@ -513,6 +532,11 @@ setConfig('plugin_'.$_GET['plugin'], '1'); break; case "disable": + if ( defined('ENANO_DEMO_MODE') && strstr($_GET['plugin'], 'Demo') ) + { + echo('

Error disabling plugin

The demo lockdown plugin cannot be disabled in demo mode.

'); + break; + } if ( $_GET['plugin'] != 'SpecialAdmin.php' ) { setConfig('plugin_'.$_GET['plugin'], '0'); @@ -613,7 +637,7 @@ } global $mime_types, $mimetype_exps, $mimetype_extlist; - if(isset($_POST['save'])) + if(isset($_POST['save']) && !defined('ENANO_DEMO_MODE')) { $bits = ''; $keys = array_keys($mime_types); @@ -626,6 +650,10 @@ setConfig('allowed_mime_types', $bits); echo '
Your changes have been saved.
'; } + else if ( isset($_POST['save']) && defined('ENANO_DEMO_MODE') ) + { + echo '
Hmm, enabling executables, are we? Tsk tsk. I\'d love to know what\'s in that EXE file you want to upload. OK, maybe you didn\'t enable EXEs. But nevertheless, changing allowed filetypes is disabled in the demo.
'; + } $allowed = fetch_allowed_extensions(); ?>

Allowed file types

@@ -727,11 +755,19 @@ return; } - if(isset($_POST['go'])) { + if(isset($_POST['go'])) + { // We need the user ID before we can do anything $q = $db->sql_query('SELECT user_id,username,email,real_name,style,user_level FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_POST['username']) . '\''); - if(!$q) die('Error selecting user ID: '.mysql_error()); - if($db->numrows() < 1) { echo('User does not exist, please enter another username.'); return; } + if ( !$q ) + { + die('Error selecting user ID: '.mysql_error()); + } + if ( $db->numrows() < 1 ) + { + echo('User does not exist, please enter another username.'); + return; + } $r = $db->fetchrow(); $db->free_result(); if(isset($_POST['save'])) @@ -741,7 +777,15 @@ $new_level = $_POST['level']; $old_level = intval($r['user_level']); - $re = $session->update_user((int)$r['user_id'], $_POST['new_username'], false, $_POST['new_pass'], $_POST['email'], $_POST['real_name'], false, $_POST['level']); + if ( defined('ENANO_DEMO_MODE') ) + { + echo '
You cannot delete or modify user accounts in demo mode - they are cleaned up once every two hours.
'; + $re = Array('permission denied'); + } + else + { + $re = $session->update_user((int)$r['user_id'], $_POST['new_username'], false, $_POST['new_pass'], $_POST['email'], $_POST['real_name'], false, $_POST['level']); + } if($re == 'success') { @@ -789,14 +833,21 @@ } elseif(isset($_POST['deleteme']) && isset($_POST['delete_conf'])) { - $q = $db->sql_query('DELETE FROM users WHERE user_id='.$r['user_id'].';'); - if($q) + if ( defined('ENANO_DEMO_MODE') ) { - echo '
The user account "'.$r['username'].'" was deleted.
'; + echo '
You cannot delete or modify user accounts in demo mode - they are cleaned up once every two hours.
'; } else { - echo '
The user account "'.$r['username'].'" could not be deleted due to a database error.

'.$db->get_error().'
'; + $q = $db->sql_query('DELETE FROM users WHERE user_id='.$r['user_id'].';'); + if($q) + { + echo '
The user account "'.$r['username'].'" was deleted.
'; + } + else + { + echo '
The user account "'.$r['username'].'" could not be deleted due to a database error.

'.$db->get_error().'
'; + } } } else @@ -817,25 +868,34 @@ '); } - } elseif(isset($_POST['clearsessions'])) { - // Get the current session information so the user doesn't get logged out - $aes = new AESCrypt(); - $sk = md5($session->sid_super); - $qb = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.$sk.'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_ADMIN); - if(!$qb) die('Error selecting session key info block B: '.$db->get_error()); - if($db->numrows($qb) < 1) die('Error: cannot read admin session info block B, aborting table clear process'); - $qa = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.md5($session->sid).'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_MEMBER); - if(!$qa) die('Error selecting session key info block A: '.$db->get_error()); - if($db->numrows($qa) < 1) die('Error: cannot read user session info block A, aborting table clear process'); - $ra = mysql_fetch_object($qa); - $rb = mysql_fetch_object($qb); - $db->free_result($qa); - $db->free_result($qb); - $db->sql_query('DELETE FROM '.table_prefix.'session_keys;'); - $db->sql_query('INSERT INTO '.table_prefix.'session_keys( session_key,salt,user_id,auth_level,source_ip,time ) VALUES( \''.$ra->session_key.'\', \''.$ra->salt.'\', \''.$session->user_id.'\', \''.$ra->auth_level.'\', \''.$ra->source_ip.'\', '.$ra->time.' ),( \''.$rb->session_key.'\', \''.$rb->salt.'\', \''.$session->user_id.'\', \''.$rb->auth_level.'\', \''.$rb->source_ip.'\', '.$rb->time.' )'); - echo(' -
The session key table has been cleared. Your database should be a little bit smaller now.
- '); + } + else if(isset($_POST['clearsessions'])) + { + if ( defined('ENANO_DEMO_MODE') ) + { + echo '
Sorry Charlie, no can do. You might mess up other people logged into the demo site.
'; + } + else + { + // Get the current session information so the user doesn't get logged out + $aes = new AESCrypt(); + $sk = md5($session->sid_super); + $qb = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.$sk.'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_ADMIN); + if(!$qb) die('Error selecting session key info block B: '.$db->get_error()); + if($db->numrows($qb) < 1) die('Error: cannot read admin session info block B, aborting table clear process'); + $qa = $db->sql_query('SELECT session_key,salt,auth_level,source_ip,time FROM '.table_prefix.'session_keys WHERE session_key=\''.md5($session->sid).'\' AND user_id='.$session->user_id.' AND auth_level='.USER_LEVEL_MEMBER); + if(!$qa) die('Error selecting session key info block A: '.$db->get_error()); + if($db->numrows($qa) < 1) die('Error: cannot read user session info block A, aborting table clear process'); + $ra = mysql_fetch_object($qa); + $rb = mysql_fetch_object($qb); + $db->free_result($qa); + $db->free_result($qb); + $db->sql_query('DELETE FROM '.table_prefix.'session_keys;'); + $db->sql_query('INSERT INTO '.table_prefix.'session_keys( session_key,salt,user_id,auth_level,source_ip,time ) VALUES( \''.$ra->session_key.'\', \''.$ra->salt.'\', \''.$session->user_id.'\', \''.$ra->auth_level.'\', \''.$ra->source_ip.'\', '.$ra->time.' ),( \''.$rb->session_key.'\', \''.$rb->salt.'\', \''.$session->user_id.'\', \''.$rb->auth_level.'\', \''.$rb->source_ip.'\', '.$rb->time.' )'); + echo(' +
The session key table has been cleared. Your database should be a little bit smaller now.
+ '); + } } echo('

User Management

@@ -1767,7 +1827,7 @@ $e = $db->sql_query('DELETE FROM '.table_prefix.'banlist WHERE ban_id=' . $db->escape($_GET['id']) . ''); if(!$e) $db->_die('The ban list entry was not deleted.'); } - if(isset($_POST['create'])) + if(isset($_POST['create']) && !defined('ENANO_DEMO_MODE')) { $q = 'INSERT INTO '.table_prefix.'banlist(ban_type,ban_value,reason,is_regex) VALUES( ' . $db->escape($_POST['type']) . ', \'' . $db->escape($_POST['value']) . '\', \''.$db->escape($_POST['reason']).'\''; if(isset($_POST['regex'])) $q .= ', 1'; @@ -1776,6 +1836,10 @@ $e = $db->sql_query($q); if(!$e) $db->_die('The banlist could not be updated.'); } + else if ( isset($_POST['create']) && defined('ENANO_DEMO_MODE') ) + { + echo '
This function is disabled in the demo. Just because you don\'t like ' . htmlspecialchars($_POST['value']) . ' doesn\'t mean we don\'t like ' . htmlspecialchars($_POST['value']) . '.
'; + } $q = $db->sql_query('SELECT ban_id,ban_type,ban_value,is_regex FROM '.table_prefix.'banlist ORDER BY ban_type;'); if(!$q) $db->_die('The banlist data could not be selected.'); echo ''; @@ -1813,7 +1877,7 @@ } global $enano_config; - if ( isset($_POST['do_send']) ) + if ( isset($_POST['do_send']) && !defined('ENANO_DEMO_MODE') ) { $use_smtp = getConfig('smtp_enabled') == '1'; @@ -1952,6 +2016,10 @@ } } + else if ( isset($_POST['do_send']) && defined('ENANO_DEMO_MODE') ) + { + echo '
This function is disabled in the demo. You think demo@enanocms.org likes getting "test" mass e-mails?
'; + } echo ''; ?>
@@ -2024,6 +2092,11 @@ return; } + if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes' && defined('ENANO_DEMO_MODE') ) + { + redirect(makeUrlComplete('Special', 'Administration'), 'Access denied', 'You\'ve got to be kidding me. Forget it, kid.', 4 ); + } + global $system_table_list; if(isset($_GET['submitting']) && $_GET['submitting'] == 'yes') { @@ -2358,6 +2431,20 @@ $content = $_POST['plugin_id']; break; } + + if ( defined('ENANO_DEMO_MODE') ) + { + // Sanitize the HTML + $content = sanitize_html($content, true); + } + + if ( defined('ENANO_DEMO_MODE') && intval($_POST['type']) == BLOCK_PHP ) + { + echo '
Adding PHP code blocks in the Enano administration demo has been disabled for security reasons.
'; + $_POST['php_content'] = '?><Nulled>'; + $content = $_POST['php_content']; + } + // Get the value of item_order $q = $db->sql_query('SELECT * FROM '.table_prefix.'sidebar WHERE sidebar_id='.$db->escape($_POST['sidebar_id']).';'); @@ -2457,6 +2544,9 @@
+ +

Creating PHP blocks in demo mode is disabled for security reasons.

+

WARNING: If you don't know what you're doing, or if you are not fluent in PHP, stop now and choose a different block type. You will brick your Enano installation if you are not careful here. ALWAYS remember to write secure code! The Enano team is not responsible if someone drops all your tables because of an SQL injection vulnerability in your sidebar code. You are probably better off using the template-formatted block type. @@ -2478,6 +2568,7 @@

+
@@ -2586,6 +2677,24 @@ die($r['block_content']); break; case 'save': + if ( defined('ENANO_DEMO_MODE') ) + { + $q = $db->sql_query('SELECT block_type FROM '.table_prefix.'sidebar WHERE item_id=' . $db->escape($_GET['id']) . ';'); + if(!$q) + { + echo 'var status=unescape(\''.hexencode($db->get_error()).'\');'; + exit; + } + $row = $db->fetchrow(); + if ( $row['block_type'] == BLOCK_PHP ) + { + $_POST['content'] = '?><Nulled>'; + } + else + { + $_POST['content'] = sanitize_html($_POST['content'], true); + } + } $q = $db->sql_query('UPDATE '.table_prefix.'sidebar SET block_content=\''.$db->escape(rawurldecode($_POST['content'])).'\' WHERE item_id=' . $db->escape($_GET['id']) . ';'); if(!$q) { diff -r edfc24408769 -r 5d003b6c9e89 schema.sql --- a/schema.sql Sat Jun 23 10:38:24 2007 -0400 +++ b/schema.sql Sat Jun 23 18:54:16 2007 -0400 @@ -15,7 +15,7 @@ CREATE TABLE {{TABLE_PREFIX}}sidebar( item_id smallint(3) NOT NULL auto_increment, item_order smallint(3) NOT NULL DEFAULT 0, item_enabled tinyint(1) NOT NULL DEFAULT 1, sidebar_id smallint(3) NOT NULL DEFAULT 1, block_name varchar(63) NOT NULL, block_type tinyint(1) NOT NULL DEFAULT 0, block_content text, PRIMARY KEY ( item_id )); CREATE TABLE {{TABLE_PREFIX}}hits( hit_id bigint(20) NOT NULL auto_increment, username varchar(63) NOT NULL, time int(12) NOT NULL DEFAULT 0, page_id varchar(63), namespace varchar(63), PRIMARY KEY ( hit_id ) ); CREATE TABLE {{TABLE_PREFIX}}search_index( word varbinary(64) NOT NULL, page_names text, PRIMARY KEY ( word ) ); -CREATE TABLE {{TABLE_PREFIX}}groups( group_id mediumint(5) UNSIGNED NOT NULL auto_increment, group_name varchar(64), group_type tinyint(1) NOT NULL DEFAULT 1, PRIMARY KEY ( group_id ) ); +CREATE TABLE {{TABLE_PREFIX}}groups( group_id mediumint(5) UNSIGNED NOT NULL auto_increment, group_name varchar(64), group_type tinyint(1) NOT NULL DEFAULT 1, PRIMARY KEY ( group_id ), system_group tinyint(1) NOT NULL DEFAULT 0 ); CREATE TABLE {{TABLE_PREFIX}}group_members( member_id int(12) UNSIGNED NOT NULL auto_increment, group_id mediumint(5) UNSIGNED NOT NULL, user_id int(12) NOT NULL, is_mod tinyint(1) NOT NULL DEFAULT 0, pending tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY ( member_id ) ); CREATE TABLE {{TABLE_PREFIX}}acl( rule_id int(12) UNSIGNED NOT NULL auto_increment, target_type tinyint(1) UNSIGNED NOT NULL, target_id int(12) UNSIGNED NOT NULL, page_id varchar(255), namespace varchar(24), rules text, PRIMARY KEY ( rule_id ) ); CREATE TABLE {{TABLE_PREFIX}}search_cache( search_id int(15) NOT NULL auto_increment, search_time int(11) NOT NULL, query text, results longblob, PRIMARY KEY ( search_id )); @@ -25,7 +25,7 @@ INSERT INTO {{TABLE_PREFIX}}themes(theme_id, theme_name, theme_order, default_style, enabled) VALUES ('oxygen', 'Oxygen', 2, 'bleu.css', 1),('stpatty', 'St. Patty', 1, 'shamrock.css', 1); INSERT INTO {{TABLE_PREFIX}}users(user_id, username, password, email, real_name, user_level, theme, style, signature, reg_time) VALUES(1, 'Anonymous', 'invalid-pass-hash', 'anonspam@enanocms.org', 'None', 1, 'stpatty', 'shamrock', '', 0); INSERT INTO {{TABLE_PREFIX}}users(user_id, username, password, email, real_name, user_level, theme, style, account_active, reg_time) VALUES (2, '{{ADMIN_USER}}', '{{ADMIN_PASS}}', '{{ADMIN_EMAIL}}', '{{REAL_NAME}}', 9, 'stpatty', 'shamrock', 1, UNIX_TIMESTAMP()); -INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type) VALUES(1, 'Everyone', 3),(2,'Administrators',3),(3,'Moderators',3); +INSERT INTO {{TABLE_PREFIX}}groups(group_id,group_name,group_type,system_group) VALUES(1, 'Everyone', 3, 1),(2,'Administrators',3,1),(3,'Moderators',3,1); INSERT INTO {{TABLE_PREFIX}}group_members(group_id,user_id,is_mod) VALUES(2, 2, 1); INSERT INTO {{TABLE_PREFIX}}acl(target_type,target_id,page_id,namespace,rules) VALUES(1,2,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=4;clear_logs=4;vote_delete=4;vote_reset=4;delete_page=4;set_wiki_mode=4;password_set=4;password_reset=4;mod_misc=4;edit_cat=4;even_when_protected=4;upload_files=4;upload_new_version=4;create_page=4;php_in_pages={{ADMIN_EMBED_PHP}};edit_acl=4;'),(1,3,NULL,NULL,'read=4;post_comments=4;edit_comments=4;edit_page=4;view_source=4;mod_comments=4;history_view=4;history_rollback=4;history_rollback_extra=4;protect=4;rename=3;clear_logs=2;vote_delete=4;vote_reset=4;delete_page=4;set_wiki_mode=2;password_set=2;password_reset=2;mod_misc=2;edit_cat=4;even_when_protected=4;upload_files=2;upload_new_version=3;create_page=3;php_in_pages=2;edit_acl=2;'); INSERT INTO {{TABLE_PREFIX}}sidebar(item_id, item_order, sidebar_id, block_name, block_type, block_content) VALUES (1, 1, 1, 'Navigation', 1, '[[Main Page|Home]]'),(2, 2, 1, 'Tools', 1, '[[$NS_SPECIAL$CreatePage|Create a page]]\n[[$NS_SPECIAL$UploadFile|Upload file]]\n[[$NS_SPECIAL$SpecialPages|Special pages]]\n{if auth_admin}\n[[$NS_SPECIAL$EditSidebar|Edit the sidebar]]\n[[$NS_SPECIAL$Administration|Administration]]\n{/if}'),(3, 3, 1, '$USERNAME$', 1, '[[$NS_USER$$USERNAME$|User page]]\n[[$NS_SPECIAL$Contributions/$USERNAME$|My Contributions]]\n{if user_logged_in}\n[[$NS_SPECIAL$Preferences|Preferences]]\n[[$NS_SPECIAL$PrivateMessages|Private messages]]\n[[$NS_SPECIAL$Usergroups|Group control panel]]\n$THEME_LINK$\n{/if}\n{if user_logged_in}\n$LOGOUT_LINK$\n{else}\n[[$NS_SPECIAL$Register|Create an account]]\n$LOGIN_LINK$\n[[$NS_SPECIAL$Login/$NS_SPECIAL$PrivateMessages|Private messages]]\n{/if}'),(4, 4, 1, 'Search', 1, '

'),(5, 2, 2, 'Links', 4, 'Links') \ No newline at end of file