plugins/admin/UserManager.php
changeset 140 40f7fa5fd061
child 141 13a43f08ffe1
equal deleted inserted replaced
139:070ff1509cc2 140:40f7fa5fd061
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
       
     5  * Version 1.0.1 (Loch Ness)
       
     6  * Copyright (C) 2006-2007 Dan Fuhry
       
     7  *
       
     8  * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
       
     9  * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
       
    10  *
       
    11  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
       
    12  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
       
    13  */
       
    14 
       
    15 function page_Admin_UserManager()
       
    16 {
       
    17   global $db, $session, $paths, $template, $plugins; // Common objects
       
    18   if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
       
    19   {
       
    20     echo '<h3>Error: Not authenticated</h3><p>It looks like your administration session is invalid or you are not authorized to access this administration page. Please <a href="' . makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true) . '">re-authenticate</a> to continue.</p>';
       
    21     return;
       
    22   }
       
    23   
       
    24   //die('<pre>' . htmlspecialchars(print_r($_POST, true)) . '</pre>');
       
    25   
       
    26   if ( isset($_POST['action']['save']) )
       
    27   {
       
    28     #
       
    29     # BEGIN VALIDATION
       
    30     #
       
    31     
       
    32     $errors = array();
       
    33     $user_id = intval($_POST['user_id']);
       
    34     if ( empty($user_id) )
       
    35       $errors[] = 'Invalid user ID.';
       
    36     
       
    37     if ( isset($_POST['delete_account']) )
       
    38     {
       
    39       $q = $db->sql_query('DELETE FROM '.table_prefix."users_extra WHERE user_id=$user_id;");
       
    40       if ( !$q )
       
    41         $db->_die();
       
    42       $q = $db->sql_query('DELETE FROM '.table_prefix."users WHERE user_id=$user_id;");
       
    43       if ( !$q )
       
    44         $db->_die();
       
    45       echo '<div class="info-box">The user account has been deleted.</div>';
       
    46     }
       
    47     else
       
    48     {
       
    49       if ( $session->user_id != $user_id )
       
    50       {
       
    51         $username = $_POST['username'];
       
    52         if ( !preg_match('#^'.$session->valid_username.'$#', $username) )
       
    53           $errors[] = 'The username you entered contains invalid characters.';
       
    54         
       
    55         $password = false;
       
    56         if ( $_POST['changing_pw'] == 'yes' )
       
    57         {
       
    58           $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
       
    59           $key_hex_md5 = $_POST['crypt_key'];
       
    60           $key_hex = $session->fetch_public_key($key_hex_md5);
       
    61           if ( $key_hex )
       
    62           {
       
    63             $key_bin = hexdecode($key_hex);
       
    64             $data_hex = $_POST['crypt_data'];
       
    65             $password = $aes->decrypt($data_hex, $key_bin, ENC_HEX);
       
    66           }
       
    67           else
       
    68           {
       
    69             $errors[] = 'Session manager denied public encryption key lookup request';
       
    70           }
       
    71         }
       
    72         
       
    73         $email = $_POST['email'];
       
    74         if ( !preg_match('/^(?:[\w\d]+\.?)+@((?:(?:[\w\d]\-?)+\.)+\w{2,4}|localhost)$/', $email) )
       
    75           $errors[] = 'You have entered an invalid e-mail address.';
       
    76         
       
    77         $real_name = $_POST['real_name'];
       
    78       }
       
    79       
       
    80       $signature = RenderMan::preprocess_text($_POST['signature'], true, true);
       
    81       
       
    82       $user_level = intval($_POST['user_level']);
       
    83       if ( $user_level < USER_LEVEL_MEMBER || $user_level > USER_LEVEL_ADMIN )
       
    84         $errors[] = 'Invalid user level';
       
    85       
       
    86       $imaddr_aim = htmlspecialchars($_POST['imaddr_aim']);
       
    87       $imaddr_msn = htmlspecialchars($_POST['imaddr_msn']);
       
    88       $imaddr_yahoo = htmlspecialchars($_POST['imaddr_yahoo']);
       
    89       $imaddr_xmpp = htmlspecialchars($_POST['imaddr_xmpp']);
       
    90       $homepage = htmlspecialchars($_POST['homepage']);
       
    91       $location = htmlspecialchars($_POST['location']);
       
    92       $occupation = htmlspecialchars($_POST['occupation']);
       
    93       $hobbies = htmlspecialchars($_POST['hobbies']);
       
    94       $email_public = ( isset($_POST['email_public']) ) ? '1' : '0';
       
    95       
       
    96       if ( !preg_match('/@([a-z0-9-]+)(\.([a-z0-9-\.]+))?/', $imaddr_msn) && !empty($imaddr_msn) )
       
    97       {
       
    98         $imaddr_msn = "$imaddr_msn@hotmail.com";
       
    99       }
       
   100       
       
   101       if ( substr($homepage, 0, 7) != 'http://' )
       
   102       {
       
   103         $homepage = "http://$homepage";
       
   104       }
       
   105       
       
   106       if ( !preg_match('/^http:\/\/([a-z0-9-.]+)([A-z0-9@#\$%\&:;<>,\.\?=\+\(\)\[\]_\/\\\\]*?)$/i', $homepage) )
       
   107       {
       
   108         $homepage = '';
       
   109       }
       
   110       
       
   111       if ( count($errors) > 0 )
       
   112       {
       
   113         echo '<div class="error-box">
       
   114                 <b>Your request could not be processed due to the following validation errors:</b>
       
   115                 <ul>
       
   116                   <li>' . implode("</li>\n        <li>", $errors) . '</li>
       
   117                 </ul>
       
   118               </div>';
       
   119         $form = new Admin_UserManager_SmartForm();
       
   120         $form->user_id = $user_id;
       
   121         $form->username = $username;
       
   122         $form->email = $email;
       
   123         $form->real_name = $real_name;
       
   124         $form->signature = $signature;
       
   125         $form->user_level = $user_level;
       
   126         $form->im = array(
       
   127             'aim' => $imaddr_aim,
       
   128             'yahoo' => $imaddr_yahoo,
       
   129             'msn' => $imaddr_msn,
       
   130             'xmpp' => $imaddr_xmpp
       
   131           );
       
   132         $form->contact = array(
       
   133             'homepage' => $homepage,
       
   134             'location' => $location,
       
   135             'job' => $occupation,
       
   136             'hobbies' => $hobbies
       
   137           );
       
   138         $form->email_public = ( isset($_POST['email_public']) );
       
   139         $form->account_active = ( isset($_POST['account_active']) );
       
   140         echo $form->render();
       
   141         return false;
       
   142       }
       
   143       else
       
   144       {
       
   145         $q = $db->sql_query('SELECT u.user_level FROM '.table_prefix.'users AS u WHERE u.user_id = ' . $user_id . ';');
       
   146         if ( !$q )
       
   147           $db->_die();
       
   148         
       
   149         if ( $db->numrows() < 1 )
       
   150         {
       
   151           echo 'Couldn\'t select user data: no rows returned';
       
   152         }
       
   153         
       
   154         $row = $db->fetchrow();
       
   155         $existing_level =& $row['user_level'];
       
   156         $db->free_result();
       
   157       
       
   158         $to_update_users = array();
       
   159         if ( $user_id != $session->user_id )
       
   160         {
       
   161           $to_update_users['username'] = $username;
       
   162           if ( $password )
       
   163           {
       
   164             $password = $aes->encrypt($password, $session->private_key, ENC_HEX);
       
   165             $to_update_users['password'] = $password;
       
   166           }
       
   167           $to_update_users['email'] = $email;
       
   168           $to_update_users['real_name'] = $real_name;
       
   169         }
       
   170         $to_update_users['signature'] = $signature;
       
   171         $to_update_users['user_level'] = $user_level;
       
   172         
       
   173         if ( isset($_POST['account_active']) )
       
   174         {
       
   175           $to_update_users['account_active'] = "1";
       
   176         }
       
   177         else
       
   178         {
       
   179           $to_update_users['account_active'] = "0";
       
   180           $to_update_users['activation_key'] = sha1($session->dss_rand());
       
   181         }
       
   182         
       
   183         $to_update_users_extra = array();
       
   184         $to_update_users_extra['user_aim'] = $imaddr_aim;
       
   185         $to_update_users_extra['user_msn'] = $imaddr_msn;
       
   186         $to_update_users_extra['user_yahoo'] = $imaddr_yahoo;
       
   187         $to_update_users_extra['user_xmpp'] = $imaddr_xmpp;
       
   188         $to_update_users_extra['user_homepage'] = $homepage;
       
   189         $to_update_users_extra['user_location'] = $location;
       
   190         $to_update_users_extra['user_job'] = $occupation;
       
   191         $to_update_users_extra['user_hobbies'] = $hobbies;
       
   192         $to_update_users_extra['email_public'] = ( $email_public ) ? '1' : '0';
       
   193         
       
   194         $update_sql = '';
       
   195         
       
   196         foreach ( $to_update_users as $key => $unused_crap )
       
   197         {
       
   198           $value =& $to_update_users[$key];
       
   199           $value = $db->escape($value);
       
   200           $update_sql .= ( empty($update_sql) ? '' : ',' ) . "$key='$value'";
       
   201         }
       
   202         
       
   203         $update_sql = 'UPDATE '.table_prefix."users SET $update_sql WHERE user_id=$user_id;";
       
   204         
       
   205         $update_sql_extra = '';
       
   206         
       
   207         foreach ( $to_update_users_extra as $key => $unused_crap )
       
   208         {
       
   209           $value =& $to_update_users_extra[$key];
       
   210           $value = $db->escape($value);
       
   211           $update_sql_extra .= ( empty($update_sql_extra) ? '' : ',' ) . "$key='$value'";
       
   212         }
       
   213         
       
   214         $update_sql_extra = 'UPDATE '.table_prefix."users_extra SET $update_sql_extra WHERE user_id=$user_id;";
       
   215         
       
   216         if ( !$db->sql_query($update_sql) )
       
   217           $db->_die();
       
   218         
       
   219         if ( !$db->sql_query($update_sql_extra) )
       
   220           $db->_die();
       
   221         
       
   222         if ( $existing_level != $user_level )
       
   223         {
       
   224           // We need to update group memberships
       
   225           if ( $existing_level == USER_LEVEL_ADMIN ) 
       
   226           {
       
   227             $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_from_admin",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");');
       
   228             if ( !$q )
       
   229               $db->_die();
       
   230             $session->remove_user_from_group($user_id, GROUP_ID_ADMIN);
       
   231           }
       
   232           else if ( $existing_level == USER_LEVEL_MOD ) 
       
   233           {
       
   234             $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_from_mod",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");');
       
   235             if ( !$q )
       
   236               $db->_die();
       
   237             $session->remove_user_from_group($user_id, GROUP_ID_MOD);
       
   238           }
       
   239           
       
   240           if ( $user_level == USER_LEVEL_ADMIN )
       
   241           {
       
   242             $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_to_admin",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");');
       
   243             if ( !$q )
       
   244               $db->_die();
       
   245             $session->add_user_to_group($user_id, GROUP_ID_ADMIN, false);
       
   246           }
       
   247           else if ( $user_level == USER_LEVEL_MOD )
       
   248           {
       
   249             $q = $db->sql_query('INSERT INTO '.table_prefix.'logs(log_type,action,time_id,edit_summary,author,page_text) VALUES("security","u_to_mod",UNIX_TIMESTAMP(),"' . $db->escape($_SERVER['REMOTE_ADDR']) . '","' . $db->escape($session->username) . '","' . $db->escape($username) . '");');
       
   250             if ( !$q )
       
   251               $db->_die();
       
   252             $session->add_user_to_group($user_id, GROUP_ID_MOD, false);
       
   253           }
       
   254         }
       
   255         
       
   256         echo '<div class="info-box">Your changes have been saved.</div>';
       
   257       }
       
   258     }
       
   259     
       
   260     #
       
   261     # END VALIDATION
       
   262     #
       
   263   }
       
   264   else if ( isset($_POST['action']['go']) || ( isset($_GET['src']) && $_GET['src'] == 'get' ) )
       
   265   {
       
   266     if ( isset($_GET['user']) )
       
   267     {
       
   268       $username =& $_GET['user'];
       
   269     }
       
   270     else if ( isset($_POST['username']) )
       
   271     {
       
   272       $username =& $_POST['username'];
       
   273     }
       
   274     else
       
   275     {
       
   276       echo 'No username provided';
       
   277       return false;
       
   278     }
       
   279     $q = $db->sql_query('SELECT u.user_id AS authoritative_uid, u.username, u.email, u.real_name, u.signature, u.account_active, u.user_level, x.* FROM '.table_prefix.'users AS u
       
   280                            LEFT JOIN '.table_prefix.'users_extra AS x
       
   281                              ON ( u.user_id = x.user_id OR x.user_id IS NULL )
       
   282                            WHERE lcase(u.username) = \'' . $db->escape(strtolower($username)) . '\' OR u.username = \'' . $db->escape($username) . '\';');
       
   283     if ( !$q )
       
   284       $db->_die();
       
   285     
       
   286     if ( $db->numrows() < 1 )
       
   287     {
       
   288       echo '<div class="error-box">The username you entered could not be found.</div>';
       
   289     }
       
   290     else
       
   291     {
       
   292       $row = $db->fetchrow();
       
   293       $row['user_id'] = $row['authoritative_uid'];
       
   294       $form = new Admin_UserManager_SmartForm();
       
   295       $form->user_id   = $row['user_id'];
       
   296       $form->username  = $row['username'];
       
   297       $form->email     = $row['email'];
       
   298       $form->real_name = $row['real_name'];
       
   299       $form->signature = $row['signature'];
       
   300       $form->user_level= $row['user_level'];
       
   301       $form->account_active = ( $row['account_active'] == 1 );
       
   302       $form->email_public   = ( $row['email_public'] == 1 );
       
   303       $form->im = array(
       
   304           'aim' => $row['user_aim'],
       
   305           'yahoo' => $row['user_yahoo'],
       
   306           'msn' => $row['user_msn'],
       
   307           'xmpp' => $row['user_xmpp']
       
   308         );
       
   309       $form->contact = array(
       
   310           'homepage' => $row['user_homepage'],
       
   311           'location' => $row['user_location'],
       
   312           'job'      => $row['user_job'],
       
   313           'hobbies'  => $row['user_hobbies'],
       
   314         );
       
   315       $form->email_public = ( $row['email_public'] == 1 );
       
   316       $html = $form->render();
       
   317       if ( !$html )
       
   318       {
       
   319         echo 'Internal error: form processor returned false';
       
   320       }
       
   321       else
       
   322       {
       
   323         echo $html;
       
   324       }
       
   325       return true;
       
   326     }
       
   327   }
       
   328   else if ( isset($_POST['action']['clear_sessions']) )
       
   329   {
       
   330     if ( defined('ENANO_DEMO_MODE') )
       
   331     {
       
   332       echo '<div class="error-box">Sorry Charlie, no can do. You might mess up other people logged into the demo site.</div>';
       
   333     }
       
   334     else
       
   335     {
       
   336       // Get the current session information so the user doesn't get logged out
       
   337       $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
       
   338       $sk = md5(strrev($session->sid_super));
       
   339       $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);
       
   340       if ( !$qb )
       
   341       {
       
   342         die('Error selecting session key info block B: '.$db->get_error());
       
   343       }
       
   344       if ( $db->numrows($qb) < 1 )
       
   345       {
       
   346         die('Error: cannot read admin session info block B, aborting table clear process');
       
   347       }
       
   348       $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);
       
   349       if ( !$qa )
       
   350       {
       
   351         die('Error selecting session key info block A: '.$db->get_error());
       
   352       }
       
   353       if ( $db->numrows($qa) < 1 )
       
   354       {
       
   355         die('Error: cannot read user session info block A, aborting table clear process');
       
   356       }
       
   357       $ra = $db->fetchrow($qa);
       
   358       $rb = $db->fetchrow($qb);
       
   359       $db->free_result($qa);
       
   360       $db->free_result($qb);
       
   361       
       
   362       $db->sql_query('DELETE FROM '.table_prefix.'session_keys;');
       
   363       $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'].' )');
       
   364       
       
   365       echo '<div class="info-box">The session key table has been cleared. Your database should be a little bit smaller now.</div>';
       
   366     }
       
   367   }
       
   368   echo '<form action="' . makeUrlNS('Special', 'Administration', 'module=' . $paths->cpage['module'], true) . '" method="post" enctype="multipart/form-data" onsubmit="if ( !submitAuthorized ) return false;">';
       
   369   echo '<h3>User administration panel</h3>';
       
   370   echo '<p>From this panel you can modify or delete user accounts.</p>';
       
   371   echo '<table border="0">
       
   372           <tr>
       
   373             <td><b>Search for user:</b><br />
       
   374                 <small>If your browser supports AJAX, this will provide suggestions for you.</small>
       
   375                 </td>
       
   376             <td style="width: 10px;"></td>
       
   377             <td>' . $template->username_field('username') . '</td>
       
   378             <td>
       
   379               <input type="submit" name="action[go]" value="Go &raquo;" />
       
   380             </td>
       
   381           </tr>
       
   382         </table>';
       
   383   echo '<h3>Clear session key table</h3>';
       
   384   echo '<p>It\'s a good idea to clean out your session keys table every once in a while, since this helps to reduce database size. During this process you will be logged off and (hopefully) logged back on automatically. If you do this, all users besides you will be logged off, so be sure to do this at a time when traffic is low.</p>';
       
   385   echo '<p><input type="submit" name="action[clear_sessions]" value="Clear session keys" /></p>';
       
   386   echo '</form>';
       
   387   
       
   388   if(isset($_GET['action']) && isset($_GET['user']))
       
   389   {
       
   390     switch($_GET['action'])
       
   391     {
       
   392       case "activate":
       
   393         $e = $db->sql_query('SELECT activation_key FROM '.table_prefix.'users WHERE username=\'' . $db->escape($_GET['user']) . '\'');
       
   394         if($e)
       
   395         {
       
   396           $row = $db->fetchrow();
       
   397           $db->free_result();
       
   398           if($session->activate_account($_GET['user'], $row['activation_key'])) { echo '<div class="info-box">The user account "'.$_GET['user'].'" has been activated.</div>'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); }
       
   399           else echo '<div class="warning-box">The user account "'.$_GET['user'].'" has NOT been activated, possibly because the account is already active.</div>';
       
   400         } else echo '<div class="error-box">Error activating account: '.mysql_error().'</div>';
       
   401         break;
       
   402       case "sendemail":
       
   403         if($session->send_activation_mail($_GET['user'])) { echo '<div class="info-box">The user "'.$_GET['user'].'" has been sent an e-mail with an activation link.</div>'; $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE time_id=' . $db->escape($_GET['logid'])); }
       
   404         else echo '<div class="error-box">The user account "'.$_GET['user'].'" has not been activated, probably because of a bad SMTP configuration.</div>';
       
   405         break;
       
   406       case "deny":
       
   407         $e = $db->sql_query('DELETE FROM '.table_prefix.'logs WHERE log_type=\'admin\' AND action=\'activ_req\' AND edit_summary=\'' . $db->escape($_GET['user']) . '\';');
       
   408         if(!$e) echo '<div class="error-box">Error during row deletion: '.mysql_error().'</div>';
       
   409         else echo '<div class="info-box">All activation requests for the user "'.$_GET['user'].'" have been deleted.</div>';
       
   410         break;
       
   411     }
       
   412   }
       
   413   $q = $db->sql_query('SELECT l.log_type, l.action, l.time_id, l.date_string, l.author, l.edit_summary, u.user_coppa FROM '.table_prefix.'logs AS l
       
   414                          LEFT JOIN '.table_prefix.'users AS u
       
   415                            ON ( u.username = l.edit_summary OR u.username IS NULL )
       
   416                          WHERE log_type=\'admin\' AND action=\'activ_req\' ORDER BY time_id DESC;');
       
   417   if($q)
       
   418   {
       
   419     if($db->numrows() > 0)
       
   420     {
       
   421       $n = $db->numrows();
       
   422       if($n == 1) $s = $n . ' user is';
       
   423       else $s = $n . ' users are';
       
   424       echo '<h3>'.$s . ' awaiting account activation</h3>';
       
   425       echo '<div class="tblholder">
       
   426             <table border="0" cellspacing="1" cellpadding="4" width="100%">
       
   427             <tr><th>Date of request</th><th>Requested by</th><th>Requested for</th><th>COPPA user</th><th colspan="3">Actions</th></tr>';
       
   428       $cls = 'row2';
       
   429       while($row = $db->fetchrow())
       
   430       {
       
   431         if($cls == 'row2') $cls = 'row1';
       
   432         else $cls = 'row2';
       
   433         $coppa = ( $row['user_coppa'] == '1' ) ? '<b>Yes</b>' : 'No';
       
   434         echo '<tr><td class="'.$cls.'">'.date('F d, Y h:i a', $row['time_id']).'</td><td class="'.$cls.'">'.$row['author'].'</td><td class="'.$cls.'">'.$row['edit_summary'].'</td><td style="text-align: center;" class="' . $cls . '">' . $coppa . '</td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&amp;action=activate&amp;user='.$row['edit_summary'].'&amp;logid='.$row['time_id']).'">Activate now</a></td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&amp;action=sendemail&amp;user='.$row['edit_summary'].'&amp;logid='.$row['time_id']).'">Send activation e-mail</a></td><td class="'.$cls.'" style="text-align: center;"><a href="'.makeUrlNS('Special', 'Administration', 'module='.$paths->nslist['Admin'].'UserManager&amp;action=deny&amp;user='.$row['edit_summary'].'&amp;logid='.$row['time_id']).'">Deny request</a></td></tr>';
       
   435       }
       
   436       echo '</table>';
       
   437     }
       
   438     $db->free_result();
       
   439   }
       
   440   
       
   441 }
       
   442 
       
   443 /**
       
   444  * Smart form class for the user manager.
       
   445  * @package Enano
       
   446  * @subpackage Administration
       
   447  */
       
   448 
       
   449 class Admin_UserManager_SmartForm
       
   450 {
       
   451   
       
   452   /**
       
   453    * Universally Unique Identifier (UUID) for this editor instance. Used to unique-itize Javascript functions and whatnot.
       
   454    * @var string
       
   455    */
       
   456   
       
   457   var $uuid = '';
       
   458   
       
   459   /**
       
   460    * User ID that we're editing.
       
   461    * @var int
       
   462    */
       
   463   
       
   464   var $user_id = 0;
       
   465   
       
   466   /**
       
   467    * Username
       
   468    * @var string
       
   469    */
       
   470   
       
   471   var $username = '';
       
   472   
       
   473   /**
       
   474    * E-mail address
       
   475    * @var string
       
   476    */
       
   477   
       
   478   var $email = '';
       
   479   
       
   480   /**
       
   481    * Real name
       
   482    * @var string
       
   483    */
       
   484   
       
   485   var $real_name = '';
       
   486   
       
   487   /**
       
   488    * Signature
       
   489    * @var string
       
   490    */
       
   491   
       
   492   var $signature = '';
       
   493   
       
   494   /**
       
   495    * IM contact information
       
   496    * @var array
       
   497    */
       
   498    
       
   499   var $im = array();
       
   500   
       
   501   /**
       
   502    * Real-life contact info
       
   503    * @var array
       
   504    */
       
   505   
       
   506   var $contact = array();
       
   507   
       
   508   /**
       
   509    * User level
       
   510    * @var int
       
   511    */
       
   512   
       
   513   var $user_level = USER_LEVEL_MEMBER;
       
   514   
       
   515   /**
       
   516    * Account activated
       
   517    * @var bool
       
   518    */
       
   519   
       
   520   var $account_active = true;
       
   521   
       
   522   /**
       
   523    * Email public switch
       
   524    * @var bool
       
   525    */
       
   526   
       
   527   var $email_public = false;
       
   528   
       
   529   /**
       
   530    * Constructor.
       
   531    */
       
   532   
       
   533   function __construct()
       
   534   {
       
   535     $this->uuid = md5( mt_rand() . microtime() );
       
   536   }
       
   537   
       
   538   /**
       
   539    * PHP4 constructor.
       
   540    */
       
   541   
       
   542   function Admin_UserManager_SmartForm()
       
   543   {
       
   544     $this->__construct();
       
   545   }
       
   546   
       
   547   /**
       
   548    * Renders and returns the finished form.
       
   549    * @return string
       
   550    */
       
   551   
       
   552   function render()
       
   553   {
       
   554     global $db, $session, $paths, $template, $plugins; // Common objects
       
   555     if ( file_exists( ENANO_ROOT . "/themes/$template->theme/admin_usermanager_form.tpl" ) )
       
   556     {
       
   557       $parser = $template->makeParser('admin_usermanager_form.tpl');
       
   558     }
       
   559     else
       
   560     {
       
   561       $tpl_code = <<<EOF
       
   562       <!-- Start of user edit form -->
       
   563       
       
   564         <script type="text/javascript">
       
   565           function userform_{UUID}_chpasswd()
       
   566           {
       
   567             var link = document.getElementById('userform_{UUID}_pwlink');
       
   568             var form = document.getElementById('userform_{UUID}_pwform');
       
   569             domOpacity(link, 100, 0, 500);
       
   570             domObjChangeOpac(0, form);
       
   571             setTimeout("var link = document.getElementById('userform_{UUID}_pwlink'); var form = document.getElementById('userform_{UUID}_pwform'); link.style.display = 'none'; form.style.display = 'block'; domOpacity(form, 0, 100, 500);", 550);
       
   572             <!-- BEGINNOT same_user -->document.forms['useredit_{UUID}'].changing_pw.value = 'yes';<!-- END same_user -->
       
   573           }
       
   574           
       
   575           function userform_{UUID}_chpasswd_cancel()
       
   576           {
       
   577             var link = document.getElementById('userform_{UUID}_pwlink');
       
   578             var form = document.getElementById('userform_{UUID}_pwform');
       
   579             domOpacity(form, 100, 0, 500);
       
   580             domObjChangeOpac(0, link);
       
   581             setTimeout("var link = document.getElementById('userform_{UUID}_pwlink'); var form = document.getElementById('userform_{UUID}_pwform'); form.style.display = 'none'; link.style.display = 'block'; domOpacity(link, 0, 100, 500);", 550);
       
   582             <!-- BEGINNOT same_user -->document.forms['useredit_{UUID}'].changing_pw.value = 'no';<!-- END same_user -->
       
   583           }
       
   584           
       
   585           function userform_{UUID}_validate()
       
   586           {
       
   587             var form = document.forms['useredit_{UUID}'];
       
   588             <!-- BEGINNOT same_user -->
       
   589             if ( form.changing_pw.value == 'yes' )
       
   590             {
       
   591               if ( form.new_password.value != form.new_password_confirm.value )
       
   592               {
       
   593                 alert('The passwords you entered did not match.');
       
   594                 return false;
       
   595               }
       
   596               form.new_password_confirm.value = '';
       
   597               runEncryption();
       
   598             }
       
   599             <!-- END same_user -->
       
   600             return true;
       
   601           }
       
   602         </script>
       
   603       
       
   604         <form action="{FORM_ACTION}" method="post" name="useredit_{UUID}" enctype="multipart/form-data" onsubmit="return userform_{UUID}_validate();">
       
   605         
       
   606           <input name="user_id" value="{USER_ID}" type="hidden" />
       
   607         
       
   608           <div class="tblholder">
       
   609             <table border="0" cellspacing="1" cellpadding="4">
       
   610             
       
   611               <!-- Heading -->
       
   612             
       
   613               <tr>
       
   614                 <th colspan="2">
       
   615                   Editing user: {USERNAME}
       
   616                 </th>
       
   617               </tr>
       
   618               
       
   619               <!-- Basic options (stored in enano_users) -->
       
   620               
       
   621                 <tr>
       
   622                   <th colspan="2" class="subhead">
       
   623                     Basic options
       
   624                   </th>
       
   625                 </tr>
       
   626                 
       
   627                 <tr>
       
   628                   <td class="row2" style="width: 25%;">
       
   629                     Username:<br />
       
   630                     <small>Must be at least 2 characters in length</small>
       
   631                   </td>
       
   632                   <td class="row1" style="width: 75%;">
       
   633                     <input type="text" name="username" value="{USERNAME}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/><!-- BEGIN same_user --> <small>You cannot change your own username. To change your username you must log into a different administrative account.</small><!-- END same_user -->
       
   634                   </td>
       
   635                 </tr>
       
   636                 
       
   637                 <tr>
       
   638                   <td class="row2">
       
   639                     Password:
       
   640                     <!-- BEGIN password_meter -->
       
   641                     <br />
       
   642                     <small>Password strength requirements are not enforced here.</small>
       
   643                     <!-- END password_meter -->
       
   644                   </td>
       
   645                   <td class="row1">
       
   646                     <div id="userform_{UUID}_pwlink">
       
   647                       <b>Password will be left unchanged.</b> <a href="#" onclick="userform_{UUID}_chpasswd(); return false;">Reset password...</a>
       
   648                     </div>
       
   649                     <div id="userform_{UUID}_pwform" style="display: none;">
       
   650                       <!-- BEGIN same_user -->
       
   651                       To change your password, please use the user preferences panel. <a href="#" onclick="userform_{UUID}_chpasswd_cancel(); return false;">Cancel</a>
       
   652                       <!-- BEGINELSE same_user -->
       
   653                       <input type="hidden" name="changing_pw" value="no" />
       
   654                       <input type="hidden" name="challenge_data" value="{MD5_CHALLENGE}" />
       
   655                       <input type="hidden" name="use_crypt" value="no" />
       
   656                       <input type="hidden" name="crypt_key" value="{PUBLIC_KEY}" />
       
   657                       <input type="hidden" name="crypt_data" value="" />
       
   658                       <table border="0" style="background-color: transparent;" cellspacing="0" cellpadding="0">
       
   659                         <tr>
       
   660                           <td colspan="2">
       
   661                             <b>Change password to:</b>
       
   662                           </td>
       
   663                         </tr>
       
   664                         <tr>
       
   665                           <td>New password:</td>
       
   666                           <td><input type="password" name="new_password" value="" <!-- BEGIN password_meter -->onkeyup="password_score_field(this);" <!-- END password_meter -->/><span class="password-checker" style="font-weight: bold; color: #AA0000"> Weak (score: -10)</span>
       
   667                             <!-- BEGIN password_meter -->
       
   668                               <div id="pwmeter" style="margin: 4px 0; height: 8px;"></div>
       
   669                             <!-- END password_meter -->
       
   670                           </td>
       
   671                         </tr>
       
   672                         <tr>
       
   673                           <td>Confirm:</td>
       
   674                           <td><input type="password" name="new_password_confirm" value="" /></td>
       
   675                         </tr>
       
   676                         <tr>
       
   677                           <td colspan="2">
       
   678                             <a href="#" onclick="userform_{UUID}_chpasswd_cancel(); return false;">Cancel</a>
       
   679                           </td>
       
   680                         </tr>
       
   681                       </table>
       
   682                       <!-- END same_user -->
       
   683                     </div>
       
   684                   </td>
       
   685                 </tr>
       
   686                 
       
   687                 <tr>
       
   688                   <td class="row2" style="width: 25%;">
       
   689                     E-mail address:
       
   690                   </td>
       
   691                   <td class="row1" style="width: 75%;">
       
   692                     <input type="text" name="email" value="{EMAIL}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/><!-- BEGIN same_user --> <small>To change your e-mail address, please use the user preferences panel.</small><!-- END same_user -->
       
   693                   </td>
       
   694                 </tr>
       
   695                 
       
   696                 <tr>
       
   697                   <td class="row2" style="width: 25%;">
       
   698                     Real name:
       
   699                   </td>
       
   700                   <td class="row1" style="width: 75%;">
       
   701                     <input type="text" name="real_name" value="{REAL_NAME}" size="40" <!-- BEGIN same_user -->disabled="disabled" <!-- END same_user -->/><!-- BEGIN same_user --> <small>To change your real name on file, please use the user preferences panel.</small><!-- END same_user -->
       
   702                   </td>
       
   703                 </tr>
       
   704                 
       
   705                 <tr>
       
   706                   <td class="row2" style="width: 25%;">
       
   707                     Signature:
       
   708                   </td>
       
   709                   <td class="row1" style="width: 75%;">
       
   710                     {SIGNATURE_FIELD}
       
   711                   </td>
       
   712                 </tr>
       
   713                 
       
   714               <!-- / Basic options -->
       
   715               
       
   716               <!-- Extended options (anything in enano_users_extra) -->
       
   717               
       
   718                 <tr>
       
   719                   <th class="subhead" colspan="2">
       
   720                     Instant messenger contact information
       
   721                   </th>
       
   722                 <tr>
       
   723                   <td class="row2">AIM handle:</td>
       
   724                   <td class="row1"><input type="text" name="imaddr_aim" value="{IM_AIM}" size="30" /></td>
       
   725                 </tr>
       
   726                 <tr>
       
   727                   <td class="row2"><acronym title="Windows&trade; Live Messenger">WLM</acronym> handle:<br /><small>If you don't specify the domain (@whatever.com), "@hotmail.com" will be assumed.</small></td>
       
   728                   <td class="row1"><input type="text" name="imaddr_msn" value="{IM_WLM}" size="30" /></td>
       
   729                 </tr>
       
   730                 <tr>
       
   731                   <td class="row2">Yahoo! IM handle:</td>
       
   732                   <td class="row1"><input type="text" name="imaddr_yahoo" value="{IM_YAHOO}" size="30" /></td>
       
   733                 </tr>
       
   734                 <tr>
       
   735                   <td class="row2">Jabber/XMPP handle:</td>
       
   736                   <td class="row1"><input type="text" name="imaddr_xmpp" value="{IM_XMPP}" size="30" /></td>
       
   737                 </tr>
       
   738                 <tr>
       
   739                   <th class="subhead" colspan="2">
       
   740                     Extra contact information
       
   741                   </th>
       
   742                 </tr>
       
   743                 <tr>
       
   744                   <td class="row2">Homepage:<br /><small>Please remember the http:// prefix.</small></td>
       
   745                   <td class="row1"><input type="text" name="homepage" value="{HOMEPAGE}" size="30" /></td>
       
   746                 </tr>
       
   747                 <tr>
       
   748                   <td class="row2">Location:</td>
       
   749                   <td class="row1"><input type="text" name="location" value="{LOCATION}" size="30" /></td>
       
   750                 </tr>
       
   751                 <tr>
       
   752                   <td class="row2">Job:</td>
       
   753                   <td class="row1"><input type="text" name="occupation" value="{JOB}" size="30" /></td>
       
   754                 </tr>
       
   755                 <tr>
       
   756                   <td class="row2">Hobbies:</td>
       
   757                   <td class="row1"><input type="text" name="hobbies" value="{HOBBIES}" size="30" /></td>
       
   758                 </tr>
       
   759                 <tr>
       
   760                   <td class="row2"><label for="chk_email_public_{UUID}">E-mail address is public</label><br /><small>If this is checked, the user's e-mail address will be displayed on your the page. To protect the address from spambots, it will be encrypted.</small></td>
       
   761                   <td class="row1"><input type="checkbox" id="chk_email_public_{UUID}" name="email_public" <!-- BEGIN email_public -->checked="checked" <!-- END email_public -->size="30" /></td>
       
   762                 </tr>
       
   763               
       
   764               <!-- / Extended options -->
       
   765               
       
   766               <!-- Administrator-only options -->
       
   767               
       
   768                 <tr>
       
   769                   <th class="subhead" colspan="2">
       
   770                     Administrator-only options
       
   771                   </th>
       
   772                 </tr>
       
   773                 
       
   774                 <tr>
       
   775                   <td class="row2">User account is active<br />
       
   776                                    <small>If this is unchecked, the existing activation key will be overwritten in the database, thus invalidating any activation e-mails sent to the user.</small>
       
   777                                    </td>
       
   778                   <td class="row1"><label><input type="checkbox" name="account_active" <!-- BEGIN account_active -->checked="checked" <!-- END account_active -->/> Account is active and enabled</label></td>
       
   779                 </tr>
       
   780                 
       
   781                 <tr>
       
   782                   <td class="row2">
       
   783                     User's site access level<br />
       
   784                     <small>If this is changed, the relevant group memberships will be updated accordingly.</small>
       
   785                   </td>
       
   786                   <td class="row1">
       
   787                     <select name="user_level">
       
   788                       <option value="{USER_LEVEL_MEMBER}"<!-- BEGIN ul_member --> selected="selected"<!-- END ul_member -->>Normal member</option>
       
   789                       <option value="{USER_LEVEL_MOD}"<!-- BEGIN ul_mod --> selected="selected"<!-- END ul_mod -->>Moderator</option>
       
   790                       <option value="{USER_LEVEL_ADMIN}"<!-- BEGIN ul_admin --> selected="selected"<!-- END ul_admin -->>Site administrator</option>
       
   791                     </select>
       
   792                   </td>
       
   793                 </tr>
       
   794                 
       
   795                 <tr>
       
   796                   <td class="row2">
       
   797                     Delete user account
       
   798                   </td>
       
   799                   <td class="row1">
       
   800                     <label><input type="checkbox" name="delete_account" onclick="var d = (this.checked) ? 'block' : 'none'; document.getElementById('delete_blurb_{UUID}').style.display = d;" /> Permanently delete this user account when I click Save</label>
       
   801                     <div id="delete_blurb_{UUID}" style="display: none;">
       
   802                       <!-- BEGIN same_user -->
       
   803                       <p><b><blink style="color: red;">WARNING!</blink> This will delete your own user account!</b></p>
       
   804                       <!-- END same_user -->
       
   805                       <p><small>Even if you delete this user account, the username will be shown in page edit history, comments, and other areas of the site.
       
   806                       Deleting a user account CANNOT BE UNDONE and should only be done in extreme circumstances.
       
   807                       If the user has violated the site policy, deleting the account will not prevent him from using the site or creating a new account, for that you need to add a new ban rule.</small></p>
       
   808                     </div>
       
   809                   </td>
       
   810                 </tr>
       
   811                 </tr>
       
   812               
       
   813               <!-- Save button -->
       
   814               <tr>
       
   815                 <th colspan="2">
       
   816                   <input type="submit" name="action[save]" value="Save changes" style="font-weight: bold;" />
       
   817                   <input type="submit" name="action[noop]" value="Cancel" style="font-weight: normal;" />
       
   818                 </th>
       
   819               </tr>
       
   820             
       
   821             </table>
       
   822           </div>
       
   823         
       
   824         </form>
       
   825         {AES_JAVASCRIPT}
       
   826       <!-- Conclusion of user edit form -->
       
   827 EOF;
       
   828       $parser = $template->makeParserText($tpl_code);
       
   829     }
       
   830     
       
   831     $this->username = htmlspecialchars($this->username);
       
   832     $this->email = htmlspecialchars($this->email);
       
   833     $this->user_id = intval($this->user_id);
       
   834     $this->real_name = htmlspecialchars($this->real_name);
       
   835     $this->signature = htmlspecialchars($this->signature);
       
   836     $this->user_level = intval($this->user_level);
       
   837     
       
   838     $im_aim   = ( isset($this->im['aim']) )   ? $this->im['aim']   : false;
       
   839     $im_yahoo = ( isset($this->im['yahoo']) ) ? $this->im['yahoo'] : false;
       
   840     $im_msn   = ( isset($this->im['msn']) )   ? $this->im['msn']   : false;
       
   841     $im_xmpp  = ( isset($this->im['xmpp']) )  ? $this->im['xmpp']  : false;
       
   842     
       
   843     $homepage = ( isset($this->contact['homepage']) ) ? $this->contact['homepage'] : false;
       
   844     $location = ( isset($this->contact['location']) ) ? $this->contact['location'] : false;
       
   845     $job = ( isset($this->contact['job']) ) ? $this->contact['job'] : false;
       
   846     $hobbies = ( isset($this->contact['hobbies']) ) ? $this->contact['hobbies'] : false;
       
   847     
       
   848     if ( empty($this->username) )
       
   849     {
       
   850       // @error One or more required parameters not set
       
   851       return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->username)';
       
   852     }
       
   853     
       
   854     if ( empty($this->user_id) )
       
   855     {
       
   856       // @error One or more required parameters not set
       
   857       return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->user_id)';
       
   858     }
       
   859     
       
   860     if ( empty($this->email) )
       
   861     {
       
   862       // @error One or more required parameters not set
       
   863       return 'Admin_UserManager_SmartForm::render: Invalid parameter ($form->email)';
       
   864     }
       
   865     
       
   866     $form_action = makeUrlNS('Special', 'Administration', 'module=' . $paths->cpage['module'], true);
       
   867     $aes_javascript = $session->aes_javascript("useredit_$this->uuid", 'new_password', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data');
       
   868     
       
   869     $parser->assign_vars(array(
       
   870         'UUID' => $this->uuid,
       
   871         'USERNAME' => $this->username,
       
   872         'EMAIL' => $this->email,
       
   873         'USER_ID' => $this->user_id,
       
   874         'MD5_CHALLENGE' => $session->dss_rand(),
       
   875         'PUBLIC_KEY' => $session->rijndael_genkey(),
       
   876         'REAL_NAME' => $this->real_name,
       
   877         'SIGNATURE_FIELD' => $template->tinymce_textarea('signature', $this->signature, 10, 50),
       
   878         'USER_LEVEL_MEMBER' => USER_LEVEL_CHPREF,
       
   879         'USER_LEVEL_MOD' => USER_LEVEL_MOD,
       
   880         'USER_LEVEL_ADMIN' => USER_LEVEL_ADMIN,
       
   881         'AES_JAVASCRIPT' => $aes_javascript,
       
   882         'IM_AIM' => $im_aim,
       
   883         'IM_YAHOO' => $im_yahoo,
       
   884         'IM_WLM' => $im_msn,
       
   885         'IM_XMPP' => $im_xmpp,
       
   886         'HOMEPAGE' => $homepage,
       
   887         'LOCATION' => $location,
       
   888         'JOB' => $job,
       
   889         'HOBBIES' => $hobbies,
       
   890         'FORM_ACTION' => $form_action
       
   891       ));
       
   892     
       
   893     $parser->assign_bool(array(
       
   894         'password_meter' => ( getConfig('pw_strength_enable') == '1' ),
       
   895         'ul_member' => ( $this->user_level == USER_LEVEL_CHPREF ),
       
   896         'ul_mod' => ( $this->user_level == USER_LEVEL_MOD ),
       
   897         'ul_admin' => ( $this->user_level == USER_LEVEL_ADMIN ),
       
   898         'account_active' => ( $this->account_active === true ),
       
   899         'email_public' => ( $this->email_public === true ),
       
   900         'same_user' => ( $this->user_id == $session->user_id )
       
   901       ));
       
   902     
       
   903     $parsed = $parser->run();
       
   904     return $parsed;
       
   905   }
       
   906   
       
   907 }
       
   908 
       
   909 ?>