/[drupal]/contributions/modules/troll/troll.admin.inc
ViewVC logotype

Contents of /contributions/modules/troll/troll.admin.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.8 - (show annotations) (download) (as text)
Sat May 9 03:54:04 2009 UTC (6 months, 2 weeks ago) by deekayen
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +61 -0 lines
File MIME type: text/x-php
port DNSBL from 6.x to D7
1 <?php
2 // $Id: troll.admin.inc,v 1.6 2009/04/10 15:01:21 deekayen Exp $
3
4 /**
5 * @file
6 * Administrative forms and functions for troll module.
7 */
8
9 /**
10 * @return array
11 */
12 function troll_admin_settings() {
13 $form['ip_settings'] = array(
14 '#type' => 'fieldset',
15 '#title' => 'IP Address Banning'
16 );
17 $form['ip_settings']['troll_enable_ip_ban'] = array(
18 '#type' => 'radios',
19 '#title' => t('IP Address Banning'),
20 '#default_value' => variable_get('troll_enable_ip_ban', 1),
21 '#options' => array('1' => t('Enable banning by IP address'), '0' => t('Disable banning by IP address'))
22 );
23 $form['ip_settings']['troll_ip_ban_redirect'] = array(
24 '#type' => 'textfield',
25 '#title' => t('IP Ban Relocation Page'),
26 '#default_value' => variable_get('troll_ip_ban_redirect', ''),
27 '#description' => t("Page for relocating users banned based on their IP address or domain name. If left blank, users will be redirected to blocked.html in the troll module's directory. Do not use a drupal path here! You will cause a loop since IP banning completely blocks all access to the site! Edit the blocked.html file, or redirect to http://localhost."),
28 );
29
30 $roles = user_roles();
31 array_unshift($roles, t(' -Select Role- '));
32 $form['role_settings'] = array(
33 '#type' => 'fieldset',
34 '#title' => t('User Blocking')
35 );
36 $form['role_settings']['troll_block_role'] = array(
37 '#type' => 'select',
38 '#title' => t('Troll Block Role'),
39 '#default_value' => variable_get('troll_block_role', 0),
40 '#options' => $roles,
41 '#description' => t('Select the role to assign to users when blocking from the troll administration screens.'),
42 );
43
44 return system_settings_form($form);
45 }
46
47 /**
48 * Admin settings page validate handler.
49 *
50 * @see troll_admin_settings()
51 */
52 function troll_admin_settings_validate($form, &$form_state) {
53 if ($form_state['values']['troll_block_role'] == '0') {
54 form_set_error('troll_block_role', t('You must choose a role to assign to users when blocking from the troll settings page.'));
55 }
56 }
57
58 /**
59 * Menu callback: user IP banning.
60 */
61 function troll_ip_ban() {
62 $form['banfieldset'] = array(
63 '#type' => 'fieldset',
64 '#title' => t('Add IP Ban'),
65 '#weight' => -1,
66 '#collapsible' => TRUE,
67 '#collapsed' => FALSE
68 );
69 $form['banfieldset']['banform'] = troll_ip_ban_form(array());
70 $form['ipdisplay'] = array(
71 '#type' => 'fieldset',
72 '#title' => t('Banned IPs'),
73 '#value' => troll_display_ip(),
74 '#weight' => 0,
75 '#collapsible' => TRUE,
76 '#collapsed' => FALSE
77 );
78 $form['#validate'] = array('troll_ip_ban_form_validate');
79 return $form;
80 }
81
82 /**
83 * Submit handler for IP Ban form.
84 *
85 * @see troll_ip_ban()
86 * @see troll_ip_ban_form()
87 */
88 function troll_ip_ban_submit($form, &$form_state) {
89 troll_insert_ip($form_state['values']);
90 }
91
92 /**
93 * Summary of how many IP blocks are filtered.
94 *
95 * @return string
96 */
97 function troll_blacklist_summary() {
98 $count = db_query('SELECT COUNT(net) FROM {troll_blacklist}')->fetchField();
99 return t('%d address blocks filtered.', array('%d' => $count));
100 }
101
102 /**
103 * Gives admins a choice of how to punish blacklisted visitors
104 *
105 * @return array
106 */
107 function troll_blacklist_punishment_form() {
108 $form['stutter'] = array(
109 '#type' => 'checkbox',
110 '#title' => t('Randomly stutter output'),
111 '#default_value' => variable_get('troll_blacklist_stutter', 0),
112 '#description' => t('While outputting content, the troll module will cause Drupal to "sleep" for random intervals of 1-5 seconds to delay output.')
113 );
114 $form['mod_requests'] = array(
115 '#type' => 'radios',
116 '#title' => t('Page request modification'),
117 '#options' => array(t('none'), 'silent_post_drop' => 'Silently drop form post submission data', 'notice_post_drop' => 'Drop form post submission data and give a notice'),
118 '#default_value' => variable_get('troll_blacklist_mod_requests', '0'),
119 '#description' => t('Modifies data sent by visitors from blacklisted IPs before Drupal even has a chance to process it.')
120 );
121 $form['alt_page_output'] = array(
122 '#type' => 'fieldset',
123 '#title' => 'Alternate page output'
124 );
125 $form['alt_page_output']['alt_page'] = array(
126 '#type' => 'radios',
127 '#title' => 'Alternate pages',
128 '#options' => array(t('none'), 'blank' => t('Blank pages'), '404' => t('404 every page request'), 'redirect' => t('Redirect to alternate URL')),
129 '#default_value' => variable_get('troll_blacklist_alt_page', '0'),
130 '#description' => t('Sends alternate page output, whether the visitor hits a real URL or not.')
131 );
132 $form['alt_page_output']['alt_url'] = array(
133 '#type' => 'textfield',
134 '#title' => t('Redirection URL'),
135 '#default_value' => variable_get('troll_blacklist_alt_url', ''),
136 '#description' => t('URL to redirect blacklisted visitors to if "Redirect to alternate URL" is selected. Start with the appropriate prefix (e.g. http://)')
137 );
138 $form['submit'] = array(
139 '#type' => 'submit',
140 '#value' => t('Update Blacklist Punishments'),
141 '#weight' => 1
142 );
143 return $form;
144 }
145
146 /**
147 * Submit handler for punishment form.
148 *
149 * @see troll_blacklist_punishment()
150 */
151 function troll_blacklist_punishment_form_submit($form, $form_state) {
152 variable_set('troll_blacklist_mod_requests', $form_state['values']['mod_requests']);
153 variable_set('troll_blacklist_stutter', $form_state['values']['stutter']);
154 variable_set('troll_blacklist_alt_page', $form_state['values']['alt_page']);
155 variable_set('troll_blacklist_alt_url', $form_state['values']['alt_url']);
156 drupal_set_message(t('The settings have been updated.'));
157 }
158
159 /**
160 * Builds form array for admin to select how to import a new blacklist.
161 *
162 * @return array
163 */
164 function troll_blacklist_import_form() {
165 $form['truncate_list'] = array(
166 '#type' => 'checkbox',
167 '#title' => t('Truncate/delete existing blacklist before import')
168 );
169 $options = array();
170 $options[0] = '';
171 if (function_exists('gzopen')) {
172 $options['OCgz'] = 'OpenBSD mirror: okean.com China bzip archive';
173 $options['OKgz'] = 'OpenBSD mirror: okean.com Korea bzip archive';
174 }
175 $options['OTtx'] = 'okean.com China and Korea text file';
176 $options['OCtx'] = 'okean.com China text file';
177 $options['OKtx'] = 'okean.com Korea text file';
178 $form['select_list'] = array(
179 '#type' => 'select',
180 '#title' => t('Download and import'),
181 '#options' => $options,
182 '#description' => t('Downloads supported blacklist from the internet. Please select a mirror when possible.'),
183 );
184 $form['custom_list'] = array(
185 '#type' => 'textfield',
186 '#title' => t('List URL'),
187 '#description' => t('URL of a list to import. List files should have one address per line in Classless Internet Domain Routing CIDR format (x.x.x.x/x). Individual IPs should still have /32.'),
188 );
189 $form['submit'] = array(
190 '#type' => 'submit',
191 '#value' => t('Import List'),
192 '#weight' => 1,
193 );
194 return $form;
195 }
196
197 /**
198 * Submit handler for blacklist import.
199 *
200 * @see troll_blacklist_import()
201 */
202 function troll_blacklist_import_form_submit($form, &$form_state) {
203 if (!empty($form_state['values']['truncate_list'])) {
204 if (db_query('TRUNCATE TABLE {troll_blacklist}')) {
205 drupal_set_message(t('Blacklist table truncated.'));
206 }
207 }
208 if (!empty($form_state['values']['select_list'])) {
209 troll_blacklist_import_list($form_state['values']['select_list']);
210 }
211 if (!empty($form_state['values']['custom_list'])) {
212 troll_blacklist_import_url($form_state['values']['custom_list']);
213 }
214 $form_state['redirect'] = 'admin/user/troll/ip_blacklist';
215 }
216
217 /**
218 * Decyphers what dropdown selection was chosen to send for parsing out IP blocks
219 *
220 * @see troll_blacklist_import_form()
221 * @see troll_blacklist_parse_save()
222 * @param array $edit
223 */
224 function troll_blacklist_import_list($list) {
225 $files = array(
226 'OCgz' => array('gz' => 'http://www.openbsd.org/spamd/chinacidr.txt.gz'),
227 'OKgz' => array('gz' => 'http://www.openbsd.org/spamd/koreacidr.txt.gz'),
228 'OTtx' => array('txt' => 'http://www.okean.com/sinokoreacidr.txt'),
229 'OCtx' => array('txt' => 'http://www.okean.com/chinacidr.txt'),
230 'OKtx' => array('txt' => 'http://www.okean.com/koreacidr.txt'));
231
232 if (!isset($files[$list])) {
233 drupal_set_message(t('Form input not valid'));
234 return FALSE;
235 }
236
237 $file_type = array_keys($files[$list]);
238 troll_blacklist_parse_save($files[$list][$file_type[0]], $file_type[0]);
239 }
240
241 /**
242 * Parses a URL to send for parsing out IP blocks
243 *
244 * @see troll_blacklist_parse_save()
245 * @param array $edit
246 */
247 function troll_blacklist_import_url($edit) {
248 $url_parts = parse_url($edit['custom_list']);
249 $file_parts = pathinfo($url_parts['path']);
250 troll_blacklist_parse_save($edit['custom_list'], $file_parts['extension']);
251 }
252
253 /**
254 * Parses input file, line by line, searching for IP blocks in CIDR
255 * format (x.x.x.x/x). Understands files in text, bzip, and bzip2 format,
256 * where the PHP installation supports it. Writes what it finds to the
257 * database as long integers.
258 *
259 * @todo should probably function_exists() the compression file functions
260 * @param $file_name string
261 * @param $file_type string
262 */
263 function troll_blacklist_parse_save($file_name, $file_type) {
264 $netmasks = array(
265 0, -2147483648, -1073741824, -536870912, -268435456, -134217728,
266 -67108864, -33554432, -16777216, -8388608, -4194304, -2097152, -1048576,
267 -524288, -262144, -131072, -65536, -32768, -16384, -8192, -4096, -2048,
268 -1024, -512, -256, -128, -64, -32, -16, -8, -4, -2, -1);
269
270 switch ($file_type) {
271 case 'gz':
272 $fp = gzopen($file_name, 'r');
273 break;
274 default:
275 $fp = fopen($file_name, 'r');
276 break;
277 }
278
279 if (is_resource($fp)) {
280 $i = 0;
281 while (!feof($fp)) {
282 $buffer = fgets($fp);
283 if ($buffer{0} != '#' && ($buffer{0} != '/' && $buffer{1} != '/') && !empty($buffer)) {
284 preg_match("/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\/([0-9]{1,2})/", $buffer, $matches);
285 // $matches array
286 // 0 = whole string
287 // 1 = i.i.i.i
288 // 2 = s
289 $longip = ip2long($matches[1]);
290 unset($buffer, $matches[0], $matches[1]);
291
292 if ($matches[2] == 32) {
293 $net = $bcast = $longip;
294 }
295 else {
296 $net = $longip & $netmasks[$matches[2]];
297 $bcast = $longip | ($netmasks[$matches[2]] ^ -1);
298 }
299 db_delete('troll_blacklist')
300 ->condition(db_and()->condition('net', $net)->condition('bcast', $bcast))
301 ->execute();
302 db_insert('troll_blacklist')
303 ->fields(array(
304 'net' => $net,
305 'bcast' => $bcast
306 ))
307 ->execute();
308 $i++;
309 }
310 }
311 switch ($file_type) {
312 case 'gz':
313 gzclose($fp);
314 break;
315 default:
316 fclose($fp);
317 break;
318 }
319 drupal_set_message(t('%i IP blocks imported', array('%i' => $i)));
320 }
321 else {
322 drupal_set_message(t('Import failed! File could not be read.'));
323 }
324 }
325
326 /**
327 * Form to search blacklist to see if an IP matches
328 *
329 * @return array
330 */
331 function troll_blacklist_search_form($form_state) {
332 $form['ip_address'] = array(
333 '#type' => 'textfield',
334 '#title' => t('IP Address'),
335 '#size' => 15,
336 '#maxlength' => 15,
337 '#description' => t('Address to search for in the database of imported IP blocks.'),
338 );
339 $form['submit'] = array(
340 '#type' => 'submit',
341 '#value' => t('Search Blacklisted IPs'),
342 '#weight' => 1
343 );
344 $form['result'] = array(
345 '#type' => 'fieldset',
346 '#title' => t('Blacklisted IPs'),
347 '#value' => !empty($form_state['values']['ip_address']) ? troll_blacklist_search($form_state['values']['ip_address']) : troll_blacklist_search(''),
348 '#weight' => 2,
349 '#collapsible' => TRUE,
350 '#collapsed' => FALSE
351 );
352 return $form;
353 }
354
355 /**
356 * Submit handler for blacklist search form.
357 *
358 * @see troll_blacklist_search_blacklist_form()
359 */
360 function troll_blacklist_search_form_submit($form, &$form_state) {
361 $form_state['rebuild'] = TRUE;
362 }
363
364 /**
365 * Perform search to see if an IP address matches a blacklisted IP block.
366 *
367 * @return string
368 */
369 function troll_blacklist_search($ip_address) {
370 $headers = array(
371 array('data' => t('Network Address'), 'field' => 'net', 'sort' => 'asc'),
372 array('data' => t('Broadcast Address'), 'field' => 'bcast'),
373 array('data' => t('Actions'), 'field' => 'delete')
374 );
375
376 if ($ip_address == '') {
377 $result = pager_query('SELECT net, bcast FROM {troll_blacklist}', 25, 0, 'SELECT COUNT(*) FROM {troll_blacklist}');
378 }
379 else {
380 $sql = 'SELECT net, bcast FROM {troll_blacklist} WHERE net <= :longip AND bcast >= :longip';
381 $count_sql = 'SELECT COUNT(*) FROM {troll_blacklist} WHERE net <= :longip AND bcast >= :longip';
382 $longip = _troll_longip($ip_address);
383 $sql .= tablesort_sql($headers);
384 $result = pager_query($sql, 25, 0, $count_sql, array(':longip' => $longip));
385 }
386
387 while ($row = $result->fetchObject()) {
388 $printnet = long2ip($row->net);
389 $printbcast = long2ip($row->bcast);
390 $action = l(t('remove'), "admin/user/troll/ip_blacklist/deleteblack/{$row->net}/{$row->bcast}");
391 $rows[] = array($printnet, $printbcast, $action);
392 }
393 if (!empty($rows)) {
394 $pager = theme('pager', NULL, 25, 0);
395 if (!empty($pager)) {
396 $rows[] = array(array('data' => $pager, 'colspan' => 3));
397 }
398 return theme('table', $headers, $rows);
399 }
400 else {
401 drupal_set_message(t('No matches found.'));
402 return FALSE;
403 }
404 }
405
406 /**
407 * Form builder function
408 *
409 * @param $net string Not used, here for later implementation of whitelist editing
410 * @param $bcast string Not used, here for later implementation of whitelist editing
411 * @see troll_whitelist_form()
412 * @return string
413 */
414 function troll_whitelist($net = NULL, $bcast = NULL) {
415 $sql = 'SELECT net, bcast FROM {troll_whitelist}';
416 $count_sql = 'SELECT COUNT(*) FROM {troll_whitelist}';
417
418 $headers = array(
419 array('data' => t('Start/Network Address'), 'field' => 'net', 'sort' => 'asc'),
420 array('data' => t('End/Broadcast Address'), 'field' => 'bcast'),
421 array('data' => t('Actions'), 'field' => 'delete')
422 );
423
424 $sql .= tablesort_sql($headers);
425 $result = pager_query($sql, 25, 0, $count_sql);
426 while ($row = db_fetch_object($result)) {
427 $printnet = long2ip($row->net);
428 $printbcast = long2ip($row->bcast);
429 $action = l(t('remove'), "admin/user/troll/ip_blacklist/deletewhite/{$row->net}/{$row->bcast}");
430 $rows[] = array($printnet, $printbcast, $action);
431 }
432
433 $pager = theme('pager', NULL, 25, 0);
434 if (!empty($pager)) {
435 $rows[] = array(array('data' => $pager, 'colspan' => 3));
436 }
437
438 return theme('table', $headers, $rows);
439 }
440
441 /**
442 * Display form for creating new whitelist block and table of current whitelisted IPs.
443 *
444 * @todo make this also useful for editing existing whitelist entries
445 * @return array
446 */
447 function troll_whitelist_form($form_state) {
448 $form['whitelist_addr1'] = array(
449 '#type' => 'textfield',
450 '#title' => t('Starting IP Address'),
451 '#size' => 15,
452 '#maxlength' => 15,
453 '#default_value' => isset($net) ? long2ip($net) : '',
454 '#description' => t('IP or start to range of IPs to whitelist.'),
455 '#required' => TRUE
456 );
457 $form['whitelist_addr2'] = array(
458 '#type' => 'textfield',
459 '#title' => t('Ending IP Address'),
460 '#size' => 15,
461 '#maxlength' => 15,
462 '#default_value' => isset($bcast) ? long2ip($bcast) : '',
463 '#description' => t('End of IP range to whitelist. If whitelisting a single IP, leave this blank.'),
464 '#required' => false
465 );
466 $form['submit'] = array(
467 '#type' => 'submit',
468 '#value' => t('Insert Whitelist IPs'),
469 '#weight' => 1
470 );
471 $form['whitelist'] = array(
472 '#type' => 'fieldset',
473 '#title' => t('Whitelisted IPs'),
474 '#value' => troll_whitelist(),
475 '#weight' => 2,
476 '#collapsible' => TRUE,
477 '#collapsed' => FALSE
478 );
479 return $form;
480 }
481
482 /**
483 * Insert a new IP block into the whitelist
484 *
485 * @param array $edit
486 */
487 function troll_whitelist_form_submit($form, &$form_state) {
488 $whitelist_addr1 = $form_state['values']['whitelist_addr1'];
489 $whitelist_addr2 = $form_state['values']['whitelist_addr2'];
490 $longip1 = _troll_longip($whitelist_addr1);
491 $longip2 = _troll_longip(empty($whitelist_addr2) ? $whitelist_addr1 : $whitelist_addr2);
492 if ($longip1 > $longip2) {
493 $temp = $longip1;
494 $longip1 = $longip2;
495 $longip2 = $temp;
496 unset($temp);
497 }
498 db_delete('troll_whitelist')
499 ->condition(db_and()->condition('net', $longip1)->condition('bcast', $longip2))
500 ->execute();
501 db_insert('troll_whitelist')
502 ->fields(array(
503 'net' => $longip1,
504 'bcast' => $longip2
505 ))
506 ->execute();
507 drupal_set_message(t('IP range %ip1 to %ip2 whitelisted.', array('%ip1' => long2ip($longip1), '%ip2' => long2ip($longip2))));
508 }
509
510 /**
511 * Menu callback: block a user and redirect to search page.
512 *
513 * @param $uid
514 */
515 function troll_confirm_block_user_form($form_state, $uid) {
516 $account = user_load($uid);
517 if (!$account) {
518 drupal_goto('admin/user/troll');
519 }
520 $form['uid'] = array(
521 '#type' => 'value',
522 '#value' => $uid,
523 );
524 return confirm_form($form, t('Block user %username?', array('%username' => $account->name)), 'admin/user/troll', t('Are you sure you want to block this user?'));
525 }
526
527 function troll_confirm_block_user_form_submit($form, &$form_state) {
528 troll_block_user($form_state['values']['uid']);
529 $form_state['redirect'] = 'admin/user/troll';
530 }
531
532 /**
533 * IP banning form.
534 *
535 * @param $iid int
536 * @return array
537 */
538 function troll_ip_ban_form($form_state, $iid = NULL) {
539 $form['submit'] = array(
540 '#type' => 'submit',
541 '#value' => (isset($iid)) ? t('Update Banned IP') : t('Ban IP'),
542 '#weight' => 1,
543 );
544
545 $ip = db_query_range('SELECT * FROM {troll_ip_ban} WHERE iid = :iid', array(':iid' => $iid), 0, 1)->fetchObject();
546 $form['iid'] = array(
547 '#type' => 'value',
548 '#value' => !empty($ip->iid) ? $ip->iid : '',
549 );
550 $form['ip_address'] = array(
551 '#type' => 'textfield',
552 '#title' => t('IP Address'),
553 '#default_value' => !empty($ip->ip_address) ? $ip->ip_address : '',
554 '#description' => t('The IP address to ban.'),
555 '#required' => TRUE
556 );
557 $form['domain_name'] = array(
558 '#type' => 'textfield',
559 '#title' => t('Domain Name'),
560 '#default_value' => !empty($ip->domain_name) ? $ip->domain_name : (!empty($ip->ip_address) ? gethostbyaddr($ip->ip_address) : ''),
561 '#description' => t('The Domain Name of the IP address to ban - for reference only.')
562 );
563
564 troll_ip_ban_expire_form($form, $ip);
565
566 return $form;
567 }
568
569 /**
570 * troll_ip_ban form validate callback function.
571 *
572 * @see troll_ip_ban_form()
573 */
574 function troll_ip_ban_form_validate($form, &$form_state) {
575 if (!preg_match('([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})', $form_state['values']['ip_address'])) {
576 form_set_error('ip_address', t('Please include a valid IP address.'));
577 }
578 }
579
580 /**
581 * Submit handler for IP ban form.
582 *
583 * @see troll_ip_ban_form()
584 */
585 function troll_ip_ban_form_submit($form, &$form_state) {
586 troll_update_ip($form_state['values']);
587 $form_state['redirect'] = 'admin/user/troll/ip_ban';
588 }
589
590 /**
591 * Helper function to return the expire form elements.
592 */
593 function troll_ip_ban_expire_form(&$form, $ip) {
594 $timestamp = isset($ip->expires) ? $ip->expires : REQUEST_TIME;
595
596 $date = getdate(gmmktime());
597 $curyear = $date['year'];
598 $i = 0;
599 while ($i < 10) {
600 $years[$curyear + $i] = $curyear + $i;
601 $i++;
602 }
603 $months = array(1 => t('January'), t('February'), t('March'), t('April'), t('May'), t('June'), t('July'), t('August'), t('September'), t('October'), t('November'), t('December'));
604 for ($i = 1; $i <= 31; $i++) {
605 $days[$i] = $i;
606 }
607
608 $form['timestamp'] = array(
609 '#type' => 'fieldset',
610 '#title' => t('Expires'),
611 '#prefix' => '<div class="container-inline"><div class="day">',
612 '#suffix' => '</div></div>',
613 '#description' => t('The ban will be removed after this day.')
614 );
615 $form['timestamp']['expires'] = array(
616 '#type' => 'checkbox',
617 '#default_value' => isset($ip->expires) ? TRUE : FALSE
618 );
619 $form['timestamp']['month'] = array(
620 '#type' => 'select',
621 '#default_value' => date('n', $timestamp),
622 '#options' => $months
623 );
624 $form['timestamp']['day'] = array(
625 '#type' => 'select',
626 '#default_value' => date('j', $timestamp),
627 '#options' => $days
628 );
629 $form['timestamp']['year'] = array(
630 '#type' => 'select',
631 '#default_value' => date('Y', $timestamp),
632 '#options' => $years
633 );
634 }
635
636 /**
637 * IP ban information form.
638 */
639 function troll_display_ip() {
640
641 $rows = array();
642 $sql = 'SELECT iid, ip_address, domain_name, expires, uid FROM {troll_ip_ban}';
643 $count_sql = 'SELECT COUNT(*) FROM {troll_ip_ban}';
644
645 $headers = array(
646 array('data' => t('IP Address'), 'field' => 'ip_address'),
647 array('data' => t('Domain Name'), 'field' => 'domain_name'),
648 array('data' => t('Expires'), 'field' => 'expires', 'sort' => 'desc'),
649 array('data' => t('Actions'), 'field' => 'delete')
650 );
651
652 $sql .= tablesort_sql($headers);
653 $result = pager_query($sql, 25, 0, $count_sql);
654 while ($row = $result->fetchObject()) {
655 $thisip = l($row->ip_address, 'admin/user/troll/ip_ban/edit/' . $row->iid);
656 $thisdom = l(($row->domain_name ? $row->domain_name : gethostbyname($row->ip_address)), 'admin/user/troll/ip_ban/edit/' . $row->iid);
657 $expires = ($row->expires ? date('M d, Y', $row->expires) : t('never'));
658 $action = l(t('remove'), 'admin/user/troll/ip_ban/delete/' . $row->iid);
659 $rows[] = array($thisip, $thisdom, $expires, $action);
660 }
661
662 $pager = theme('pager', NULL, 25, 0);
663 if (!empty($pager)) {
664 $rows[] = array(array('data' => $pager, 'colspan' => 5));
665 }
666
667 return theme('table', $headers, $rows);
668 }
669
670 /**
671 * IP ban delete confirmation form.
672 */
673 function troll_confirm_delete_ip_form($form_state, $iid) {
674 $ip = db_query_range('SELECT ip_address FROM {troll_ip_ban} WHERE iid = :iid', array(':iid' => $iid), 0, 1)->fetchField();
675 $form['iid'] = array(
676 '#type' => 'value',
677 '#value' => $iid,
678 );
679 return confirm_form($form, t('Remove Ban for IP %ip?', array('%ip' => $ip)), 'admin/user/troll/ip_ban', t('Are you sure you want to remove the ban on this IP?'));
680 }
681
682 /**
683 * Submit handler for delete confirmation form.
684 *
685 * @see troll_confirm_delete_ip_form()
686 */
687 function troll_confirm_delete_ip_form_submit($form, &$form_state) {
688 troll_remove_ip($form_state['values']['iid']);
689 $form_state['redirect'] = 'admin/user/troll/ip_ban';
690 }
691
692 /**
693 * IP ban confirmation form.
694 */
695 function troll_confirm_ban_ip_form($form_state, $uid) {
696 $ip = db_query_range('SELECT ip_address FROM {troll_ip_track} WHERE uid = :uid ORDER BY accessed DESC', array(':uid' => $uid), 0, 1)->fetchField();
697 $form['ip_address'] = array(
698 '#type' => 'value',
699 '#value' => $ip->ip_address,
700 );
701 $form['domain_name'] = array(
702 '#type' => 'value',
703 '#value' => gethostbyaddr($ip->ip_address),
704 );
705 troll_ip_ban_expire_form($form, $ip);
706
707 return confirm_form($form, t('Ban IP %ip?', array('%ip' => $ip)), 'admin/user/troll/ip_ban', t('Are you sure you want to ban this IP?'));
708 }
709
710 /**
711 * Submit handler for ban confirmation form.
712 *
713 * @see troll_confirm_ban_ip_form()
714 */
715 function troll_confirm_ban_ip_form_submit($form, &$form_state) {
716 troll_insert_ip($form_state['values']);
717 $form_state['redirect'] = 'admin/user/troll';
718 }
719
720 /**
721 * Confirmation form for deleting a blacklist IP block
722 *
723 * @param integer $net IP in long format
724 * @param integer $bcast IP in long format
725 */
726 function troll_confirm_delete_black_block_form($form_state, $net, $bcast) {
727 $result = db_query('SELECT COUNT(net) FROM {troll_blacklist} WHERE net = :net AND bcast = :bcast', array(':net' => $net, ':bcast' => $bcast))->fetchField();
728 if (empty($result)) {
729 drupal_set_message(t('No such IP range found in the database.'));
730 drupal_goto('admin/user/troll/ip_blacklist/search');
731 }
732 $form['net'] = array(
733 '#type' => 'value',
734 '#value' => $net
735 );
736 $form['bcast'] = array(
737 '#type' => 'value',
738 '#value' => $bcast
739 );
740 return confirm_form(
741 $form,
742 t('Remove listing for IP block %ip1 to %ip2?', array('%ip1' => long2ip($net), '%ip2' => long2ip($bcast))),
743 'admin/user/troll/ip_blacklist/search',
744 t('Are you sure you want to remove this IP block from the blacklist?'),
745 t('Confirm Blacklist Removal')
746 );
747 }
748
749 /**
750 * Submit handler for deletion of IP from blacklist.
751 *
752 * @see troll_confirm_delete_black_block_form()
753 */
754 function troll_confirm_delete_black_block_form_submit($form, &$form_state) {
755 troll_remove_blacklist($form_state['values']['net'], $form_state['values']['bcast']);
756 $form_state['redirect'] = 'admin/user/troll/ip_blacklist/search';
757 }
758
759 /**
760 * Confirmation form for deleting a whitelist IP block
761 *
762 * @param integer $net IP in long format
763 * @param integer $bcast IP in long format
764 */
765 function troll_confirm_delete_white_block_form($form_state, $net, $bcast) {
766 $result = db_query('SELECT COUNT(net) FROM {troll_whitelist} WHERE net = :net AND bcast = :bcast', array(':net' => $net, ':bcast' => $bcast))->fetchField();
767 if (empty($result)) {
768 drupal_set_message(t('No such IP range found in the database.'));
769 drupal_goto('admin/user/troll/ip_blacklist/whitelist');
770 }
771 $form['net'] = array(
772 '#type' => 'value',
773 '#value' => $net
774 );
775 $form['bcast'] = array(
776 '#type' => 'value',
777 '#value' => $bcast
778 );
779
780 return confirm_form(
781 $form,
782 t('Remove listing for IP block %ip1 to %ip2?', array('%ip1' => long2ip($net), '%ip2' => long2ip($bcast))),
783 'admin/user/troll/ip_blacklist/whitelist',
784 t('Are you sure you want to remove this IP block from the whitelist?'),
785 t('Confirm Whitelist Removal')
786 );
787 }
788
789 /**
790 * Submit handler for deletion of IP from whitelist.
791 *
792 * @see troll_confirm_delete_white_block_form()
793 */
794 function troll_confirm_delete_white_block_form_submit($form, &$form_state) {
795 troll_remove_whitelist($form_state['values']['net'], $form_state['values']['bcast']);
796 $form_state['redirect'] = 'admin/user/troll/ip_blacklist/whitelist';
797 }
798
799 /**
800 * User search form.
801 *
802 * @return array
803 */
804 function troll_search_form($form_state) {
805 $form['search'] = array(
806 '#type' => 'fieldset',
807 '#title' => t('Search Users'),
808 '#collapsible' => TRUE
809 );
810 $form['search']['username'] = array(
811 '#type' => 'textfield',
812 '#title' => t('Username'),
813 );
814 $form['search']['mail'] = array(
815 '#type' => 'textfield',
816 '#title' => t('Email')
817 );
818 $form['search']['ip_address'] = array(
819 '#type' => 'textfield',
820 '#title' => t('IP Address')
821 );
822 $form['search']['date_created'] = array(
823 '#type' => 'textfield',
824 '#title' => t('Account Date Created'),
825 '#description' => t('Enter date in mm/dd/yyyy format. Returns all users created after the date entered.')
826 );
827 $form['search']['submit'] = array(
828 '#type' => 'submit',
829 '#value' => t('Search Users')
830 );
831 $form['users'] = array(
832 '#type' => 'fieldset',
833 '#title' => t('Users'),
834 '#value' => isset($form_state['values']) ? troll_list_users($form_state['values']) : troll_list_users(array()),
835 '#weight' => 2,
836 '#collapsible' => TRUE,
837 '#collapsed' => FALSE
838 );
839 return $form;
840 }
841
842 function troll_search_form_submit($form, &$form_state) {
843 $form_state['rebuild'] = TRUE;
844 }
845
846 /**
847 * User list form.
848 *
849 * @param $edit array
850 */
851 function troll_list_users($edit) {
852
853 $args = array();
854 $where[] = 'u.uid <> 0';
855
856 if (!empty($edit['username'])) {
857 $where[] = "LOWER(u.name) LIKE '%:name%' ";
858 $args[':name'] = drupal_strtolower($edit['username']);
859 }
860 if (!empty($edit['mail'])) {
861 $where[] = "LOWER(u.mail) LIKE '%:mail%' ";
862 $args[':mail'] = drupal_strtolower($edit['mail']);
863 }
864 if (!empty($edit['ip_address'])) {
865 $where[] = "LOWER(t.ip_address) LIKE '%:ip_address%' ";
866 $args[':ip_address'] = drupal_strtolower($edit['ip_address']);
867 }
868 if (!empty($edit['date_created'])) {
869 $where[] = "u.created > :created ";
870 $args[':created'] = drupal_strtotime($edit['date_created']);
871 }
872
873 $sql = "SELECT u.uid, u.name, u.mail, u.status, t.ip_address, MAX(t.accessed) AS recorded, u.created FROM {users} u LEFT JOIN {troll_ip_track} t ON u.uid = t.uid";
874
875 $sql .= ' WHERE ' . implode(' AND ', $where);
876
877 $headers = array(
878 array('data' => t('Username'), 'field' => 'u.name'),
879 array('data' => t('Email'), 'field' => 'u.mail'),
880 array('data' => t('Status'), 'field' => 'u.status'),
881 array('data' => t('IP Address'), 'field' => 't.ip_address'),
882 array('data' => t('Last Access'), 'field' => 't.created'),
883 array('data' => t('Account Created'), 'field' => 'u.created'),
884 array('data' => t('Actions'), 'field' => 'actions')
885 );
886
887 $sql .= ' GROUP BY u.uid, u.name, u.mail, u.status, t.ip_address, u.created';
888 $sql .= tablesort_sql($headers);
889
890 $count_sql = 'SELECT COUNT(*) FROM {users} u LEFT JOIN {troll_ip_track} t ON u.uid = t.uid WHERE ' . implode(' AND ', $where) . ' AND u.uid <> 0';
891 $result = pager_query($sql, 25, 0, $count_sql, $args);
892
893 while ($user = db_fetch_object($result)) {
894 $name = l($user->name, 'admin/user/troll/search/view/' . $user->uid, array('title' => t('View detailed user information')));
895 $email = $user->mail;
896 $status = ($user->status ? t('Active') : t('Blocked'));
897 $ip = ($user->ip_address ? l($user->ip_address, 'admin/user/troll/search/view/' . $user->uid, array('title' => t('View detailed user information'))) : t('none'));
898 $recorded = ($user->recorded ? date('M d, Y', $user->recorded) : t('none recorded'));
899 $created = date('M d, Y', $user->created);
900 $actions = array();
901
902 if (!$user->status) {
903 $actions[] = array('title' => t('Edit User'), 'href' => "user/{$user->uid}/edit");
904 }
905 else if (variable_get('troll_block_role', NULL)) {
906 $actions[] = array('title' => t('Block User'), 'href' => 'admin/user/troll/search/block/' . $user->uid);
907 }
908 else {
909 $actions[] = array('title' => t('Set up Block Role'), 'href' => 'admin/user/troll/settings');
910 }
911 if ($user->ip_address) {
912 $actions[] = array('title' => t('Ban IP'), 'href' => 'admin/user/troll/ip_ban/user/' . $user->uid);
913 }
914 $action = theme('links', $actions);
915 $rows[] = array($name, $email, $status, $ip, $recorded, $created, $action);
916 }
917
918 $pager = theme('pager', NULL, 25);
919
920 if (!empty($pager)) {
921 $rows[] = array(array('data' => $pager, 'colspan' => 7));
922 }
923
924 return theme('table', $headers, $rows);
925 }
926
927 /**
928 * User detail form.
929 *
930 * This is not an actual form; the form API is just being used for easy formatting.
931 *
932 * @param $uid int
933 * @return string
934 */
935 function troll_search_user_detail($uid) {
936 $u = user_load($uid);
937 $u->ip = db_query_range('SELECT t.ip_address FROM {troll_ip_track} t WHERE t.uid = :uid GROUP BY t.uid, t.ip_address', array(':uid' => $uid), 0, 1)->fetchField();
938
939 $form['details'] = array(
940 '#type' => 'fieldset',
941 '#title' => t('Account Details for %username', array('%username' => $u->name))
942 );
943
944 $form['details'][] = array(
945 '#type' => 'item',
946 '#title' => t('User Name'),
947 '#value' => theme('username', $u),
948 );
949 $form['details'][] = array(
950 '#type' => 'item',
951 '#title' => t('Email'),
952 '#value' => $u->mail
953 );
954 $form['details'][] = array(
955 '#type' => 'item',
956 '#title' => t('User ID'),
957 '#value' => $uid
958 );
959 $form['details'][] = array(
960 '#type' => 'item',
961 '#title' => t('Account Created'),
962 '#value' => format_date($u->created, 'large')
963 );
964 $form['details'][] = array(
965 '#type' => 'item',
966 '#title' => t('Last Access'),
967 '#value' => format_date($u->access, 'large')
968 );
969 $form['details'][] = array(
970 '#type' => 'item',
971 '#title' => t('Status'),
972 '#value' => ($u->status ? t('Active') : t('Blocked'))
973 );
974 $form['details'][] = array(
975 '#type' => 'item',
976 '#title' => t('User Roles'),
977 '#value' => implode(', ', $u->roles)
978 );
979 if ($u->status) {
980 $links[] = array('title' => t('Block User'), 'href' => "admin/user/troll/search/block/$uid");
981 }
982 else {
983 $links[] = array('title' => t('Edit User'), 'href' => "user/$uid/edit");
984 }
985 if ($u->ip) {
986 $links[] = array('title' => t('Ban IP'), 'href' => "admin/user/troll/ip_ban/user/$uid");
987 }
988 $form['details'][] = array(
989 '#type' => 'item',
990 '#title' => t('Actions'),
991 '#value' => theme('links', $links)
992 );
993
994 $content = drupal_render($form);
995
996 // Get IP history.
997 $result = db_query('SELECT * FROM {troll_ip_track} WHERE uid = :uid ORDER BY created DESC', array(':uid' => $uid));
998 while ($ip = $result->fetchObject()) {
999 $banned = db_query_range('SELECT iid, ip_address, expires FROM {troll_ip_ban} WHERE ip_address = :ip_address', array(':ip_address' => $ip->ip_address), 0, 1)->fetchObject();
1000 if (!empty($banned->ip_address)) {
1001 if (!empty($banned->expires) && $banned->expires < REQUEST_TIME) {
1002 $status = l(t('expired'), 'admin/user/troll/ip_ban/edit/' . $banned->iid, array('title' => t('Edit IP ban information')));
1003 }
1004 else {
1005 $status = l(t('banned'), 'admin/user/troll/ip_ban/edit/' . $banned->iid, array('title' => t('Edit IP ban information')));
1006 }
1007 }
1008 else {
1009 $status = l(t('not banned'), 'admin/user/troll/ip_ban/user/' . $uid, array('title' => t('Ban this IP')));
1010 }
1011 $rows[] = array($ip->ip_address, $status, format_date($ip->accessed, 'large'), format_date($ip->created, 'large'), exec('host ' . $ip->ip_address));
1012 }
1013
1014 if ($rows) {
1015 $pheader = array(t('IP'), t('Status'), t('Last Access'), t('First Access'), t('Host Information'));
1016 $posts = theme('table', $pheader, $rows);
1017 }
1018 $content .= theme('box', t('IP History'), ($posts ? $posts : t('No ip history')));
1019
1020 // Get recent posts.
1021 $posts = NULL;
1022 $rows = array();
1023 $result = db_query_range("SELECT * FROM {node} WHERE uid = :uid ORDER BY created DESC", array(':uid' => $uid), 0, 5);
1024 while ($node = $result->fetchObject()) {
1025 $rows[] = array(l($node->title, "node/$node->nid") . ' ' . theme('mark', node_mark($node->nid, $node->changed)), $node->type, date('M d, Y', $node->created), ($node->status ? t('published') : t('not published')));
1026 }
1027 if ($rows) {
1028 $pheader = array(t('Title'), t('Type'), t('Created'), t('Status'));
1029 $posts = theme('table', $pheader, $rows);
1030 }
1031
1032 $content .= theme('box', t('Recent Posts'), ($posts ? $posts : t('No recent posts')));
1033
1034 if (module_exists('comment')) {
1035 // Get recent comments.
1036 $rows = array();
1037 $posts = NULL;
1038
1039 $result = db_query('SELECT cid, nid, subject, changed, timestamp, status FROM {comments} WHERE uid = :uid ORDER BY timestamp DESC', array(':uid' => $uid));
1040 while ($comment = $result->fetchObject()) {
1041 $rows[] = array(l($comment->subject, 'node/' . $comment->nid, array('fragment' => 'comment-' . $comment->cid)) . ' ' . theme('mark', node_mark($comment->nid, $comment->changed)), date('M d, Y', $comment->timestamp), ($comment->status ? t('not published') : t('published')));
1042 }
1043
1044 if ($rows) {
1045 $cheader = array(t('Subject'), t('Date Created'), t('Status'));
1046 $posts = theme('table', $cheader, $rows);
1047 }
1048 $content .= theme('box', t('Recent Comments'), ($posts ? $posts : t('No recent comments')));
1049 }
1050 return $content;
1051 }
1052
1053 function troll_dnsbl_settings() {
1054 $form = array();
1055
1056 $form['troll_dnsbl_ip_test'] = array(