Merge branch 'spamadmin'

This commit is contained in:
Claude 2012-09-01 20:03:56 +02:00
commit 1b6f409b88
10 changed files with 447 additions and 2 deletions

View File

@ -245,7 +245,7 @@ $config['encryption_key'] = '';
|
*/
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_expiration'] = 60*60*24*1;
$config['sess_expire_on_close'] = FALSE;
$config['sess_encrypt_cookie'] = FALSE;
$config['sess_use_database'] = TRUE;

View File

@ -52,6 +52,10 @@ $route['view/:any'] = 'main/view';
$route['lists'] = 'main/lists';
$route['lists/rss'] = 'main/lists/rss';
$route['lists/:num'] = 'main/lists/$1';
$route['spamadmin/:num'] = 'spamadmin/index';
$route['spamadmin/blacklist/unblock/(:any)'] = 'spamadmin/unblock_ip';
$route['spamadmin/blacklist'] = 'spamadmin/blacklist';
$route['spamadmin/:any'] = 'spamadmin/spam_detail';
$route['about'] = 'main/about';
$route['iphone/:num'] = 'iphone';

View File

@ -72,6 +72,9 @@ $config['per_page'] = 10;
**/
$config['private_only'] = false;
$config['enable_captcha'] = false;
//spamadmin: accessible via /spamadmin (only active when user + pass is set)
$config['spamadmin_user'] = '';
$config['spamadmin_pass'] = '';
/**
* Default language

View File

@ -16,6 +16,7 @@
* - captcha()
* - _valid_lang()
* - _valid_captcha()
* - _valid_ip()
* - get_cm_js()
* - error_404()
* Classes list:
@ -120,6 +121,11 @@ class Main extends CI_Controller
'type' => 'VARCHAR',
'constraint' => 8,
) ,
'ip_address' => array(
'type' => 'VARCHAR',
'constraint' => 16,
'null' => TRUE,
) ,
);
$this->dbforge->add_field($fields);
$this->dbforge->add_key('id', true);
@ -127,8 +133,76 @@ class Main extends CI_Controller
$this->dbforge->add_key('private');
$this->dbforge->add_key('replyto');
$this->dbforge->add_key('created');
$this->dbforge->add_key('ip_address');
$this->dbforge->create_table('pastes', true);
}
if (!$this->db->table_exists('blocked_ips'))
{
$this->load->dbforge();
$fields = array(
'ip_address' => array(
'type' => 'VARCHAR',
'constraint' => 16,
'default' => 0,
) ,
'blocked_at' => array(
'type' => 'INT',
'constraint' => 10,
) ,
'spam_attempts' => array(
'type' => 'INT',
'constraint' => 6,
'default' => 0,
) ,
);
$this->dbforge->add_field($fields);
$this->dbforge->add_key('ip_address', true);
$this->dbforge->create_table('blocked_ips', true);
}
if (!$this->db->field_exists('ip_address', 'pastes'))
{
$this->load->dbforge();
$fields = array(
'ip_address' => array(
'type' => 'VARCHAR',
'constraint' => 16,
'null' => TRUE,
) ,
);
$this->dbforge->add_column('pastes', $fields);
}
//todo: remove that after migration
if (!$this->db->field_exists('blocked_at', 'blocked_ips'))
{
$this->load->dbforge();
$fields = array(
'blocked_at' => array(
'type' => 'INT',
'constraint' => 10,
) ,
);
$this->dbforge->add_column('blocked_ips', $fields);
}
if (!$this->db->field_exists('spam_attempts', 'blocked_ips'))
{
$this->load->dbforge();
$fields = array(
'spam_attempts' => array(
'type' => 'INT',
'constraint' => 6,
'default' => 0,
) ,
);
$this->dbforge->add_column('blocked_ips', $fields);
}
//end todo
}
function _form_prep($lang = false, $title = '', $paste = '', $reply = false)
@ -220,6 +294,11 @@ class Main extends CI_Controller
'label' => 'Captcha',
'rules' => 'callback__valid_captcha',
) ,
array(
'field' => 'valid_ip',
'label' => 'Valid IP',
'rules' => 'callback__valid_ip',
) ,
);
//form validation
@ -441,6 +520,44 @@ class Main extends CI_Controller
}
}
function _valid_ip()
{
//get ip
$ip_address = $this->input->ip_address();
$ip = explode('.', $ip_address);
$ip_firstpart = $ip[0] . '.' . $ip[1] . '.';
//setup message
$this->form_validation->set_message('_valid_ip', 'You are not allowed to paste.');
//lookup
$this->db->select('ip_address, spam_attempts');
$this->db->like('ip_address', $ip_firstpart, 'after');
$query = $this->db->get('blocked_ips');
//check
if ($query->num_rows() > 0)
{
//update spamcount
$blocked_ips = $query->result_array();
$spam_attempts = $blocked_ips[0]['spam_attempts'];
$this->db->where('ip_address', $ip_address);
$this->db->update('blocked_ips', array(
'spam_attempts' => $spam_attempts + 1,
));
//return for the validation
return false;
}
else
{
return true;
}
}
function get_cm_js()
{
$lang = $this->uri->segment(3);

View File

@ -0,0 +1,97 @@
<?php
/**
* Class and Function List:
* Function list:
* - __construct()
* - index()
* - spam_detail()
* - blacklist()
* - unblock_ip()
* Classes list:
* - Spamadmin extends CI_Controller
*/
class Spamadmin extends CI_Controller
{
function __construct()
{
parent::__construct();
//protection
$user = $this->config->item('spamadmin_user');
$pass = $this->config->item('spamadmin_pass');
if ($user == '' || $pass == '' || !isset($_SERVER['PHP_AUTH_USER']) || $_SERVER['PHP_AUTH_USER'] != $user || $_SERVER['PHP_AUTH_PW'] != $pass)
{
header('WWW-Authenticate: Basic realm="Spamadmin"');
header('HTTP/1.0 401 Unauthorized');
exit;
}
}
function index()
{
$this->load->model('pastes');
$data = $this->pastes->getSpamLists();
$this->load->view('list_ips', $data);
}
function spam_detail()
{
$this->load->model('pastes');
$ip_address = $this->uri->segment(2);
if ($this->input->post('confirm_remove') && $ip_address != '')
{
$this->db->where('ip_address', $ip_address);
$this->db->delete('pastes');
$paste_count = $this->db->affected_rows();
if ($this->input->post('block_ip'))
{
$query = $this->db->get_where('blocked_ips', array(
'ip_address' => $ip_address
));
if ($query->num_rows() == 0)
{
$this->db->insert('blocked_ips', array(
'ip_address' => $ip_address,
'blocked_at' => mktime() ,
'spam_attempts' => $paste_count,
));
}
}
}
//fill data
$data = $this->pastes->getSpamLists('spamadmin/' . $ip_address, $seg = 3, $ip_address);
$data['ip_address'] = $ip_address;
$ip = explode('.', $ip_address);
$ip_firstpart = $ip[0] . '.' . $ip[1] . '.';
$data['ip_range'] = $ip_firstpart . '*.*';
//view
$this->load->view('spam_detail', $data);
}
function blacklist()
{
$this->db->select('ip_address, blocked_at, spam_attempts');
$this->db->order_by('blocked_at desc, ip_address asc');
$query = $this->db->get('blocked_ips');
$data['blocked_ips'] = $query->result_array();
//view
$this->load->view('list_blocked_ips', $data);
}
function unblock_ip()
{
$ip_address = $this->uri->segment(4);
$this->db->where('ip_address', $ip_address);
$this->db->delete('blocked_ips');
redirect('spamadmin/blacklist');
}
}

View File

@ -10,6 +10,7 @@
* - getPaste()
* - getReplies()
* - getLists()
* - getSpamLists()
* - cron()
* Classes list:
* - Pastes extends CI_Model
@ -23,9 +24,14 @@ class Pastes extends CI_Model
parent::__construct();
}
function countPastes()
function countPastes($ip_address = false)
{
$this->db->where('private', 0);
if ($ip_address)
{
$this->db->where('ip_address', $ip_address);
}
$query = $this->db->get('pastes');
return $query->num_rows();
}
@ -148,6 +154,7 @@ class Pastes extends CI_Model
$data['snipurl'] = false;
}
}
$data['ip_address'] = $this->input->ip_address();
$this->db->insert('pastes', $data);
return 'view/' . $data['pid'];
}
@ -365,6 +372,67 @@ class Pastes extends CI_Model
return $data;
}
function getSpamLists($root = 'spamadmin/', $seg = 2, $ip_address = false)
{
$this->load->library('pagination');
$this->load->library('process');
$amount = $this->config->item('per_page');
if (!$this->uri->segment($seg))
{
$page = 0;
}
else
{
$page = $this->uri->segment($seg);
}
$this->db->select('id, title, name, created, pid, lang, ip_address');
$this->db->where('private', 0);
if ($ip_address)
{
$this->db->where('ip_address', $ip_address);
}
$this->db->order_by('created', 'desc');
$query = $this->db->get('pastes', $amount, $page);
if ($query->num_rows() > 0)
{
$n = 0;
foreach ($query->result_array() as $row)
{
$data['pastes'][$n]['id'] = $row['id'];
$data['pastes'][$n]['title'] = $row['title'];
$data['pastes'][$n]['name'] = $row['name'];
$data['pastes'][$n]['created'] = $row['created'];
$data['pastes'][$n]['lang'] = $row['lang'];
$data['pastes'][$n]['pid'] = $row['pid'];
$data['pastes'][$n]['ip_address'] = $row['ip_address'];
$n++;
}
}
//pagination
$config['base_url'] = site_url($root);
$config['total_rows'] = $this->countPastes($ip_address);
$config['per_page'] = $amount;
$config['num_links'] = 9;
$config['full_tag_open'] = '<div class="pages">';
$config['full_tag_close'] = '</div>';
$config['uri_segment'] = $seg;
$this->pagination->initialize($config);
$data['pages'] = $this->pagination->create_links();
//total spam attempts
$this->db->select('SUM(spam_attempts) as sum');
$query = $this->db->get('blocked_ips');
$q = $query->result_array();
$data['total_spam_attempts'] = ($q[0]['sum'] != '' ? $q[0]['sum'] : 0);
//return
return $data;
}
function cron()
{
$now = now();

View File

@ -0,0 +1,45 @@
<?php $this->load->view('defaults/header');?>
<h1><a href="<?php echo site_url('spamadmin'); ?>">Spamadmin</a> - blacklist</h1>
<?php
function checkNum($num){
return ($num%2) ? TRUE : FALSE;
}
$n = 0;
if(!empty($blocked_ips)){ ?>
<table class="recent">
<tbody>
<tr>
<th class="title">IP range</th>
<th class="time">When</th>
<th class="time">Spam attempts</th>
<th class="name">Unblock IP</th>
</tr>
<?php foreach($blocked_ips as $ip_address){
if(checkNum($n) == TRUE) {
$eo = "even";
} else {
$eo = "odd";
}
$n++;
$ip = explode('.', $ip_address['ip_address']);
$ip_firstpart = $ip[0] . '.' . $ip[1] . '.';
$ip_range = $ip_firstpart . '*.*';
?>
<tr class="<?php echo $eo; ?>">
<td class="first"><?php echo $ip_range; ?></td>
<td><?php $p = explode(",", timespan($ip_address['blocked_at'], time())); echo $p[0]; ?> ago.</td>
<td><?php echo $ip_address['spam_attempts']; ?></td>
<td><a href="<?php echo site_url('spamadmin/blacklist/unblock/' . $ip_address['ip_address']) ?>">Unblock</a></td>
</tr>
<?php }?>
</tbody>
</table>
<?php } else { ?>
<p>No IP ranges blocked.</p>
<?php }?>
<?php echo $pages; ?>
<div class="spacer"></div>
<?php $this->load->view('defaults/footer');?>

View File

@ -0,0 +1,45 @@
<?php $this->load->view('defaults/header');?>
<h1>Spamadmin</h1>
<p><?php echo $total_spam_attempts; ?> spam-pastes eaten so far. <a href="<?php echo site_url('spamadmin/blacklist'); ?>">View blocked IPs</a>.</p>
<?php
function checkNum($num){
return ($num%2) ? TRUE : FALSE;
}
$n = 0;
if(!empty($pastes)){ ?>
<table class="recent">
<tbody>
<tr>
<th class="title">Title</th>
<th class="name">Name</th>
<th class="lang">Language</th>
<th class="time">When</th>
<th class="time">IP</th>
</tr>
<?php foreach($pastes as $paste) {
if(checkNum($n) == TRUE) {
$eo = "even";
} else {
$eo = "odd";
}
$n++;
?>
<tr class="<?php echo $eo; ?>">
<td class="first"><a href="<?php echo site_url("view/".$paste['pid']); ?>"><?php echo $paste['title']; ?></a></td>
<td><?php echo $paste['name']; ?></td>
<td><?php echo $paste['lang']; ?></td>
<td><?php $p = explode(",", timespan($paste['created'], time())); echo $p[0]; ?> ago.</td>
<td><a href="<?php echo site_url('spamadmin/' . $paste['ip_address']) ?>"><?php echo $paste['ip_address']; ?></a></td>
</tr>
<?php }?>
</tbody>
</table>
<?php } else { ?>
<p>There have been no pastes :(</p>
<?php }?>
<?php echo $pages; ?>
<div class="spacer"></div>
<?php $this->load->view('defaults/footer');?>

View File

@ -0,0 +1,58 @@
<?php $this->load->view('defaults/header');?>
<h1><a href="<?php echo site_url('spamadmin'); ?>">Spamadmin</a> - Pastes for ip <?php echo $ip_address; ?></h1>
<div class="space">&nbsp;</div>
<div class="form_wrapper">
<form action="" method="post">
<input class="dangerbutton" type="submit" name="confirm_remove" value="Remove of all pastes below" />
<label for="block_ip">Block IP range
<span class="instruction">(<?php echo $ip_range; ?>)</span>
</label>
<div class="text_beside">
<input type="checkbox" id="block_ip" name="block_ip" value="1" checked="checked" />
</div>
</form>
</div>
<div class="space"></div>
<?php
function checkNum($num){
return ($num%2) ? TRUE : FALSE;
}
$n = 0;
if(!empty($pastes)){ ?>
<table class="recent">
<tbody>
<tr>
<th class="title">Title</th>
<th class="name">Name</th>
<th class="lang">Language</th>
<th class="time">When</th>
</tr>
<?php foreach($pastes as $paste) {
if(checkNum($n) == TRUE) {
$eo = "even";
} else {
$eo = "odd";
}
$n++;
?>
<tr class="<?php echo $eo; ?>">
<td class="first"><a href="<?php echo site_url("view/".$paste['pid']); ?>"><?php echo $paste['title']; ?></a></td>
<td><?php echo $paste['name']; ?></td>
<td><?php echo $paste['lang']; ?></td>
<td><?php $p = explode(",", timespan($paste['created'], time())); echo $p[0]; ?> ago.</td>
</tr>
<?php }?>
</tbody>
</table>
<?php } else { ?>
<p class="clear">There have been no pastes :(</p>
<?php }?>
<?php echo $pages; ?>
<div class="spacer"></div>
<?php $this->load->view('defaults/footer');?>

View File

@ -254,6 +254,10 @@ h4 {
margin-top: 20px;
}
.form_wrapper .dangerbutton:hover {
background: #f00;
}
.form_wrapper .message_wrapper .message {
margin-top: -10px;
}
@ -263,6 +267,10 @@ h4 {
height: 1px;
}
.clear {
clear: both;
}
.explain {
font-size: 12px;
color: #666;