|
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 »" /> |
|
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&action=activate&user='.$row['edit_summary'].'&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&action=sendemail&user='.$row['edit_summary'].'&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&action=deny&user='.$row['edit_summary'].'&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™ 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 ?> |