Index: common/ban.php
===================================================================
--- common/ban.php	(revision 0)
+++ common/ban.php	(revision 0)
@@ -0,0 +1,97 @@
+<?php
+
+require_once(IA_ROOT_DIR . "common/db/db.php");
+require_once(IA_ROOT_DIR . "common/user.php");
+
+// Add an entry in the user / ip table
+function user_ip_add($username, $userip) {
+    $safe_user = db_escape($username);
+    $safe_ip = db_escape($userip);
+    $query = db_fetch_all("SELECT * FROM ia_user_ip
+                           WHERE username = '$safe_user'
+                           AND userip = '$safe_ip'");
+    if (!$query) {
+        $query = db_query("INSERT INTO ia_user_ip (username, userip)
+                           VALUES ('$safe_user', '$safe_ip') ");
+    }
+}
+
+// The next two functions add a ban for a certain user
+function username_add_ban($username, $expire_date) {
+    $safe_user = db_escape($username);
+    db_query("INSERT INTO ia_ban_user (username, expire)
+              VALUES ('$safe_user', '$expire_date') ");
+}
+
+function userip_add_ban($userip, $expire_date) {
+    $safe_ip = db_escape($userip);
+    db_query("INSERT INTO ia_ban_ip (userip, expire)
+              VALUES ('$safe_ip', '$expire_date') ");
+}
+
+// The next two functions remove the ban for a certain user
+function username_remove_ban($username) {
+    $safe_user = db_escape($username);
+    db_query("DELETE FROM ia_ban_user
+              WHERE username = '$safe_user' ");
+}
+
+function userip_remove_ban($userip) {
+    $safe_ip = db_escape($userip);
+    db_query("DELETE FROM ia_ban_ip
+              WHERE userip = '$safe_ip' ");
+}
+
+//Returns the last ip adress used by a certain user
+function get_ip_from_username($username) {
+    $query = db_query("SELECT *
+                       FROM ia_user_ip
+                       WHERE username = '$username'
+                       ORDER BY id DESC");
+    $row = mysql_fetch_row($query);
+
+    if ($row != null) {
+        return $row['2'];
+    }
+    return "";
+}
+
+//Checks if the username or ip is banned
+function user_test_ban($username, $userip) {
+    $current_date = date("Y-m-d");
+    $is_banned = false;
+    $safe_user = db_escape($username);
+    $safe_ip = db_escape($userip);
+
+    $rows = db_fetch_all("SELECT *
+                          FROM ia_ban_user
+                          WHERE username = '$safe_user'
+                          AND expire > '$current_date'");
+    if ($rows != null)
+        $is_banned = true;
+
+    //Generates all possible ip addresses, using the '*' character
+    $ip = array();
+    for ($i = 0; $i < 16; $i++) {
+        $groups = explode(".", $safe_ip);
+
+        for ($j = 0; $j < 4; $j++)
+            if ($i & (1 << $j)) {
+                $groups[$j] = "*";
+            }
+
+        $ip[$i] = implode(".", $groups);
+    }
+
+    $rows = db_fetch_all("SELECT *
+                          FROM ia_ban_ip
+                          WHERE (userip = '$ip[0]' OR userip = '$ip[1]' OR userip = '$ip[2]' OR userip = '$ip[3]' OR userip = '$ip[4]' OR
+                                 userip = '$ip[5]' OR userip = '$ip[6]' OR userip = '$ip[7]' OR userip = '$ip[8]' OR userip = '$ip[9]' OR
+                                 userip = '$ip[10]' OR userip = '$ip[11]' OR userip = '$ip[12]') AND expire > '$current_date'");
+    if ($rows != null)
+       $is_banned = true;
+
+    return $is_banned;
+}
+
+?>
Index: common/lcs
===================================================================

Property changes on: common/lcs
___________________________________________________________________
Added: svn:executable
   + *
Added: svn:mime-type
   + application/octet-stream

Index: scripts/migrate-ban-ip.php
===================================================================
--- scripts/migrate-ban-ip.php	(revision 0)
+++ scripts/migrate-ban-ip.php	(revision 0)
@@ -0,0 +1,27 @@
+#! /usr/bin/env php
+<?php
+    //This script creates the two necessary tables for banning users
+    require_once(dirname($argv[0]) . "/utilities.php");
+    db_connect();
+
+    $query = "CREATE TABLE `ia_ban_user` (
+              `id` int NOT NULL AUTO_INCREMENT,
+              `username` VARCHAR(64) NOT NULL,
+              `expire` timestamp,
+              PRIMARY KEY (id))";
+    db_query($query);
+
+    $query = "CREATE TABLE `ia_ban_ip` (
+              `id` int NOT NULL AUTO_INCREMENT,
+              `userip` VARCHAR(64) NOT NULL,
+              `expire` timestamp,
+              PRIMARY KEY (id))";
+    db_query($query);
+
+    $query = "CREATE TABLE `ia_user_ip` (
+              `id` int NOT NULL AUTO_INCREMENT,
+              `username` VARCHAR(64) NOT NULL,
+              `userip` VARCHAR(64) NOT NULL,
+              PRIMARY KEY (id))";
+    db_query($query);
+?>

Property changes on: scripts/migrate-ban-ip.php
___________________________________________________________________
Added: svn:executable
   + *

Index: www/controllers/ban.php
===================================================================
--- www/controllers/ban.php	(revision 0)
+++ www/controllers/ban.php	(revision 0)
@@ -0,0 +1,62 @@
+<?php
+    require_once(IA_ROOT_DIR . "common/ban.php");
+    require_once(IA_ROOT_DIR . "common/db/db.php");
+    require_once(IA_ROOT_DIR . "common/user.php");
+    require_once(IA_ROOT_DIR . "common/common.php");
+    require_once(IA_ROOT_DIR . "www/url.php");
+
+    function controller_ban() {
+        global $identity_user;
+
+        if (user_is_admin($identity_user) == true) {
+            $view = array();
+            $view['title'] = 'Formular de banare';
+            $view['user'] = request('user');
+            $view['ip'] = request('ip');
+
+            // the data for banning is stored in an array
+            $data = array();
+
+            // this is where the validation errors are stored
+            $errors = array();
+
+            $submit = request_is_post();
+
+            if ($submit) {
+                //Validate data and place stuff in errors
+                $data['username'] = request('username');
+                $data['ip'] = request('ip');
+                $data['expire_date'] = request('expire_date');
+                $data['ban_username'] = request('ban_username');
+                $data['ban_userip'] = request('ban_userip');
+
+                $errors['valid_date'] = is_db_date($data['expire_date']);
+                $errors['select'] = $data['ban_username'] != "on" && $data['ban_userip'] != "on";
+
+                if ($errors['select']) {
+                    flash_error("Selectati un tip pentru ban!");
+                } else {
+                    if ($errors['valid_date'] == false) {
+                        flash_error('Reintroduceti data expirarii banului!');
+                    } else {
+                        if ($data['ban_username']) {
+                            username_add_ban($data['username'], $data['expire_date']);
+                        }
+
+                        if ($data['ban_userip']) {
+                            userip_add_ban($data['ip'], $data['expire_date']);
+                        }
+
+                        flash("Ban-ul a fost efectuat cu succes!");
+                    }
+                }
+            }
+
+            execute_view_die('views/ban.php', $view);
+        }
+        else {
+            flash_error("Nu ai permisiunile necesare pentru a accesa aceasta pagina!");
+            redirect(url_home());
+        }
+    }
+?>
Index: www/controllers/login.php
===================================================================
--- www/controllers/login.php	(revision 1150)
+++ www/controllers/login.php	(working copy)
@@ -1,6 +1,7 @@
 <?php
 
 require_once(IA_ROOT_DIR . "common/db/user.php");
+require_once(IA_ROOT_DIR . "common/ban.php");
 
 function controller_login() {
     global $identity_user;
@@ -21,7 +22,14 @@
         $data['username'] = getattr($_POST, 'username');
         $data['password'] = getattr($_POST, 'password');
         $data['remember'] = getattr($_POST, 'remember');
+        $data['userip'] = remote_ip_info();
+
         $user = user_test_password($data['username'], $data['password']);
+        $ban_user = user_test_ban($data['username'], $data['userip']);
+        if ($ban_user) {
+           $errors = true;
+        }
+
         if (!$user) {
             $user = user_test_ia1_password($data['username'], $data['password']);
             if (!$user) {
@@ -44,6 +52,9 @@
 
         // process
         if (!$errors) {
+            // add current data in the user / ip table necessary for banning
+            user_ip_add($data['username'], $data['userip']);
+
             // persist user to session (login)
             $remember_user = ($data['remember'] ? true : false);
             identity_start_session($user, $remember_user);
@@ -73,8 +84,13 @@
                 $_SESSION['_ia_redirect'] = $_SERVER['HTTP_REFERER'];
             }
 
-            flash_error('Numele de utilizator inexistent sau parola ' .
-                        'incorecta. Incearca din nou.');
+            if (!$user) {
+                flash_error('Numele de utilizator inexistent sau parola' .
+                            'incorecta. Incearca din nou!');
+            }
+            else {
+                flash_error('Contul sau IP-ul tau a fost suspendat!');
+            }
         }
     }
 
Index: www/index.php
===================================================================
--- www/index.php	(revision 1150)
+++ www/index.php	(working copy)
@@ -1,17 +1,24 @@
 <?php
+
 require_once("../config.php");
 require_once(IA_ROOT_DIR."www/config.php");
+
 require_once(IA_ROOT_DIR."common/log.php");
 require_once(IA_ROOT_DIR."common/common.php");
+require_once(IA_ROOT_DIR."common/security.php");
+require_once(IA_ROOT_DIR."common/ban.php");
+require_once(IA_ROOT_DIR."common/db/db.php");
+
 if (IA_DEVELOPMENT_MODE) {
     log_print("- -- --- ---- ----- Request: ".$_SERVER['QUERY_STRING']);
 }
 check_requirements();
-require_once(IA_ROOT_DIR."common/security.php");
+
+require_once(IA_ROOT_DIR.'www/format/list.php');
+
 require_once(IA_ROOT_DIR."www/url.php");
 require_once(IA_ROOT_DIR."www/utilities.php");
 require_once(IA_ROOT_DIR."www/identity.php");
-require_once(IA_ROOT_DIR."common/db/db.php");
 db_connect();
 
 // restore identity (if such a session exists)
@@ -32,7 +39,6 @@
     redirect(url_home());
 }
 
-
 // Prepare some vars for url handler.
 // Filter empty path elements. Strips extra '/'s
 $page = normalize_page_name($page);
@@ -48,17 +54,30 @@
 $directmaps = array_flip(array('register', 'changes',
                                'login', 'logout', 'json', 'job_detail',
                                'monitor', 'projector', 'submit', 'userinfo',
-                               'plot', 'search',
+                               'plot', 'search', 'ban',
                                'unsubscribe', 'resetpass', 'reeval'
 ));
 
+// Check if the current user is banned
+global $identity_user;
+
+$username = $identity_user['username'];
+$userip = remote_ip_info();
+
+$query = user_test_ban($username, $userip);
+
+if ($username != null && $query == true) {
+    flash_error("Tocmai ai fost banat! :)");
+    identity_end_session();
+}
+
 //
 // Here comes the big url mapper.
 // We include in the if statement to avoid an extra parsing load.
 //
 
 // Trivial direct mappings
-if (isset($directmaps[$urlstart])) {
+else if (isset($directmaps[$urlstart])) {
     require_once(IA_ROOT_DIR."www/controllers/{$urlstart}.php");
     $fname = "controller_{$urlstart}";
     $fname($page_id);
Index: www/static/css/screen.css
===================================================================
--- www/static/css/screen.css	(revision 1150)
+++ www/static/css/screen.css	(working copy)
@@ -944,6 +944,16 @@
     text-decoration: underline;
 }
 
+.htabs li.ban a {
+    background: #e44;
+    color: white;
+}
+
+.htabs li.ban a:hover {
+    background: #f23;
+    color: #000;
+}
+
 /* horizontal tabs, level 2 */
 ul.htabs-2 {
     padding: 0.9pt 3pt;
Index: www/static/images/ban.png
===================================================================

Property changes on: www/static/images/ban.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: www/static/images/icons/ban.png
===================================================================

Property changes on: www/static/images/icons/ban.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: www/url.php
===================================================================
--- www/url.php	(revision 1150)
+++ www/url.php	(working copy)
@@ -387,6 +387,14 @@
     return IA_SMF_URL;
 }
 
+function url_ban($options = array()) {
+    return url_complex("ban", $options);
+}
+
+function url_ban_details($options = array()) {
+    return url_complex("ban_details", $options);
+}
+
 // Newsletter
 
 function url_newsletter($page_name, $rev = null) {
Index: www/utilities.php
===================================================================
--- www/utilities.php	(revision 1150)
+++ www/utilities.php	(working copy)
@@ -73,7 +73,7 @@
 // printing stuff too early or you're trying to redirect too late (view?).
 // Either way, it is a bug and it must be solved rather than handled gracefully
 //
-// FIXME: bool to se ia_redirect to REQUEST_URI? might be usefull.
+// FIXME: bool to see ia_redirect to REQUEST_URI? might be usefull.
 function redirect($absolute_url) {
     header("Location: {$absolute_url}\n\n");
     session_write_close();
Index: www/views/ban.php
===================================================================
--- www/views/ban.php	(revision 0)
+++ www/views/ban.php	(revision 0)
@@ -0,0 +1,13 @@
+<?php
+    global $identity_user;
+
+    require_once(IA_ROOT_DIR.'www/format/list.php');
+    require_once(IA_ROOT_DIR.'www/url.php');
+
+    include('header.php');
+
+    echo format_tag('h1', html_escape($view['title']));
+    include(IA_ROOT_DIR.'www/views/form_ban.php');
+
+    include('footer.php');
+?>
Index: www/views/form_ban.php
===================================================================
--- www/views/form_ban.php	(revision 0)
+++ www/views/form_ban.php	(revision 0)
@@ -0,0 +1,37 @@
+<form action="<?= html_escape(url_ban()) ?>" method="post" class="ban">
+<fieldset>
+    <legend><img src="<?= html_escape(url_static('images/ban.png')) ?>" alt="!" /> </legend>
+    <ul class="form">
+
+<?= format_open_tag("li", array("id" => "field_username_ban")) ?>
+<?= format_tag("label", "Contul utilizatorului", array("for" => "form_username_ban")) ?>
+<?= format_tag("input", "", array("value" => $view['user'], "type" => "text", "name" => "username", "id" => "form_username_ban")) ?>
+
+<?= format_open_tag("li", array("id" => "field_ip_ban")) ?>
+<?= format_tag("label", "IP-ul <br />
+                Poti bana toate ip-urile ce contin un anume subdomeniu. <br />
+                Pentru a realiza aceasta, inlocuieste un grup de cifre cu caracterul \"*\". <br />
+                De exemplu, daca introduci secventa \"192.168.0.*\", atunci vei bana toate ipurile de forma \"192.168.0.0\", \"192.168.0.1\" ... \"192.168.0.255\".", array("for" => "form_IP_ban"), false) ?>
+<?= format_tag("input", "", array("value" => $view['ip'], "type" => "text", "name" => "ip", "id" => "form_ip_ban")) ?>
+
+<?= view_form_field_li(array(
+        'name' => 'Data expirarii banului (in format YYYY-MM-DD).',
+        'type' => 'string',
+        'access_key' => 'd',
+), 'expire_date') ?>
+
+        <li>
+			<input type="checkbox" value="on" id="form_remember" name="ban_username" class="checkbox"<?= fval('ban_username') ? ' checked="checked"' : '' ?>/>
+			<label class="checkbox"> ban pe username</label>
+
+			<br/>
+
+			<input type="checkbox" value="on" id="form_remember" name="ban_userip" class="checkbox"<?= fval('ban_username') ? ' checked="checked"' : '' ?>/>
+			<label class="checkbox"> ban pe ip</label>
+        </li>
+        <li>
+            <input type="submit" value="Baneaza!" id="form_submit" class="button important" />
+        </li>
+    </ul>
+</fieldset>
+</form>
Index: www/views/user.php
===================================================================
--- www/views/user.php	(revision 1150)
+++ www/views/user.php	(working copy)
@@ -2,9 +2,15 @@
 require_once(IA_ROOT_DIR.'www/wiki/wiki.php');
 require_once(IA_ROOT_DIR.'www/format/format.php');
 require_once(IA_ROOT_DIR.'www/format/list.php');
+require_once(IA_ROOT_DIR.'www/url.php');
 
+require_once(IA_ROOT_DIR.'common/ban.php');
 require_once(IA_ROOT_DIR.'common/tags.php');
+require_once(IA_ROOT_DIR.'common/user.php');
+require_once(IA_ROOT_DIR.'common/db/db.php');
 
+global $identity_user;
+
 $username = $user['username'];
 
 // site header
@@ -19,6 +25,13 @@
     'rating' => format_link(url_user_rating($username), 'Rating'),
     'stats' => format_link(url_user_stats($username), 'Statistici'),
 );
+
+if (user_is_admin($identity_user) == true) {
+    $ip = get_ip_from_username($username);
+    $options['ban'] = array(format_link(url_ban(array("user" => $username,
+                      "ip" => $ip)), 'Baneaza!'), array('class' => 'ban'));
+}
+
 // mark selected action with class 'active'
 $options[$action] = array($options[$action], array('class' => 'active'));
 echo format_ul($options, 'htabs');
