From 78f3ea783394dba14b51b27f7f2db3974ce8b8b3 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 09:29:08 +1000 Subject: View IP adress page, ban form. --- inc/mod/ban.php | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 inc/mod/ban.php (limited to 'inc/mod/ban.php') diff --git a/inc/mod/ban.php b/inc/mod/ban.php new file mode 100644 index 00000000..236b2b14 --- /dev/null +++ b/inc/mod/ban.php @@ -0,0 +1,77 @@ +bindValue(':ip', $mask); + $query->bindValue(':mod', $mod['id']); + if ($reason !== '') + $query->bindValue(':reason', $reason); + else + $query->bindValue(':reason', null, PDO::PARAM_NULL); + + if ($length > 0) + $query->bindValue(':expires', time() + $length); + else + $query->bindValue(':expires', null, PDO::PARAM_NULL); + + if ($board) + $query->bindValue(':board', $board); + else + $query->bindValue(':board', null, PDO::PARAM_NULL); + + $query->execute() or error(db_error($query)); +} -- cgit v1.3 From 2843ddc4826f250a8af6203cff437929ab807a41 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 09:47:27 +1000 Subject: view bans / unban --- inc/mod/ban.php | 19 ++++++++---- inc/mod/pages.php | 18 ++++++++++-- inc/template.php | 2 +- templates/mod/view_ip.html | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 9 deletions(-) (limited to 'inc/mod/ban.php') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 236b2b14..33b64975 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -10,7 +10,7 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { } function parse_time($str) { - if(empty($str)) + if (empty($str)) return false; if (($time = @strtotime($str)) !== false) @@ -55,16 +55,18 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod; - $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, UNIX_TIMESTAMP(), :expires, :reason, :board)"); + $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); - if ($reason !== '') + $query->bindValue(':time', time()); + if ($reason !== '') { + markup($reason); $query->bindValue(':reason', $reason); - else + } else $query->bindValue(':reason', null, PDO::PARAM_NULL); if ($length > 0) - $query->bindValue(':expires', time() + $length); + $query->bindValue(':expires', $length); else $query->bindValue(':expires', null, PDO::PARAM_NULL); @@ -75,3 +77,10 @@ function ban($mask, $reason, $length, $board) { $query->execute() or error(db_error($query)); } + +function unban($id) { + $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); +} + diff --git a/inc/mod/pages.php b/inc/mod/pages.php index c00cd672..e7e4f065 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -94,9 +94,17 @@ function mod_view_thread($boardName, $thread) { function mod_page_ip($ip) { global $config, $mod; - if(filter_var($ip, FILTER_VALIDATE_IP) === false) + if (filter_var($ip, FILTER_VALIDATE_IP) === false) error("Invalid IP address."); + if (isset($_POST['ban_id'], $_POST['unban'])) { + require_once 'inc/mod/ban.php'; + + unban($_POST['ban_id']); + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + return; + } + $args = array(); $args['ip'] = $ip; $args['posts'] = array(); @@ -134,6 +142,11 @@ function mod_page_ip($ip) { $args['boards'] = $boards; + $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); + $query->bindValue(':ip', $ip); + $query->execute() or error(db_error($query)); + $args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC); + mod_page("IP: $ip", 'mod/view_ip.html', $args); } @@ -147,8 +160,7 @@ function mod_page_ban() { ban($_POST['ip'], $_POST['reason'], parse_time($_POST['length']), $_POST['board'] == '*' ? false : $_POST['board']); - - if(isset($_POST['redirect'])) + if (isset($_POST['redirect'])) header('Location: ' . $_POST['redirect'], true, $config['redirect_http']); else header('Location: ?/', true, $config['redirect_http']); diff --git a/inc/template.php b/inc/template.php index 8d679d25..ab220454 100644 --- a/inc/template.php +++ b/inc/template.php @@ -26,7 +26,7 @@ function load_twig() { $loader->setPaths($config['dir']['template']); $twig = new Twig_Environment($loader, array( 'autoescape' => false, - 'cache' => "{$config['dir']['template']}/cache", + //'cache' => "{$config['dir']['template']}/cache", 'debug' => ($config['debug'] ? true : false), )); $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index 3b558e4b..a9676dd7 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -11,6 +11,79 @@ {% set redirect = '?/IP/' ~ ip %} +{% if bans|count > 0 %} +
+ Ban{% if bans|count != 1 %}s{% endif %} on record + + {% for ban in bans %} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Status + {% if config.mod.view_banexpired and ban.expires != 0 and ban.expires < time() %} + Expired + {% else %} + Active + {% endif %} +
IP{{ ban.ip }}
Reason + {% if ban.reason %} + {{ ban.reason }} + {% else %} + no reason + {% endif %} +
Board + {% if ban.board %} + {{ config.board_abbreviation|sprintf(ban.board) }} + {% else %} + all boards + {% endif %} +
Set{{ ban.set|date(config.post_date) }}
Expires + {% if ban.expires %} + {{ ban.expires|date(config.post_date) }} + {% else %} + never + {% endif %} +
Staff + {% if ban.username %} + {{ ban.username }} + {% else %} + deleted? + {% endif %} +
+ + +
+ {% endfor %} +
+{% endif %} +
New ban {% include 'mod/ban_form.html' %} -- cgit v1.3 From 7f6f836bf85350fe92d3975d2fb3973343923aeb Mon Sep 17 00:00:00 2001 From: Michael Save Date: Fri, 13 Apr 2012 10:41:30 +1000 Subject: IP notes --- inc/mod/ban.php | 4 +++ inc/mod/pages.php | 90 +++++++++++++++++++++++++++++++++++++++++++--- mod.php | 15 +++++--- templates/mod/confirm.html | 7 ++++ templates/mod/log.html | 11 ++++++ templates/mod/view_ip.html | 80 +++++++++++++++++++++++++++++++++++++---- 6 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 templates/mod/confirm.html create mode 100644 templates/mod/log.html (limited to 'inc/mod/ban.php') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 33b64975..8d86cbcd 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -55,6 +55,8 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod; + // TODO: permissions + $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); @@ -79,6 +81,8 @@ function ban($mask, $reason, $length, $board) { } function unban($id) { + // TODO: permissions + $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); diff --git a/inc/mod/pages.php b/inc/mod/pages.php index e7e4f065..73015cf9 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -52,7 +52,11 @@ function mod_login() { if (isset($_POST['username'])) $args['username'] = $_POST['username']; - mod_page('Dashboard', 'mod/login.html', $args); + mod_page('Login', 'mod/login.html', $args); +} + +function mod_confirm($request) { + mod_page('Confirm action', 'mod/confirm.html', array('request' => $request)); } function mod_dashboard() { @@ -63,6 +67,21 @@ function mod_dashboard() { mod_page('Dashboard', 'mod/dashboard.html', $args); } +function mod_log($page_no = 1) { + global $config; + + if (!hasPermission($config['mod']['modlog'])) + error($config['error']['noaccess']); + + $query = prepare("SELECT `username`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); + $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + $logs = $query->fetchAll(PDO::FETCH_ASSOC); + + mod_page('Moderation log', 'mod/log.html', array('logs' => $logs)); +} + function mod_view_board($boardName, $page_no = 1) { global $config, $mod; @@ -91,6 +110,20 @@ function mod_view_thread($boardName, $thread) { echo $page; } +function mod_ip_remove_note($ip, $id) { + global $config, $mod; + + if (filter_var($ip, FILTER_VALIDATE_IP) === false) + error("Invalid IP address."); + + $query = prepare('DELETE FROM `ip_notes` WHERE `ip` = :ip AND `id` = :id'); + $query->bindValue(':ip', $ip); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); +} + function mod_page_ip($ip) { global $config, $mod; @@ -105,6 +138,21 @@ function mod_page_ip($ip) { return; } + if (isset($_POST['note'])) { + // TODO: permissions + + markup($_POST['note']); + $query = prepare('INSERT INTO `ip_notes` VALUES (NULL, :ip, :mod, :time, :body)'); + $query->bindValue(':ip', $ip); + $query->bindValue(':mod', $mod['id']); + $query->bindValue(':time', time()); + $query->bindValue(':body', $_POST['note']); + $query->execute() or error(db_error($query)); + + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + return; + } + $args = array(); $args['ip'] = $ip; $args['posts'] = array(); @@ -145,14 +193,26 @@ function mod_page_ip($ip) { $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); $query->bindValue(':ip', $ip); $query->execute() or error(db_error($query)); - $args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC); + $args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC); + + $query = prepare("SELECT `ip_notes`.*, `username` FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); + $query->bindValue(':ip', $ip); + $query->execute() or error(db_error($query)); + $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); mod_page("IP: $ip", 'mod/view_ip.html', $args); } -function mod_page_ban() { - if(!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) - error($config['error']['missedafield']); +function mod_ban() { + if (!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) { + mod_page("New ban", 'mod/ban_form.html', array()); + return; + } + + $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); + $query->bindValue(':ip', $ip); + $query->execute() or error(db_error($query)); + $args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC); $ip = $_POST['ip']; @@ -166,3 +226,23 @@ function mod_page_ban() { header('Location: ?/', true, $config['redirect_http']); } +function mod_delete($board, $post) { + global $config, $mod; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['delete'], $board)) + error($config['error']['noaccess']); + + // Delete post + deletePost($post); + // Record the action + modLog("Deleted post #{$post}"); + // Rebuild board + buildIndex(); + + // Redirect + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + diff --git a/mod.php b/mod.php index 5f2cad56..c89c2f01 100644 --- a/mod.php +++ b/mod.php @@ -21,11 +21,18 @@ if (get_magic_quotes_gpc()) { $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $pages = array( - '!^$!' => ':?/', // redirect to dashboard - '!^/$!' => 'dashboard', // dashboard + '!^$!' => ':?/', // redirect to dashboard + '!^/$!' => 'dashboard', // dashboard + '!^/log$!' => 'log', // modlog + '!^/log/(\d+)/$!' => 'log', // modlog - '!^/IP/(.+)$!' => 'ip', // view ip address - '!^/ban$!' => 'ban', // new ban + '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) + + '!^/ban$!' => 'ban', // new ban + '!^/IP/([\w.:]+)$!' => 'ip', // view ip address + '!^/IP/([\w.:]+)/remove_note/(\d+)$!' => 'ip_remove_note', // remove note from ip address + + '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post // This should always be at the end: '!^/(\w+)/' . preg_quote($config['file_index'], '!') . '?$!' => 'view_board', diff --git a/templates/mod/confirm.html b/templates/mod/confirm.html new file mode 100644 index 00000000..7509ce3c --- /dev/null +++ b/templates/mod/confirm.html @@ -0,0 +1,7 @@ +

+ Are you sure you want to do that? Click to proceed to ?/{{ request }}. +

+

+ You are seeing this message because we were unable to serve a confirmation dialog, probably due to Javascript being disabled. +

+ diff --git a/templates/mod/log.html b/templates/mod/log.html new file mode 100644 index 00000000..2aa0ea0a --- /dev/null +++ b/templates/mod/log.html @@ -0,0 +1,11 @@ + + + + + {% for log in logs %} + + {% endfor %} +
+ +
+ diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index a9676dd7..3bc9654c 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -9,9 +9,73 @@
{% endfor %} -{% set redirect = '?/IP/' ~ ip %} +{% if mod|hasPermission(config.mod.view_notes) %} +
+ + {{ notes|count }} note{% if notes|count != 1 %}s{% endif %} on record + + + {% if notes|count > 0 %} + + + + + + {% if mod|hasPermission(config.mod.remove_notes) %} + + {% endif %} + + {% for note in notes %} + + + + + {% if mod|hasPermission(config.mod.remove_notes) %} + + {% endif %} + + {% endfor %} +
StaffNoteDateActions
+ {% if note.username %} + {{ note.username }} + {% else %} + deleted? + {% endif %} + + {{ note.body }} + + {{ note.time|date(config.post_date) }} + + [remove] +
+ {% endif %} + + {% if mod|hasPermission(config.mod.create_notes) %} +
+ + + + + + + + + + + + + +
Staff{{ mod.username }}
+ + + +
+
+ {% endif %} +
+{% endif %} -{% if bans|count > 0 %} +{% if bans|count > 0 and mod|hasPermission(config.mod.view_ban) %}
Ban{% if bans|count != 1 %}s{% endif %} on record @@ -84,8 +148,10 @@
{% endif %} -
- New ban - {% include 'mod/ban_form.html' %} -
- +{% if mod|hasPermission(config.mod.ban) %} +
+ New ban + {% set redirect = '?/IP/' ~ ip %} + {% include 'mod/ban_form.html' %} +
+{% endif %} -- cgit v1.3 From ad55a634bf3f9301489f5371942c73940361a24c Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 16 Apr 2012 16:40:24 +1000 Subject: various improvements --- inc/mod/ban.php | 41 +++++++++-------- inc/mod/pages.php | 105 +++++++++++++++++++++++++++++++++++++++----- mod.php | 4 +- stylesheets/style.css | 15 ++++--- templates/mod/ban_list.html | 74 +++++++++++++++++++++++++++++++ templates/mod/new_pm.html | 4 +- templates/mod/pm.html | 41 +++++++++++++++++ 7 files changed, 247 insertions(+), 37 deletions(-) create mode 100644 templates/mod/ban_list.html create mode 100644 templates/mod/pm.html (limited to 'inc/mod/ban.php') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 8d86cbcd..e7110edf 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -16,44 +16,45 @@ function parse_time($str) { if (($time = @strtotime($str)) !== false) return $time; - if (!preg_match('/^((\d+)\s*ye?a?r?s?)?\s*+((\d+)\s*mon?t?h?s?)?\s*((\d+)\s*we?e?k?s?)?\s*((\d+)\s*da?y?s?)?((\d+)\s*ho?u?r?s?)?\s*((\d+)\s*mi?n?u?t?e?s?)?\s*+((\d+)\s*se?c?o?n?d?s?)?$/', $str, $matches)) + if (!preg_match('/^((\d+)\s?ye?a?r?s?)?\s?+((\d+)\s?mon?t?h?s?)?\s?+((\d+)\s?we?e?k?s?)?\s?+((\d+)\s?da?y?s?)?((\d+)\s?ho?u?r?s?)?\s?+((\d+)\s?mi?n?u?t?e?s?)?\s?+((\d+)\s?se?c?o?n?d?s?)?$/', $str, $matches)) return false; - $expire = time(); - if (isset($m[2])) { + $expire = 0; + + if (isset($matches[2])) { // Years - $expire += $m[2]*60*60*24*365; + $expire += $matches[2]*60*60*24*365; } - if (isset($m[4])) { + if (isset($matches[4])) { // Months - $expire += $m[4]*60*60*24*30; + $expire += $matches[4]*60*60*24*30; } - if (isset($m[6])) { + if (isset($matches[6])) { // Weeks - $expire += $m[6]*60*60*24*7; + $expire += $matches[6]*60*60*24*7; } - if (isset($m[8])) { + if (isset($matches[8])) { // Days - $expire += $m[8]*60*60*24; + $expire += $matches[8]*60*60*24; } - if (isset($m[10])) { + if (isset($matches[10])) { // Hours - $expire += $m[10]*60*60; + $expire += $matches[10]*60*60; } - if (isset($m[12])) { + if (isset($matches[12])) { // Minutes - $expire += $m[12]*60; + $expire += $matches[12]*60; } - if (isset($m[14])) { + if (isset($matches[14])) { // Seconds - $expire += $m[14]; + $expire += $matches[14]; } - return $expire; + return time() + $expire; } function ban($mask, $reason, $length, $board) { - global $mod; + global $mod, $pdo; // TODO: permissions @@ -78,6 +79,8 @@ function ban($mask, $reason, $length, $board) { $query->bindValue(':board', null, PDO::PARAM_NULL); $query->execute() or error(db_error($query)); + + modLog('Created a new ban (#' . $pdo->lastInsertId() . ') for ' . utf8tohtml($mask) . ' with ' . ($reason ? 'reason: ' . $reason . '' : 'no reason')); } function unban($id) { @@ -86,5 +89,7 @@ function unban($id) { $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); + + modLog("Removed ban #{$id}"); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 7518b9fb..60f101ea 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -39,7 +39,7 @@ function mod_login() { $args['error'] = $config['error']['invalid']; } else { - modLog("Logged in."); + modLog('Logged in'); // Login successful // Set cookies @@ -101,6 +101,7 @@ function mod_view_board($boardName, $page_no = 1) { $page['btn'] = getPageButtons($page['pages'], true); $page['mod'] = true; $page['config'] = $config; + echo Element('index.html', $page); } @@ -128,6 +129,8 @@ function mod_ip_remove_note($ip, $id) { $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); + modLog("Removed a note for {$ip}"); + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); } @@ -160,6 +163,8 @@ function mod_page_ip($ip) { $query->bindValue(':body', $_POST['note']); $query->execute() or error(db_error($query)); + modLog("Added a note for {$ip}"); + header('Location: ?/IP/' . $ip, true, $config['redirect_http']); return; } @@ -177,8 +182,9 @@ function mod_page_ip($ip) { $query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); - while ($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { if (!$post['thread']) { + // TODO: There is no reason why this should be such a fucking mess. $po = new Thread( $post['id'], $post['subject'], $post['email'], $post['name'], $post['trip'], $post['capcode'], $post['body'], $post['time'], $post['thumb'], $post['thumbwidth'], $post['thumbheight'], $post['file'], $post['filewidth'], @@ -230,13 +236,6 @@ function mod_ban() { return; } - $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE `ip` = :ip"); - $query->bindValue(':ip', $ip); - $query->execute() or error(db_error($query)); - $args['bans'] = $query->fetchAll(PDO::FETCH_ASSOC); - - $ip = $_POST['ip']; - require_once 'inc/mod/ban.php'; ban($_POST['ip'], $_POST['reason'], parse_time($_POST['length']), $_POST['board'] == '*' ? false : $_POST['board']); @@ -247,6 +246,51 @@ function mod_ban() { header('Location: ?/', true, $config['redirect_http']); } +function mod_bans() { + global $config; + + if (!hasPermission($config['mod']['view_banlist'])) + error($config['error']['noaccess']); + + if (isset($_POST['unban'])) { + if (!hasPermission($config['mod']['unban'])) + error($config['error']['noaccess']); + + $unban = array(); + foreach ($_POST as $name => $unused) { + if (preg_match('/^ban_(\d+)$/', $name, $match)) + $unban[] = $match[1]; + } + + query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); + + foreach ($unban as $id) { + modLog("Removed ban #{$id}"); + } + + header('Location: ?/bans', true, $config['redirect_http']); + } + + if ($config['mod']['view_banexpired']) { + $query = prepare("SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY (`expires` IS NOT NULL AND `expires` < :time), `set` DESC"); + $query->bindValue(':time', time(), PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + } else { + // Filter out expired bans + $query = prepare("SELECT `bans`.*, `username` FROM `bans` INNER JOIN `mods` ON `mod` = `mods`.`id` WHERE `expires` = 0 OR `expires` > :time ORDER BY `set` DESC"); + $query->bindValue(':time', time(), PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + } + $bans = $query->fetchAll(PDO::FETCH_ASSOC); + + foreach ($bans as &$ban) { + if (filter_var($ban['ip'], FILTER_VALIDATE_IP) !== false) + $ban['real_ip'] = true; + } + + mod_page('Ban list', 'mod/ban_list.html', array('bans' => $bans)); +} + function mod_delete($board, $post) { global $config, $mod; @@ -290,9 +334,48 @@ function mod_user_promote($uid, $action) { $query->bindValue(':id', $uid); $query->execute() or error(db_error($query)); + modLog(($action == 'promote' ? 'Promoted' : 'Demoted') . " user #{$uid}"); + header('Location: ?/users', true, $config['redirect_http']); } +function mod_pm($id, $reply = false) { + global $mod, $config; + + $query = prepare("SELECT `mods`.`username`, `mods_to`.`username` AS `to_username`, `pms`.* FROM `pms` LEFT JOIN `mods` ON `mods`.`id` = `sender` LEFT JOIN `mods` AS `mods_to` ON `mods_to`.`id` = `to` WHERE `pms`.`id` = :id"); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + if ((!$pm = $query->fetch(PDO::FETCH_ASSOC)) || ($pm['to'] != $mod['id'] && !hasPermission($config['mod']['master_pm']))) + error($config['error']['404']); + + if (isset($_POST['delete'])) { + $query = prepare("DELETE FROM `pms` WHERE `id` = :id"); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + header('Location: ?/', true, $config['redirect_http']); + return; + } + + if ($pm['unread'] && $pm['to'] == $mod['id']) { + $query = prepare("UPDATE `pms` SET `unread` = 0 WHERE `id` = :id"); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + modLog('Read a PM'); + } + + if ($reply) { + if (!$pm['to_username']) + error($config['error']['404']); // deleted? + + mod_page("New PM for {$pm['to_username']}", 'mod/new_pm.html', array('username' => $pm['to_username'], 'id' => $pm['to'], 'message' => quote($pm['message']))); + } else { + mod_page("Private message – #$id", 'mod/pm.html', $pm); + } +} + function mod_new_pm($username) { global $config, $mod; @@ -323,6 +406,8 @@ function mod_new_pm($username) { $query->bindValue(':time', time()); $query->execute() or error(db_error($query)); + modLog('Sent a PM to ' . utf8tohtml($username)); + header('Location: ?/', true, $config['redirect_http']); } @@ -371,7 +456,7 @@ function mod_rebuild() { } $query = query(sprintf("SELECT `id` FROM `posts_%s` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); - while($post = $query->fetch()) { + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $log[] = '' . sprintf($config['board_abbreviation'], $board['uri']) . ': Rebuilding thread #' . $post['id']; buildThread($post['id']); } diff --git a/mod.php b/mod.php index f641d371..6fc216f8 100644 --- a/mod.php +++ b/mod.php @@ -26,16 +26,18 @@ $pages = array( '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) '!^/log$!' => 'log', // modlog '!^/log/(\d+)$!' => 'log', // modlog - + '!^/users$!' => 'users', // manage users '!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm + '!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm '!^/rebuild$!' => 'rebuild', // rebuild static files '!^/ban$!' => 'ban', // new ban '!^/IP/([\w.:]+)$!' => 'ip', // view ip address '!^/IP/([\w.:]+)/remove_note/(\d+)$!' => 'ip_remove_note', // remove note from ip address + '!^/bans$!' => 'bans', // ban list '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post diff --git a/stylesheets/style.css b/stylesheets/style.css index d77f05b5..edebf0c1 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -68,15 +68,18 @@ form table input { } input[type="text"], input[type="password"], textarea { border: 1px solid #a9a9a9; - text-indent: 0px; + text-indent: 0; text-shadow: none; text-transform: none; word-spacing: normal; } form table tr td { text-align: left; - margin: 0px; - padding: 0px; + margin: 0; + padding: 0; +} +form table.mod tr td { + padding: 2px; } form table tr th { text-align: left; @@ -102,7 +105,7 @@ form table tr td div label { } p.fileinfo { display: block; - margin: 0px; + margin: 0; padding-right: 7em; } div.banner { @@ -326,7 +329,7 @@ div.pages form input { hr { border: none; border-top: 1px solid #B7C5D9; - height: 0px; + height: 0; clear: left; } div.boardlist { @@ -349,7 +352,7 @@ table.modlog { } table.modlog tr td { text-align: left; - margin: 0px; + margin: 0; padding: 4px 15px 0 0; } table.modlog tr th { diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html new file mode 100644 index 00000000..00b8a0f4 --- /dev/null +++ b/templates/mod/ban_list.html @@ -0,0 +1,74 @@ +{% if bans|count == 0 %} +

(There are no active bans.)

+{% else %} +
+ + + + + + + + + + {% for ban in bans %} + + + + + + + + + {% endfor %} +
{% trans %}IP address{% endtrans %}{% trans %}Reason{% endtrans %}{% trans %}Board{% endtrans %}{% trans %}Set{% endtrans %}{% trans %}Expires{% endtrans %}{% trans %}Staff{% endtrans %}
+ + {% if ban.real_ip %} + {{ ban.ip }} + {% else %} + {{ ban.ip|e }} + {% endif %} + + {% if ban.reason %} + {{ ban.reason }} + {% else %} + - + {% endif %} + + {% if ban.board %} + {{ config.board_abbreviation|sprintf(ban.board) }} + {% else %} + {% trans %}all boards{% endtrans %} + {% endif %} + + {{ ban.set|date(config.post_date) }} + + {% if ban.expires == 0 %} + never + {% else %} + {{ ban.expires|date(config.post_date) }} + {% if ban.expires > time() %} + ({{ ban.expires|until }}) + {% endif %} + {% endif %} + + {% if ban.username %} + {% if mod|hasPermission(config.mod.view_banstaff) %} + {{ ban.username|e }} + {% else %} + {% if mod|hasPermission(config.mod.view_banquestionmark) %} + ? + {% else %} + + {% endif %} + {% endif %} + {% else %} + deleted? + {% endif %} +
+ +

+ +

+
+{% endif %} diff --git a/templates/mod/new_pm.html b/templates/mod/new_pm.html index d694bc26..ece1325c 100644 --- a/templates/mod/new_pm.html +++ b/templates/mod/new_pm.html @@ -2,7 +2,7 @@ {% set username = 'me' %} {% endif %}#} -
+ @@ -14,7 +14,7 @@ - +
To
Message
diff --git a/templates/mod/pm.html b/templates/mod/pm.html new file mode 100644 index 00000000..511bcfef --- /dev/null +++ b/templates/mod/pm.html @@ -0,0 +1,41 @@ + + + + + {% if username %} + + {% else %} + + {% endif %} + + {% if to != mod.id %} + + + {% if to_username %} + + {% else %} + + {% endif %} + + {% endif %} + + + + + + + + +
From{{ username|e }}deleted?
To{{ to_username|e }}deleted?
Date{{ time|date(config.post_date) }}
Message{{ message }}
+ + +
-- cgit v1.3 From cc614e36b4135d5b8ac000bad8ed450df0e61ffe Mon Sep 17 00:00:00 2001 From: Michael Save Date: Mon, 16 Apr 2012 20:11:10 +1000 Subject: multiple improvements --- inc/mod/ban.php | 2 +- inc/mod/pages.php | 80 ++++++++++++++++++++++++++++++++++++--- mod.php | 11 +++++- templates/mod/dashboard.html | 10 +++++ templates/mod/debug/antispam.html | 42 ++++++++++++++++++++ templates/page.html | 2 +- 6 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 templates/mod/debug/antispam.html (limited to 'inc/mod/ban.php') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index e7110edf..4d73488f 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -80,7 +80,7 @@ function ban($mask, $reason, $length, $board) { $query->execute() or error(db_error($query)); - modLog('Created a new ban (#' . $pdo->lastInsertId() . ') for ' . utf8tohtml($mask) . ' with ' . ($reason ? 'reason: ' . $reason . '' : 'no reason')); + modLog('Created a new ban (#' . $pdo->lastInsertId() . ') for ' . utf8tohtml($mask) . ' with ' . ($reason ? 'reason: ' . utf8tohtml($reason) . '' : 'no reason')); } function unban($id) { diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 3c3c08a4..7e6cddfe 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -15,6 +15,7 @@ function mod_page($title, $template, $args) { echo Element('page.html', array( 'config' => $config, 'mod' => $mod, + 'hide_dashboard_link' => $template == 'mod/dashboard.html', 'title' => $title, 'body' => Element($template, array_merge( @@ -262,10 +263,12 @@ function mod_bans($page_no = 1) { $unban[] = $match[1]; } - query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); + if (!empty($unban)) { + query('DELETE FROM `bans` WHERE `id` = ' . implode(' OR `id` = ', $unban)) or error(db_error()); - foreach ($unban as $id) { - modLog("Removed ban #{$id}"); + foreach ($unban as $id) { + modLog("Removed ban #{$id}"); + } } header('Location: ?/bans', true, $config['redirect_http']); @@ -278,8 +281,8 @@ function mod_bans($page_no = 1) { $query = prepare("SELECT `bans`.*, `username` FROM `bans` INNER JOIN `mods` ON `mod` = `mods`.`id` WHERE `expires` = 0 OR `expires` > :time ORDER BY `set` DESC LIMIT :offset, :limit"); } $query->bindValue(':time', time(), PDO::PARAM_INT); - $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); - $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); + $query->bindValue(':limit', $config['mod']['banlist_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['banlist_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); $bans = $query->fetchAll(PDO::FETCH_ASSOC); @@ -295,6 +298,58 @@ function mod_bans($page_no = 1) { mod_page('Ban list', 'mod/ban_list.html', array('bans' => $bans, 'count' => $count)); } + +function mod_lock($board, $unlock, $post) { + global $config; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['lock'], $board)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('UPDATE `posts_%s` SET `locked` = :locked WHERE `id` = :id AND `thread` IS NULL', $board)); + $query->bindValue(':id', $post); + $query->bindValue(':locked', $unlock ? 0 : 1); + $query->execute() or error(db_error($query)); + + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + +function mod_sticky($board, $unsticky, $post) { + global $config; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['sticky'], $board)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('UPDATE `posts_%s` SET `sticky` = :sticky WHERE `id` = :id AND `thread` IS NULL', $board)); + $query->bindValue(':id', $post); + $query->bindValue(':sticky', $unsticky ? 0 : 1); + $query->execute() or error(db_error($query)); + + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + +function mod_bumplock($board, $unbumplock, $post) { + global $config; + + if (!openBoard($board)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['bumplock'], $board)) + error($config['error']['noaccess']); + + $query = prepare(sprintf('UPDATE `posts_%s` SET `sage` = :bumplock WHERE `id` = :id AND `thread` IS NULL', $board)); + $query->bindValue(':id', $post); + $query->bindValue(':bumplock', $unbumplock ? 0 : 1); + $query->execute() or error(db_error($query)); + + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); +} + function mod_delete($board, $post) { global $config, $mod; @@ -599,4 +654,19 @@ function mod_report_dismiss($id, $all = false) { header('Location: ?/reports', true, $config['redirect_http']); } +function mod_debug_antispam() { + $args = array(); + + $query = query('SELECT COUNT(*) FROM `antispam`') or error(db_error()); + $args['total'] = number_format($query->fetchColumn(0)); + + $query = query('SELECT COUNT(*) FROM `antispam` WHERE `expires` IS NOT NULL') or error(db_error()); + $args['expiring'] = number_format($query->fetchColumn(0)); + + $query = query('SELECT * FROM `antispam` /* WHERE `passed` > 0 */ ORDER BY `passed` DESC LIMIT 25') or error(db_error()); + $args['top'] = $query->fetchAll(PDO::FETCH_ASSOC); + + mod_page("Debug: Anti-spam", 'mod/debug/antispam.html', $args); +} + diff --git a/mod.php b/mod.php index 86169b59..8af74a7b 100644 --- a/mod.php +++ b/mod.php @@ -43,10 +43,17 @@ $pages = array( '!^/bans/(\d+)$!' => 'bans', // ban list '!^/(\w+)/delete/(\d+)$!' => 'delete', // delete post + '!^/(\w+)/(un)?lock/(\d+)$!' => 'lock', // lock thread + '!^/(\w+)/(un)?sticky/(\d+)$!' => 'sticky', // sticky thread + '!^/(\w+)/bump(un)?lock/(\d+)$!' => 'bumplock', // "bumplock" thread + + // these pages aren't listed in the dashboard without $config['debug'] + '!^/debug/antispam$!' => 'debug_antispam', // This should always be at the end: - '!^/(\w+)/' . preg_quote($config['file_index'], '!') . '?$!' => 'view_board', - '!^/(\w+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_board', + '!^/(\w+)/$!' => 'view_board', + '!^/(\w+)/' . preg_quote($config['file_index'], '!') . '$!' => 'view_board', + '!^/(\w+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_board', '!^/(\w+)/' . preg_quote($config['dir']['res'], '!') . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_thread', ); diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 2a90d709..e9290e12 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -79,3 +79,13 @@ {# TODO #} + +{% if config.debug %} +
+ Debug + +
+{% endif %} + diff --git a/templates/mod/debug/antispam.html b/templates/mod/debug/antispam.html new file mode 100644 index 00000000..af5354ed --- /dev/null +++ b/templates/mod/debug/antispam.html @@ -0,0 +1,42 @@ +

+ Most used (in active): +

+ + + + + + + + + + {% for hash in top %} + + + + + + + + + {% endfor %} +
BoardThreadHash (CRC32)CreatedExpiresPassed
{{ config.board_abbreviation|sprintf(hash.board) }} + {% if hash.thread %} + {{ hash.thread }} + {% else %} + - + {% endif %}{{ hash.hash }} + {{ hash.created|ago }} ago + + {% if hash.expires %} + + {{ hash.expires|until }} + + {% else %} + - + {% endif %} + {{ hash.passed }}
+

+ Total: {{ total }} ({{ expiring }} set to expire) +

+ diff --git a/templates/page.html b/templates/page.html index 39d73bbd..0c0264d1 100644 --- a/templates/page.html +++ b/templates/page.html @@ -17,7 +17,7 @@ {% if subtitle %} {{ subtitle }} {% endif %} - {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} + {% if mod and not hide_dashboard_link %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} {{ body }} -- cgit v1.3 From 2cc17f8d9b891701851580af9d0541f5657a7d49 Mon Sep 17 00:00:00 2001 From: Michael Save Date: Tue, 8 May 2012 00:42:17 +1000 Subject: more information in modlog for bans --- inc/mod/ban.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'inc/mod/ban.php') diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 4d73488f..51befe27 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -56,8 +56,6 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod, $pdo; - // TODO: permissions - $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); @@ -80,12 +78,14 @@ function ban($mask, $reason, $length, $board) { $query->execute() or error(db_error($query)); - modLog('Created a new ban (#' . $pdo->lastInsertId() . ') for ' . utf8tohtml($mask) . ' with ' . ($reason ? 'reason: ' . utf8tohtml($reason) . '' : 'no reason')); + modLog('Created a new ' . + ($length > 0 ? preg_replace('/^(\d+) (\w+?)s?$/', '$1-$2', until($length)) : 'permanent') . + ' ban (#' . $pdo->lastInsertId() . ') for ' . + (filter_var($mask, FILTER_VALIDATE_IP) !== false ? "$mask" : utf8tohtml($mask)) . + ' with ' . ($reason ? 'reason: ' . utf8tohtml($reason) . '' : 'no reason')); } -function unban($id) { - // TODO: permissions - +function unban($id) { $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query->bindValue(':id', $id); $query->execute() or error(db_error($query)); -- cgit v1.3