Commit 08b9055d authored by Hugo Leisink's avatar Hugo Leisink

Release 0.7

parent 0749693e
monitor (0.7) stable; urgency=low
* Graph layout adepts to amount of monitor days.
* Added CGI statistics module.
* Dropped support for request monitoring.
* Support for Prowl notifications.
* Improved menu library.
* Account activity overview added to profile module.
* Small improvements.
-- Hugo Leisink <hugo@leisink.net> Wed, 23 Apr 2014 21:10:07 +0200
monitor (0.6) stable; urgency=low
* Host statistics module made faster.
......
......@@ -17,6 +17,14 @@
"Webservers" => array("admin/webserver", "webserver.png")));
public function execute() {
if (($this->user->id == 1) && ($this->user->password == "08b5411f848a2581a41672a759c87380")) {
$this->output->add_system_message("Don't forget to change the password of the admin account!");
}
if ($this->page->pathinfo[1] != null) {
$this->output->add_system_message("The administration module '%s' does not exist.", $this->page->pathinfo[1]);
}
if (is_true(DEBUG_MODE)) {
$this->output->add_system_message("Website is running in debug mode. Set DEBUG_MODE in settings/website.conf to 'no'.");
}
......
<?php
class admin_menu_controller extends controller {
private $url = null;
private function show_menu_form($menu_id, $menu) {
$this->output->add_javascript("jquery/jquery.js");
$this->output->add_javascript("jquery/ui.core.js");
$this->output->add_javascript("jquery/ui.widget.js");
$this->output->add_javascript("jquery/ui.mouse.js");
$this->output->add_javascript("jquery/ui.sortable.js");
$this->output->add_javascript("admin/menu.js");
$this->output->open_tag("edit");
if (($parent = $this->model->get_menu($menu_id)) != false) {
$this->output->add_tag("parent", $parent["text"], array("id" => $parent["parent_id"]));
private function show_menu($menu) {
if (is_array($menu) == false) {
$menu = array();
}
$this->output->open_tag("menu", array("id" => $menu_id));
$max_id = 0;
$this->output->open_tag("branch");
foreach ($menu as $item) {
unset($item["parent_id"]);
$this->output->record($item, "item");
if ($item["id"] > $max_id) {
$max_id = $item["id"];
$this->output->open_tag("item");
$this->output->add_tag("text", $item["text"]);
$this->output->add_tag("link", $item["link"]);
if (isset($item["submenu"])) {
$this->show_menu($item["submenu"]);
}
$this->output->close_tag();
}
$this->output->close_tag();
$this->output->add_tag("max_menu_id", $max_id + 1);
$this->output->close_tag();
}
if (count($menu) == 0) {
$this->output->onload_javascript("add_item('editmenu', 1)");
}
private function show_menu_form($menu) {
$this->output->add_javascript("jquery/jquery.js");
$this->output->add_javascript("jquery/jquery-ui.js");
$this->output->add_javascript("jquery/jquery.menueditor.js");
$this->output->add_javascript("admin/menu.js");
$this->output->add_css("includes/menueditor.css");
$this->output->open_tag("edit");
$this->show_menu($menu);
$this->output->close_tag();
}
public function execute() {
$this->url = array("url" => "admin/menu");
if ($_SERVER["REQUEST_METHOD"] == "POST") {
/* Update menu
*/
if ($this->model->menu_oke($_POST) == false) {
foreach ($_POST["menu"] as $id => $value) {
$_POST["menu"][$id]["id"] = $id;
}
$this->show_menu_form($_POST["menu_id"], $_POST["menu"]);
} else if ($this->model->update_menu($_POST["menu_id"], $_POST["menu"]) == false) {
$this->output->add_tag("result", "Error while updating menu.", $url);
if ($this->model->menu_oke($_POST["menu"]) == false) {
$this->show_menu_form($_POST["menu"]);
} else if ($this->model->update_menu($_POST["menu"]) == false) {
$this->output->add_tag("result", "Error while updating menu.");
} else {
$this->output->add_tag("result", "The menu has been updated.", array("url" => "admin/menu/".$_POST["menu_id"]));
$this->output->remove_from_cache("menu");
$this->user->log_action("menu ".$_POST["menu_id"]." updated");
$this->output->add_tag("result", "The menu has been updated.");
$this->user->log_action("menu updated");
header("X-Hiawatha-Cache-Remove: all");
$cache = new cache($this->db, "menu");
$cache->store("last_updated", time(), 365 * DAY);
}
} else {
/* Show menu
*/
if (valid_input($this->page->pathinfo[2], VALIDATE_NUMBERS, VALIDATE_NONEMPTY) == false) {
$menu_id = 0;
} else if (($menu_id = (int)$this->page->pathinfo[2]) != 0) {
if (($parent = $this->model->get_menu($menu_id)) == false) {
$this->output->add_tag("result", "Menu not found.", $url);
return;
}
}
if (($menu = $this->model->get_menu_items($menu_id)) === false) {
$this->output->add_tag("result", "Database error!", $url);
} else {
$this->show_menu_form($menu_id, $menu);
if (($menu = $this->model->get_menu()) === false) {
$this->output->add_tag("result", "Error loading menu.");
} else {
$this->show_menu_form($menu);
}
}
}
......
......@@ -8,5 +8,31 @@
protected $pagination_links = 7;
protected $pagination_step = 1;
protected $foreign_null = "---";
protected function show_item_form($item) {
if ((is_true(DEBUG_MODE) == false) && isset($item["id"])) {
if (($current = $this->model->get_item($item["id"])) === false) {
$this->output->add_tag("result", "Database error.");
return false;
}
$this->output->add_javascript("jquery/jquery.js");
$this->output->add_javascript("admin/settings.js");
$this->output->open_tag("label");
$this->output->add_tag("key", $current["key"]);
$this->output->add_tag("type", $current["type"]);
$this->output->close_tag();
}
parent::show_item_form($item);
}
protected function handle_submit() {
parent::handle_submit();
$cache = new cache($this->db, "settings");
$cache->store("last_updated", time(), 365 * DAY);
}
}
?>
<?php
if (valid_input($_page->pathinfo[1], VALIDATE_NUMBERS, VALIDATE_NONEMPTY) == false) {
$_output->add_tag("result", "Host missing.", array("url" => "homepage"));
} else if (($hostname = get_hostname($db, $_page->pathinfo[1])) == false) {
$_output->add_tag("result", "Host not found.", array("url" => "homepage"));
} else {
$period = ALERTS_PERIOD." hours";
$timestamp = date("Y-m-d H:i:s", strtotime("-".$period));
if (($uris = get_not_founds($db, $_page->pathinfo[1], $timestamp)) !== false) {
$_output->open_tag("uris");
foreach ($uris as $uri) {
$_output->record($uri, "uri");
}
$_output->close_tag();
}
}
?>
<?php
define("PIXELS", 580);
class browser_with_os_controller extends controller {
public function execute() {
$filter = new filter($this->db, $this->output);
$filter->to_output("requests", true);
if (($info = $this->model->get_information($filter->hostname, $filter->webserver)) === false) {
$this->output->add_tag("result", "Database error.");
return;
}
if ($filter->browser_version == false) {
$info = $this->model->remove_browser_version($info);
}
$max = 0;
foreach ($info as $item) {
if ($item["count"] > $max) {
$max = $item["count"];
}
}
$this->output->add_tag("max", $max);
$this->output->open_tag("info", array("label" => "Web browser with Operating System"));
foreach ($info as $item) {
$count = $max == 0 ? 0 : (int)(PIXELS * $item["count"] / $max);
if ($count < $this->settings->browser_os_min_count) {
continue;
}
$this->output->add_tag("item", $item["info"], array("count" => $count));
}
$this->output->close_tag();
}
}
?>
<?php
class cgi_statistics_controller extends graph_controller {
protected $graphs = array(
"time_0_1" => "0 - 1 second",
"time_1_3" => "1 - 3 seconds",
"time_3_10" => "3 - 10 seconds",
"time_10_x" => "More than 10 seconds");
}
?>
<?php
class homepage_controller extends controller {
class dashboard_controller extends controller {
public function execute() {
/* Webserver
*/
$webservers = $this->model->get_webservers();
foreach ($webservers as $webserver) {
$webserver["address"] = ($webserver["ssl"] == 0 ? "http" : "https") . "://".$webserver["ip_address"];
if ((($webserver["ssl"] == 0) && ($webserver["port"] != 80)) ||
(($webserver["ssl"] == 1) && ($webserver["port"] != 443))) {
$webserver["address"] .= ":".$webserver["port"];
}
$webserver["address"] .= "/";
$webserver["ssl"] = show_boolean($webserver["ssl"]);
$webserver["active"] = show_boolean($webserver["active"]);
......
<?php
define("PIXELS", 730);
class operating_system_controller extends controller {
public function execute() {
$filter = new filter($this->db, $this->output);
$filter->to_output("requests");
if (($info = $this->model->get_information($filter->hostname, $filter->webserver)) === false) {
$this->output->add_tag("result", "Database error.");
return;
}
$max = 0;
foreach ($info as $browser) {
if ($browser["count"] > $max) {
$max = $browser["count"];
}
}
$this->output->add_tag("max", $max);
/* Operating Systems
*/
$this->output->open_tag("info", array("label" => "Operating Systems"));
foreach ($info as $os) {
$count = $max == 0 ? 0 : (int)(PIXELS * $os["count"] / $max);
$this->output->add_tag("item", $os["os"], array("count" => $count));
}
$this->output->close_tag();
}
}
?>
<?php
define("PIXELS", 730);
class origins_controller extends controller {
public function execute() {
$filter = new filter($this->db, $this->output);
$filter->to_output("requests");
if (($origins = $this->model->get_origins($filter->hostname, $filter->webserver)) === false) {
$this->output->add_tag("result", "Database error.\n");
return;
}
$max = 0;
foreach ($origins as $origin) {
if ($origin["count"] > $max) {
$max = $origin["count"];
}
}
$this->output->open_tag("origins", array("max" => $max));
foreach ($origins as $origin) {
$count = $max == 0 ? 0 : (int)(PIXELS * $origin["count"] / $max);
if ($count < $this->settings->origins_min_count) {
continue;
}
$this->output->add_tag("origin", $origin["country"], array("count" => $count));
}
$this->output->close_tag();
}
}
?>
<?php
define("PIXELS", 680);
class pages_controller extends controller {
private $skip_urls = array("/robots.txt", "/logout");
private $skip_extensions = array("css", "gif", "ico", "jpg", "js", "png", "ttf");
private function skip_url($url) {
if (substr($url, 0, 6) == "/admin") {
return true;
}
if (in_array($url, $this->skip_urls)) {
return true;
}
$parts = explode(".", $url);
$extension = array_pop($parts);
if (in_array($extension, $this->skip_extensions)) {
return true;
}
return false;
}
public function execute() {
$filter = new filter($this->db, $this->output);
$filter->to_output("requests");
if (($pages = $this->model->get_pages($filter->hostname, $filter->webserver)) === false) {
$this->output->add_tag("result", "Database error.\n");
return;
}
$max = 0;
foreach ($pages as $i => $page) {
if ($this->skip_url($page["request_uri"])) {
unset($pages[$i]);
} else if ($page["count"] > $max) {
$max = $page["count"];
}
}
$this->output->open_tag("pages", array("max" => $max));
foreach ($pages as $page) {
$count = $max == 0 ? 0 : (int)(PIXELS * $page["count"] / $max);
if ($count < $this->settings->pages_min_count) {
continue;
}
$this->output->add_tag("page", $page["request_uri"], array("count" => $count));
}
$this->output->close_tag();
}
}
?>
......@@ -7,6 +7,7 @@
$this->output->open_tag("edit");
$this->output->add_tag("email", $profile["email"]);
$this->output->add_tag("prowl_key", $profile["prowl_key"]);
if ($this->user->status == USER_STATUS_CHANGEPWD) {
$this->output->add_tag("cancel", "Logout", array("page" => LOGOUT_MODULE));
}
......@@ -41,7 +42,9 @@
$this->user->log_action("profile updated");
}
} else {
$user = array("email" => $this->user->email);
$user = array(
"email" => $this->user->email,
"prowl_key" => $this->user->prowl_key);
$this->show_profile_form($user);
}
}
......
<?php
class referers_controller extends controller {
public function execute() {
$this->output->add_javascript("jquery/jquery.js");
$filter = new filter($this->db, $this->output);
$filter->to_output("requests");
if (($referers = $this->model->get_referers($filter->hostname, $filter->webserver)) === false) {
$this->output->add_tag("result", "Database error.");
return;
}
$this->output->open_tag("referers");
foreach ($referers["hostnames"] as $hostname => $count) {
$to_output = false;
foreach ($referers["referers"][$hostname] as $referer) {
if ($referer["count"] < $this->settings->referer_min_count) {
continue;
}
if ($to_output == false) {
$this->output->open_tag("hostname", array("name" => $hostname, "count" => $count));
$to_output = true;
}
$this->output->add_tag("referer", $referer["referer"], array("count" => $referer["count"]));
}
if ($to_output) {
$this->output->close_tag();
}
}
$this->output->close_tag();
}
}
?>
<?php
class request_statistics_controller extends graph_controller {
protected $graphs = array(
"requests" => "Requests",
"bytes_sent" => "Bytes sent",
"result_forbidden" => "Result: 403 Forbidden",
"result_not_found" => "Result: 404 Not Found",
"result_internal_error" => "Result: 500 Internal Server Error");
}
?>
<?php
class security_statistics_controller extends graph_controller {
protected $graphs = array(
"bans" => "Clients banned",
"exploit_attempts" => "Exploit attempts");
}
?>
<?php
define("PIXELS", 730);
class web_browser_controller extends controller {
public function execute() {
$filter = new filter($this->db, $this->output);
$filter->to_output("requests", true);
if (($info = $this->model->get_information($filter->hostname, $filter->webserver)) === false) {
$this->output->add_tag("result", "Database error.");
return;
}
if ($filter->browser_version == false) {
$info = $this->model->remove_browser_version($info);
}
$max = 0;
foreach ($info as $browser) {
if ($browser["count"] > $max) {
$max = $browser["count"];
}
}
$this->output->add_tag("max", $max);
/* Browsers
*/
$this->output->open_tag("info");
foreach ($info as $browser) {
$count = $max == 0 ? 0 : (int)(PIXELS * $browser["count"] / $max);
$this->output->add_tag("item", $browser["browser"], array("count" => $count));
}
$this->output->close_tag();
}
}
?>
......@@ -12,9 +12,8 @@
exit("Internal error: database not available.\n");
}
$tables = array("host_statistics", "server_statistics", "requests",
"user_agents", "user_agent_browser", "user_agent_os",
"events", "hostnames", "referers", "request_uris", "webservers");
$tables = array("host_statistics", "cgi_statistics",
"server_statistics" "events", "hostnames", "webservers");
foreach ($tables as $table) {
$query = "truncate table %S";
$db->query($query, $table);
......
......@@ -28,95 +28,31 @@
*/
$query = "delete from host_statistics where timestamp_end<%s";
if ($db->query($query, $date) == false) {
exit("Error deleting server statistics.\n");
exit("Error deleting host statistics.\n");
}
/* Requests
/* CGI statistics
*/
$query = "delete from requests where timestamp<%s";
$query = "delete from cgi_statistics where timestamp_end<%s";
if ($db->query($query, $date) == false) {
exit("Error deleting server statistics.\n");
exit("Error deleting CGI statistics.\n");
}
/* Unsed hostnames
*/
$query = "select id from hostnames h where (select count(*) from host_statistics where hostname_id=h.id)=0";
if (($ids1 = $db->execute($query)) === false) {
$query = "select id from hostnames h where ".
"(select count(*) from host_statistics where hostname_id=h.id)=0 and ".
"(select count(*) from cgi_statistics where hostname_id=h.id)=0";
if (($ids = $db->execute($query)) === false) {
exit("Error deleting unused hostnames.\n");
}
$query = "select id from hostnames h where (select count(*) from requests where hostname_id=h.id)=0";
if (($ids2 = $db->execute($query)) === false) {
exit("Error deleting unused hostnames.\n");
}
if (($count = count($ids) > 0)) {
$params = implode(", ", array_fill(0, $count, "%d"));
if (($c1 = count($ids1) > 0) && (($c2 = count($ids2)) > 0)) {
$params1 = implode(", ", array_fill(0, $c1, "%d"));
$params2 = implode(", ", array_fill(0, $c2, "%d"));
$query = "delete from hostnames where id in (".$params1.") and id in (".$params2.")";
unset($params1);
unset($params2);
if ($db->query($query, $ids1, $ids2) == false) {
$query = "delete from hostnames where id in (".$params.")";
if ($db->query($query, $ids) == false) {
exit("Error deleting unused hostnames.\n");
}
}
unset($ids1);
unset($ids2);
/* Delete unused records
*/
function delete_unused_records($db, $table, $ref_table, $ref_column) {
$query = "select id from %S t where (select count(*) from %S where %S=t.id)=0";
if (($resource = $db->query($query, $table, $ref_table, $ref_column)) === false) {
return false;
}
do {
$ids = array();
$count = 0;
while (($id = $db->fetch($resource)) !== false) {
array_push($ids, $id);
if (++$count == 1000) {
break;
}
}
if ($count == 0) {
break;
}
$query = "delete from %S where id in (".implode(", ", array_fill(0, $count, "%d")).")";
if ($db->query($query, $table, $ids) == false) {
return false;
}
} while ($id !== false);
return true;
}
/* Unused request URIs
*/
if (delete_unused_records(