# HG changeset patch
# User Dan
# Date 1188175533 14400
# Node ID a8891e108c95ba26d90d493550149af5b8ac215c
# Parent d807dcd7aed74577e99bf46124174c427cdd557b
Several major improvements: Memberlist page added (planned since about beta 2), page group support added for non-JS ACL editor (oops!), and attempting to view a page for which you lack read permissions will get you logged.
diff -r d807dcd7aed7 -r a8891e108c95 includes/clientside/static/ajax.js
--- a/includes/clientside/static/ajax.js Sun Aug 26 16:48:15 2007 -0400
+++ b/includes/clientside/static/ajax.js Sun Aug 26 20:45:33 2007 -0400
@@ -812,6 +812,28 @@
window.location = loc;
}
+function ajaxAdminUser(username)
+{
+ // IE <6 pseudo-compatibility
+ if ( KILL_SWITCH )
+ return true;
+ if ( auth_level < USER_LEVEL_ADMIN )
+ {
+ ajaxPromptAdminAuth(function(k) {
+ ENANO_SID = k;
+ auth_level = USER_LEVEL_ADMIN;
+ var loc = String(window.location + '');
+ window.location = append_sid(loc);
+ var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'UserManager&src=get&user=' + ajaxEscape(username));
+ if ( (ENANO_SID + ' ').length > 1 )
+ window.location = loc;
+ }, 9);
+ return false;
+ }
+ var loc = makeUrlNS('Special', 'Administration', 'module=' + namespace_list['Admin'] + 'UserManager&src=get&user=' + ajaxEscape(username));
+ window.location = loc;
+}
+
function ajaxDisableEmbeddedPHP()
{
// IE <6 pseudo-compatibility
diff -r d807dcd7aed7 -r a8891e108c95 includes/pageprocess.php
--- a/includes/pageprocess.php Sun Aug 26 16:48:15 2007 -0400
+++ b/includes/pageprocess.php Sun Aug 26 20:45:33 2007 -0400
@@ -969,14 +969,39 @@
{
global $db, $session, $paths, $template, $plugins; // Common objects
+ // Log it for crying out loud
+ $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES(\'security\', \'illegal_page\', '.time().', \''.date('d M Y h:i a').'\', \''.$db->escape($session->username).'\', \''.$db->escape($_SERVER['REMOTE_ADDR']).'\', \'' . $db->escape(serialize(array($this->page_id, $this->namespace))) . '\')');
+
$ob = '';
- $template->tpl_strings['PAGE_NAME'] = 'Access denied';
+ //$template->tpl_strings['PAGE_NAME'] = 'Access denied';
+ $template->tpl_strings['PAGE_NAME'] = htmlspecialchars( $this->title );
if ( $this->send_headers )
{
$ob .= $template->getHeader();
}
+ if ( count($this->redirect_stack) > 0 )
+ {
+ $stack = array_reverse($this->redirect_stack);
+ foreach ( $stack as $oldtarget )
+ {
+ $url = makeUrlNS($oldtarget[1], $oldtarget[0], 'redirect=no', true);
+ $page_id_key = $paths->nslist[ $oldtarget[1] ] . $oldtarget[0];
+ $page_data = $paths->pages[$page_id_key];
+ $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$oldtarget[1]] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $oldtarget[0] ) ) );
+ $a = '' . $title . '';
+
+ $url = makeUrlNS($this->namespace, $this->page_id, 'redirect=no', true);
+ $page_id_key = $paths->nslist[ $this->namespace ] . $this->page_id;
+ $page_data = $paths->pages[$page_id_key];
+ $title = ( isset($page_data['name']) ) ? $page_data['name'] : $paths->nslist[$this->namespace] . htmlspecialchars( str_replace('_', ' ', dirtify_page_id( $this->page_id ) ) );
+ $b = '' . $title . '';
+
+ $ob .= '(Redirected to ' . $b . ' from ' . $a . ')
';
+ }
+ }
+
$ob .= '
Access to this page is denied.
This may be because you are not logged in or you have not met certain criteria for viewing this page.
';
if ( $this->send_headers )
diff -r d807dcd7aed7 -r a8891e108c95 includes/pageutils.php
--- a/includes/pageutils.php Sun Aug 26 16:48:15 2007 -0400
+++ b/includes/pageutils.php Sun Aug 26 20:45:33 2007 -0400
@@ -1943,11 +1943,25 @@
{
echo '';
}
+ // page group selector
+ $groupsel = '';
+ if ( count($response['page_groups']) > 0 )
+ {
+ $groupsel = '
+ ';
+ }
+
echo '
' . $template->username_field('data[target_id_user]') . '
What should this access rule control?
+ ' . $groupsel . '
@@ -1999,7 +2013,7 @@
echo '
Create new rule
';
}
$type = ( $response['target_type'] == ACL_TYPE_GROUP ) ? 'group' : 'user';
- $scope = ( $response['page_id'] ) ? 'this page' : 'this entire site';
+ $scope = ( $response['page_id'] ) ? ( $response['namespace'] == '__PageGroup' ? 'this group of pages' : 'this page' ) : 'this entire site';
echo 'This panel allows you to edit what the '.$type.' "'.$response['target_name'].'" can do on '.$scope.'. Unless you set a permission to "Deny", these permissions may be overridden by other rules.';
echo $formstart;
$parser = $template->makeParserText( $response['template']['acl_field_begin'] );
@@ -2047,7 +2061,7 @@
-
+ ' . ( ( $response['type'] == 'edit' ) ? ' ' : '' ) . '
';
echo $formend;
break;
@@ -2097,6 +2111,11 @@
$parms['page_id'] = false;
$parms['namespace'] = false;
}
+ else if ( $parms['scope'] == 'page_group' )
+ {
+ $parms['page_id'] = $parms['pg_id'];
+ $parms['namespace'] = '__PageGroup';
+ }
break;
}
diff -r d807dcd7aed7 -r a8891e108c95 index.php
--- a/index.php Sun Aug 26 16:48:15 2007 -0400
+++ b/index.php Sun Aug 26 20:45:33 2007 -0400
@@ -15,7 +15,7 @@
// Set up gzip encoding before any output is sent
- $aggressive_optimize_html = false;
+ $aggressive_optimize_html = true;
global $do_gzip;
$do_gzip = true;
diff -r d807dcd7aed7 -r a8891e108c95 plugins/SpecialAdmin.php
--- a/plugins/SpecialAdmin.php Sun Aug 26 16:48:15 2007 -0400
+++ b/plugins/SpecialAdmin.php Sun Aug 26 20:45:33 2007 -0400
@@ -128,10 +128,19 @@
$q = $db->sql_query($l);
while($r = $db->fetchrow())
{
+ if ( $r['action'] == 'illegal_page' )
+ {
+ list($illegal_id, $illegal_ns) = unserialize($r['page_text']);
+ $url = makeUrlNS($illegal_ns, $illegal_id, false, true);
+ $title = get_page_title_ns($illegal_id, $illegal_ns);
+ $class = ( isPage($paths->nslist[$illegal_ns] . $illegal_id) ) ? '' : ' class="wikilink-nonexistent"';
+ $illegal_link = '' . $title . '';
+ }
if($cls == 'row2') $cls = 'row1';
else $cls = 'row2';
echo '';
- switch($r['action']) {
+ switch($r['action'])
+ {
case "admin_auth_good": echo 'Successful elevated authentication'; if ( !empty($r['page_text']) ) { $level = $session->userlevel_to_string( intval($r['page_text']) ); echo " Authentication level: $level"; } break;
case "admin_auth_bad": echo 'Failed elevated authentication'; if ( !empty($r['page_text']) ) { $level = $session->userlevel_to_string( intval($r['page_text']) ); echo " Attempted auth level: $level"; } break;
case "activ_good": echo 'Successful account activation'; break;
@@ -142,6 +151,7 @@
case "db_backup": echo 'Database backup created Tables: ' . $r['page_text'] . ''; break;
case "install_enano": echo "Installed Enano version {$r['page_text']}"; break;
case "upgrade_enano": echo "Upgraded Enano to version {$r['page_text']}"; break;
+ case "illegal_page": echo "Unauthorized viewing attempt Page: {$illegal_link}"; break;
}
echo ' | '.date('d M Y h:i a', $r['time_id']).' | '.$r['author'].' | '.$r['edit_summary'].' |
';
}
@@ -790,6 +800,12 @@
return;
}
+ if ( isset($_GET['src']) && $_GET['src'] == 'get' && !empty($_GET['user']) )
+ {
+ $_POST['go'] = true;
+ $_POST['username'] = $_GET['user'];
+ }
+
if(isset($_POST['go']))
{
// We need the user ID before we can do anything
@@ -2312,7 +2328,7 @@
@set_time_limit(300); // five minutes
// Do the actual export
$aesext = ( defined('SQL_BACKUP_CRYPT') ) ? '.tea' : '';
- $filename = 'enano_backup_' . date('dmy') . '.sql' . $aesext;
+ $filename = 'enano_backup_' . date('ymd') . '.sql' . $aesext;
ob_start();
header('Content-disposition: attachment, filename="'.$filename.'";');
header('Content-type: application/transact-sql');
@@ -2342,6 +2358,7 @@
}
foreach($tables as $t)
{
+ // THE FOLLOWING COMMENT DOES NOT APPLY AS OF 1.0.
// Sorry folks - this script CAN'T backup enano_files, enano_search_index, and enano_search_cache due to the sheer size of the tables.
// If encryption is enabled the log data will be excluded too.
echo export_table(
diff -r d807dcd7aed7 -r a8891e108c95 plugins/SpecialUserFuncs.php
--- a/plugins/SpecialUserFuncs.php Sun Aug 26 16:48:15 2007 -0400
+++ b/plugins/SpecialUserFuncs.php Sun Aug 26 20:45:33 2007 -0400
@@ -83,6 +83,13 @@
\'namespace\'=>\'Special\',
\'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
));
+
+ $paths->add_page(Array(
+ \'name\'=>\'Member list\',
+ \'urlname\'=>\'Memberlist\',
+ \'namespace\'=>\'Special\',
+ \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\',
+ ));
');
// function names are IMPORTANT!!! The name pattern is: page__
@@ -1066,4 +1073,185 @@
$template->footer();
}
+function page_Special_Memberlist()
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $template->header();
+
+ $startletters = 'abcdefghijklmnopqrstuvwxyz';
+ $startletters = enano_str_split($startletters);
+ $startletter = ( isset($_GET['letter']) ) ? strtolower($_GET['letter']) : '';
+ if ( !in_array($startletter, $startletters) && $startletter != 'chr' )
+ {
+ $startletter = '';
+ }
+
+ $startletter_sql = $startletter;
+ if ( $startletter == 'chr' )
+ {
+ $startletter_sql = '([^a-z])';
+ }
+
+ // determine number of rows
+ $q = $db->sql_query('SELECT u.user_id FROM '.table_prefix.'users AS u WHERE u.username REGEXP "^' . $startletter_sql . '" AND u.username != "Anonymous";');
+ if ( !$q )
+ $db->_die();
+
+ $num_rows = $db->numrows();
+ $db->free_result();
+
+ // offset
+ $offset = ( isset($_GET['offset']) && strval(intval($_GET['offset'])) === $_GET['offset']) ? intval($_GET['offset']) : 0;
+
+ // sort order
+ $sortkeys = array(
+ 'uid' => 'u.user_id',
+ 'username' => 'u.username',
+ 'email' => 'u.email'
+ );
+
+ $sortby = ( isset($_GET['sort']) && isset($sortkeys[$_GET['sort']]) ) ? $_GET['sort'] : 'username';
+ $sort_sqllet = $sortkeys[$sortby];
+
+ $target_order = ( isset($_GET['orderby']) && in_array($_GET['orderby'], array('ASC', 'DESC')) )? $_GET['orderby'] : 'ASC';
+
+ $sortorders = array();
+ foreach ( $sortkeys as $k => $_unused )
+ {
+ $sortorders[$k] = ( $sortby == $k ) ? ( $target_order == 'ASC' ? 'DESC' : 'ASC' ) : 'ASC';
+ }
+
+ // Why 3.3714%? 100 percent / 28 cells, minus a little (0.2% / cell) to account for cell spacing
+
+ echo '';
+
+ // formatter parameters
+ $formatter = new MemberlistFormatter();
+ $formatters = array(
+ 'username' => array($formatter, 'username'),
+ 'user_level' => array($formatter, 'user_level'),
+ 'email' => array($formatter, 'email')
+ );
+
+ // Column markers
+ $headings = '
+
+ #
+ |
+
+ Username
+ |
+
+ E-mail
+ |
+
';
+
+ $q = $db->sql_unbuffered_query('SELECT u.user_id, u.username, u.reg_time, u.email, u.user_level, x.email_public FROM '.table_prefix.'users AS u
+ LEFT JOIN '.table_prefix.'users_extra AS x
+ ON ( u.user_id = x.user_id )
+ WHERE u.username REGEXP "^' . $startletter_sql . '" AND u.username != "Anonymous"
+ ORDER BY ' . $sort_sqllet . ' ' . $target_order . ';');
+ if ( !$q )
+ $db->_die();
+
+ $html = paginate(
+ $q, // MySQL result resource
+ '
+ {user_id} |
+ {username} {user_level} |
+ {email} |
+
+ ', // TPL code for rows
+ $num_rows, // Number of results
+ makeUrlNS('Special', 'Memberlist', 'letter=' . $startletter . '&offset=%s&sort=' . $sortby . '&orderby=' . $target_order ), // Result URL
+ $offset, // Start at this number
+ 25, // Results per page
+ $formatters, // Formatting hooks
+ '
+
+ ' . $headings . '
+ ', // Header (printed before rows)
+ ' ' . $headings . '
+
+
+ ' // Footer (printed after rows)
+ );
+
+ if ( $num_rows < 1 )
+ {
+ echo 'Sorry - no users with usernames that start with that letter could be found.
';
+ }
+ else
+ {
+ echo $html;
+ }
+
+ $template->footer();
+}
+
+/**
+ * Class for formatting results for the memberlist.
+ * @access private
+ */
+
+class MemberlistFormatter
+{
+ function username($username, $row)
+ {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ $userpage = $paths->nslist['User'] . sanitize_page_id($username);
+ $class = ( isPage($userpage) ) ? ' title="Click to view this user\'s userpage"' : ' class="wikilink-nonexistent" title="This user hasn\'t created a userpage yet, but you can still view profile details by clicking this link."';
+ $anchor = '' . htmlspecialchars($username) . '';
+ if ( $session->user_level >= USER_LEVEL_ADMIN )
+ {
+ $anchor .= ' - Administer user';
+ }
+ return $anchor;
+ }
+ function user_level($level, $row)
+ {
+ global $db, $session, $paths, $template, $plugins; // Common objects
+ switch ( $level )
+ {
+ case USER_LEVEL_GUEST:
+ $s_level = 'Guest'; break;
+ case USER_LEVEL_MEMBER:
+ case USER_LEVEL_CHPREF:
+ $s_level = 'Member'; break;
+ case USER_LEVEL_MOD:
+ $s_level = 'Moderator'; break;
+ case USER_LEVEL_ADMIN:
+ $s_level = 'Site administrator'; break;
+ default:
+ $s_level = 'Unknown (level ' . $level . ')';
+ }
+ return $s_level;
+ }
+ function email($addy, $row)
+ {
+ if ( $row['email_public'] == '1' )
+ {
+ global $email;
+ $addy = $email->encryptEmail($addy);
+ return $addy;
+ }
+ else
+ {
+ return '<Non-public>';
+ }
+ }
+}
+
?>
\ No newline at end of file
diff -r d807dcd7aed7 -r a8891e108c95 plugins/SpecialUserPrefs.php
--- a/plugins/SpecialUserPrefs.php Sun Aug 26 16:48:15 2007 -0400
+++ b/plugins/SpecialUserPrefs.php Sun Aug 26 20:45:33 2007 -0400
@@ -41,6 +41,28 @@
}
}
+$plugins->attachHook('compile_template', 'userprefs_jbox_setup($button, $tb, $menubtn);');
+
+function userprefs_jbox_setup(&$button, &$tb, &$menubtn)
+{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
+ if ( $paths->namespace != 'Special' || $paths->cpage['urlname_nons'] != 'Preferences' )
+ return false;
+
+ $tb .= "";
+ $template->toolbar_menu = '';
+
+ $button->assign_vars(array(
+ 'TEXT' => 'list of registered members',
+ 'FLAGS' => '',
+ 'PARENTFLAGS' => '',
+ 'HREF' => makeUrlNS('Special', 'Memberlist')
+ ));
+
+ $tb .= $button->run();
+}
+
function userprefs_menu_html()
{
global $userprefs_menu;
diff -r d807dcd7aed7 -r a8891e108c95 themes/oxygen/css/bleu.css
--- a/themes/oxygen/css/bleu.css Sun Aug 26 16:48:15 2007 -0400
+++ b/themes/oxygen/css/bleu.css Sun Aug 26 20:45:33 2007 -0400
@@ -71,6 +71,16 @@
div.tblholder th.subhead { padding: 4px; background-color: #90A0B0; font-weight: bold; text-align: center; color: #FFFFFF; }
div.tblholder table { background-color: #FFFFFF; width: 100%; }
+div.tblholder th a {
+ color: #FFFFFF !important;
+ text-decoration: underline !important;
+}
+
+div.tblholder th a:hover {
+ color: #FFFF00 !important;
+ text-decoration: underline !important;
+}
+
/* The "page tools" bar below the site logo but above the page content
div.pagebar { background-color: #B0D0F0; margin-top: 0px; padding: 3px; font-size: 7pt; }
div.pagebar a { cursor: pointer; padding: 3px; margin-left: 3px; margin-right: 3px; text-decoration: none; color: #406080; }
@@ -222,6 +232,7 @@
input[type ^="button"], input[type ^="submit"] {
background-image: url(../images/buttonbg.gif);
background-repeat: repeat-x;
+ color: #202020;
}
/* JWS window theming */