summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/mod/ban.php77
-rw-r--r--inc/mod/pages.php28
-rw-r--r--mod.php3
-rw-r--r--templates/mod/ban_form.html59
-rw-r--r--templates/mod/dashboard.html81
-rw-r--r--templates/mod/login.html26
-rw-r--r--templates/mod/view_ip.html18
7 files changed, 289 insertions, 3 deletions
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 @@
+<?php
+
+/*
+ * Copyright (c) 2010-2012 Tinyboard Development Group
+ */
+
+if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) {
+ // You cannot request this file directly.
+ exit;
+}
+
+function parse_time($str) {
+ if(empty($str))
+ return false;
+
+ 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))
+ return false;
+ $expire = time();
+
+ if (isset($m[2])) {
+ // Years
+ $expire += $m[2]*60*60*24*365;
+ }
+ if (isset($m[4])) {
+ // Months
+ $expire += $m[4]*60*60*24*30;
+ }
+ if (isset($m[6])) {
+ // Weeks
+ $expire += $m[6]*60*60*24*7;
+ }
+ if (isset($m[8])) {
+ // Days
+ $expire += $m[8]*60*60*24;
+ }
+ if (isset($m[10])) {
+ // Hours
+ $expire += $m[10]*60*60;
+ }
+ if (isset($m[12])) {
+ // Minutes
+ $expire += $m[12]*60;
+ }
+ if (isset($m[14])) {
+ // Seconds
+ $expire += $m[14];
+ }
+
+ return $expire;
+}
+
+function ban($mask, $reason, $length, $board) {
+ global $mod;
+
+ $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, UNIX_TIMESTAMP(), :expires, :reason, :board)");
+ $query->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));
+}
diff --git a/inc/mod/pages.php b/inc/mod/pages.php
index 9d154181..c00cd672 100644
--- a/inc/mod/pages.php
+++ b/inc/mod/pages.php
@@ -94,12 +94,17 @@ function mod_view_thread($boardName, $thread) {
function mod_page_ip($ip) {
global $config, $mod;
+ if(filter_var($ip, FILTER_VALIDATE_IP) === false)
+ error("Invalid IP address.");
+
$args = array();
$args['ip'] = $ip;
$args['posts'] = array();
$boards = listBoards();
foreach ($boards as $board) {
+ openBoard($board['uri']);
+
$query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `ip` = :ip ORDER BY `sticky` DESC, `id` DESC LIMIT :limit', $board['uri']));
$query->bindValue(':ip', $ip);
$query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT);
@@ -122,11 +127,30 @@ function mod_page_ip($ip) {
}
if (!isset($args['posts'][$board['uri']]))
- $args['posts'][$board['uri']] = array();
- $args['posts'][$board['uri']][] = $po->build(true);
+ $args['posts'][$board['uri']] = array('board' => $board, 'posts' => array());
+ $args['posts'][$board['uri']]['posts'][] = $po->build(true);
}
}
+ $args['boards'] = $boards;
+
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']);
+
+ $ip = $_POST['ip'];
+
+ require_once 'inc/mod/ban.php';
+
+ ban($_POST['ip'], $_POST['reason'], parse_time($_POST['length']), $_POST['board'] == '*' ? false : $_POST['board']);
+
+
+ if(isset($_POST['redirect']))
+ header('Location: ' . $_POST['redirect'], true, $config['redirect_http']);
+ else
+ header('Location: ?/', true, $config['redirect_http']);
+}
+
diff --git a/mod.php b/mod.php
index 0ac83f46..5f2cad56 100644
--- a/mod.php
+++ b/mod.php
@@ -25,10 +25,11 @@ $pages = array(
'!^/$!' => 'dashboard', // dashboard
'!^/IP/(.+)$!' => 'ip', // view ip address
+ '!^/ban$!' => 'ban', // new ban
// 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+)/' . 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/ban_form.html b/templates/mod/ban_form.html
new file mode 100644
index 00000000..1b94e725
--- /dev/null
+++ b/templates/mod/ban_form.html
@@ -0,0 +1,59 @@
+<form action="?/ban" method="post">
+ {% if redirect %}
+ <input type="hidden" name="redirect" value="{{ redirect|e }}">
+ {% endif %}
+
+ <table>
+ <tr>
+ <th>
+ <label for="ip">IP <span class="unimportant">(or subnet)</span></label>
+ </th>
+ <td>
+ <input type="text" name="ip" id="ip" size="30" maxlength="40" value="{{ ip }}">
+ </td>
+ </tr>
+ <tr>
+ <th>
+ <label for="reason">Reason</label>
+ </th>
+ <td>
+ <textarea name="reason" id="reason" rows="5" cols="30">{{ reason|e }}</textarea>
+ </td>
+ </tr>
+ <tr>
+ <th>
+ <label for="length">Length</label>
+ </th>
+ <td>
+ <input type="text" name="length" id="length" size="20" maxlength="40">
+ <span class="unimportant">(eg. "2d1h30m" or "2 days")</span></td>
+ </tr>
+ <tr>
+ <th>Board</th>
+ <td>
+ <ul style="list-style:none;padding:2px 5px">
+ <li>
+ <input type="radio" name="board" value="*" id="ban-allboards" checked>
+ <label style="display:inline" for="ban-allboards">
+ <em>all boards</em>
+ </label>
+ </li>
+
+ {% for board in boards %}
+ <li>
+ <input type="radio" name="board" value="{{ board.uri }}" id="ban-board-{{ board.uri }}">
+ <label style="display:inline" for="ban-board-{{ board.uri }}">
+ {{ config.board_abbreviation|sprintf(board.uri) }} - {{ board.title }}
+ </label>
+ </li>
+ {% endfor %}
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><input name="new_ban" type="submit" value="New Ban"></td>
+ </tr>
+ </table>
+</form>
+
diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html
new file mode 100644
index 00000000..2a90d709
--- /dev/null
+++ b/templates/mod/dashboard.html
@@ -0,0 +1,81 @@
+<fieldset>
+ <legend>Boards</legend>
+
+ <ul>
+ {% for board in boards %}
+ <li>
+ <a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board.uri) }}</a>
+ -
+ {{ board.title }}
+ {% if board.subtitle %}
+ <small>&mdash; {{ board.subtitle }}</small>
+ {% endif %}
+
+ {% if mod|hasPermission(config.mod.manageboards) %}
+ <a href="?/manage/{{ board.uri }}"><small>[manage]</small></a>
+ {% endif %}
+ </li>
+ {% endfor %}
+
+ {% if mod|hasPermission(config.mod.newboard) %}
+ <li style="margin-top:15px"><a href="?/new_board"><strong>Create new board</strong></a></li>
+ {% endif %}
+ </ul>
+</fieldset>
+
+{% if mod|hasPermission(config.mod.noticeboard) %}
+ <fieldset>
+ <legend>Noticeboard</legend>
+
+ {# TODO #}
+ </fieldset>
+{% endif %}
+
+<fieldset>
+ <legend>Administration</legend>
+
+ <ul>
+ {% if mod|hasPermission(config.mod.reports) %}
+ <li><a href="?/reports">Report queue</a></li>
+ {% endif %}
+
+ {% if mod|hasPermission(config.mod.view_banlist) %}
+ <li><a href="?/bans">Ban list</a></li>
+ {% endif %}
+
+ {% if mod|hasPermission(config.mod.manageusers) %}
+ <li><a href="?/users">Manage users</a></li>
+ {% elseif mod|hasPermission(config.mod.change_password) %}
+ <li><a href="?/users/{{ mod.id }}">Change password</a></li>
+ {% endif %}
+
+ {% if mod|hasPermission(config.mod.modlog) %}
+ <li><a href="?/log">Moderation log</a></li>
+ {% endif %}
+
+ {% if mod|hasPermission(config.mod.rebuild) %}
+ <li><a href="?/rebuild">Rebuild</a></li>
+ {% if config.cache.enabled %}
+ <li><a href="?/flushcache">Clear cache</a></li>
+ {% endif %}
+ {% endif %}
+
+ {% if mod|hasPermission(config.mod.show_config) %}
+ <li><a href="?/config">Configuration</a></li>
+ {% endif %}
+ </ul>
+</fieldset>
+
+{% if mod|hasPermission(config.mod.themes) %}
+ <fieldset>
+ <legend>Themes</legend>
+
+ {# TODO #}
+ </fieldset>
+{% endif %}
+
+<fieldset>
+ <legend>Search</legend>
+
+ {# TODO #}
+</fieldset>
diff --git a/templates/mod/login.html b/templates/mod/login.html
new file mode 100644
index 00000000..5ac308a3
--- /dev/null
+++ b/templates/mod/login.html
@@ -0,0 +1,26 @@
+{% if error %}<h2 style="text-align:center">{{ error }}</h2>{% endif %}
+<form action="" method="post">
+<table style="margin-top:25px;">
+ <tr>
+ <th>
+ {% trans %}Username{% endtrans %}
+ </th>
+ <td>
+ <input type="text" name="username" size="20" maxlength="30" value="{{ username|e }}">
+ </td>
+ </tr>
+ <tr>
+ <th>
+ {% trans %}Password{% endtrans %}
+ </th>
+ <td>
+ <input type="password" name="password" size="20" maxlength="30" value="">
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>
+ <input type="submit" name="login" value="{% trans %}Continue{% endtrans %}" />
+ </td>
+</table>
+</form>
diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html
new file mode 100644
index 00000000..3b558e4b
--- /dev/null
+++ b/templates/mod/view_ip.html
@@ -0,0 +1,18 @@
+{% for board_posts in posts %}
+ <fieldset>
+ <legend>
+ <a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board_posts.board.uri) }}</a>
+ -
+ {{ board_posts.board.title }}
+ </legend>
+ {{ board_posts.posts|join('<hr>') }}
+ </fieldset>
+{% endfor %}
+
+{% set redirect = '?/IP/' ~ ip %}
+
+<fieldset>
+ <legend>New ban</legend>
+ {% include 'mod/ban_form.html' %}
+</fieldset>
+