From 30b85f58db091d30ae5ac60b0f9422e05a04c018 Mon Sep 17 00:00:00 2001 From: Shish Date: Thu, 28 Nov 2019 21:32:18 +0000 Subject: [PATCH] anon-ghost mode, and ghosts can't sign up for accounts --- composer.lock | 8 +-- core/permissions.php | 1 + core/userclass.php | 2 + ext/ipban/main.php | 142 +++++++++++++++++++++++-------------------- ext/user/main.php | 7 ++- ext/user/theme.php | 4 +- 6 files changed, 92 insertions(+), 72 deletions(-) diff --git a/composer.lock b/composer.lock index 12147aae..b78c7273 100644 --- a/composer.lock +++ b/composer.lock @@ -388,12 +388,12 @@ "source": { "type": "git", "url": "https://github.com/shish/microcrud.git", - "reference": "6471a4c7445e872282f12d1de3730db55d5c06e2" + "reference": "7c917baa46f137c5e0f6bd4d9874b1c61014797e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/shish/microcrud/zipball/6471a4c7445e872282f12d1de3730db55d5c06e2", - "reference": "6471a4c7445e872282f12d1de3730db55d5c06e2", + "url": "https://api.github.com/repos/shish/microcrud/zipball/7c917baa46f137c5e0f6bd4d9874b1c61014797e", + "reference": "7c917baa46f137c5e0f6bd4d9874b1c61014797e", "shasum": "" }, "require": { @@ -429,7 +429,7 @@ "crud", "generator" ], - "time": "2019-11-28T15:53:53+00:00" + "time": "2019-11-28T21:02:52+00:00" }, { "name": "shish/microhtml", diff --git a/core/permissions.php b/core/permissions.php index 84eb292e..a2eb842b 100644 --- a/core/permissions.php +++ b/core/permissions.php @@ -13,6 +13,7 @@ abstract class Permissions public const VIEW_IP = "view_ip"; # view IP addresses associated with things public const BAN_IP = "ban_ip"; + public const CREATE_USER = "create_user"; public const EDIT_USER_NAME = "edit_user_name"; public const EDIT_USER_PASSWORD = "edit_user_password"; public const EDIT_USER_INFO = "edit_user_info"; # email address, etc diff --git a/core/userclass.php b/core/userclass.php index e639167d..faf41bbe 100644 --- a/core/userclass.php +++ b/core/userclass.php @@ -83,6 +83,7 @@ new UserClass("base", null, [ Permissions::VIEW_IP => false, # view IP addresses associated with things Permissions::BAN_IP => false, + Permissions::CREATE_USER => false, Permissions::EDIT_USER_NAME => false, Permissions::EDIT_USER_PASSWORD => false, Permissions::EDIT_USER_INFO => false, # email address, etc @@ -163,6 +164,7 @@ new UserClass("ghost", "base", [ // Anonymous users can't do anything by default, but // the admin might grant them some permissions new UserClass("anonymous", "base", [ + Permissions::CREATE_USER => true, ]); new UserClass("user", "base", [ diff --git a/ext/ipban/main.php b/ext/ipban/main.php index 3f995e41..a000aa2c 100644 --- a/ext/ipban/main.php +++ b/ext/ipban/main.php @@ -21,10 +21,16 @@ class IPBanTable extends Table ) AS tbl1 "; - $this->size = 10; + $this->size = 100; + $this->limit = 1000000; $this->columns = [ new InetColumn("ip", "IP"), - new EnumColumn("mode", "Mode", ["Block"=>"block", "Firewall"=>"firewall", "Ghost"=>"ghost"]), + new EnumColumn("mode", "Mode", [ + "Block"=>"block", + "Firewall"=>"firewall", + "Ghost"=>"ghost", + "Anon Ghost"=>"anon-ghost" + ]), new TextColumn("reason", "Reason"), new StringColumn("banner", "Banner"), new DateColumn("added", "Added"), @@ -37,7 +43,7 @@ class IPBanTable extends Table $this->create_url = make_link("ip_ban/create"); $this->delete_url = make_link("ip_ban/delete"); - $this->table_attrs = ["class" => "sortable zebra"]; + $this->table_attrs = ["class" => "zebra"]; } } @@ -90,95 +96,101 @@ class IPBan extends Extension { global $cache, $config, $database, $page, $user, $_shm_user_classes; - // Get lists of banned IPs and banned networks + // Get lists of banned IPs and banned networks $ips = $cache->get("ip_bans"); $networks = $cache->get("network_bans"); if ($ips === false || $networks === false) { - $rows = $database->get_pairs(" + $rows = $database->get_pairs(" SELECT ip, id FROM bans WHERE ((expires > CURRENT_TIMESTAMP) OR (expires IS NULL)) "); - $ips = []; # "0.0.0.0" => 123; - $networks = []; # "0.0.0.0/32" => 456; - foreach ($rows as $ip => $id) { - if (strstr($ip, '/')) { - $networks[$ip] = $id; - } else { - $ips[$ip] = $id; - } - } + $ips = []; # "0.0.0.0" => 123; + $networks = []; # "0.0.0.0/32" => 456; + foreach ($rows as $ip => $id) { + if (strstr($ip, '/')) { + $networks[$ip] = $id; + } else { + $ips[$ip] = $id; + } + } - $cache->set("ip_bans", $ips, 600); - $cache->set("network_bans", $networks, 600); + $cache->set("ip_bans", $ips, 600); + $cache->set("network_bans", $networks, 600); } - // Check if our current IP is in either of the ban lists + // Check if our current IP is in either of the ban lists $remote = $_SERVER['REMOTE_ADDR']; - $active_ban_id = null; + $active_ban_id = null; if (isset($ips[$remote])) { $active_ban_id = $ips[$remote]; + } else { + foreach ($networks as $range => $ban_id) { + if (ip_in_range($remote, $range)) { + $active_ban_id = $ban_id; + } + } } - else { - foreach ($networks as $range => $ban_id) { - if (ip_in_range($remote, $range)) { - $active_ban_id = $ban_id; - } - } - } - // If an active ban is found, act on it - if(!is_null($active_ban_id)) { - $row = $database->get_row("SELECT * FROM bans WHERE id=:id", ["id"=>$active_ban_id]); + // If an active ban is found, act on it + if (!is_null($active_ban_id)) { + $row = $database->get_row("SELECT * FROM bans WHERE id=:id", ["id"=>$active_ban_id]); - $msg = $config->get_string("ipban_message"); - $msg = str_replace('$IP', $row["ip"], $msg); - $msg = str_replace('$DATE', $row['expires'], $msg); - $msg = str_replace('$ADMIN', User::by_id($row['banner_id'])->name, $msg); - $msg = str_replace('$REASON', $row['reason'], $msg); - $contact_link = contact_link(); - if (!empty($contact_link)) { - $msg = str_replace('$CONTACT', "Contact the staff (be sure to include this message)", $msg); - } else { - $msg = str_replace('$CONTACT', "", $msg); - } + $msg = $config->get_string("ipban_message"); + $msg = str_replace('$IP', $row["ip"], $msg); + $msg = str_replace('$DATE', $row['expires'], $msg); + $msg = str_replace('$ADMIN', User::by_id($row['banner_id'])->name, $msg); + $msg = str_replace('$REASON', $row['reason'], $msg); + $contact_link = contact_link(); + if (!empty($contact_link)) { + $msg = str_replace('$CONTACT', "Contact the staff (be sure to include this message)", $msg); + } else { + $msg = str_replace('$CONTACT', "", $msg); + } - if($row["mode"] == "ghost") { - $b = new Block(null, $msg, "main", 0); - $b->is_content = false; - $page->add_block($b); - $event->user->class = $_shm_user_classes["ghost"]; - } else { - header("HTTP/1.0 403 Forbidden"); - print "$msg"; - exit; - } - } + if ($row["mode"] == "ghost") { + $b = new Block(null, $msg, "main", 0); + $b->is_content = false; + $page->add_block($b); + $event->user->class = $_shm_user_classes["ghost"]; + } elseif ($row["mode"] == "anon-ghost") { + if ($event->user->is_anonymous()) { + $b = new Block(null, $msg, "main", 0); + $b->is_content = false; + $page->add_block($b); + $event->user->class = $_shm_user_classes["ghost"]; + } + } else { + header("HTTP/1.0 403 Forbidden"); + print "$msg"; + exit; + } + } } public function onPageRequest(PageRequestEvent $event) { if ($event->page_matches("ip_ban")) { - global $database, $page, $user; + global $database, $page, $user; if ($user->can(Permissions::BAN_IP)) { if ($event->get_arg(0) == "create") { - $user->ensure_authed(); - $input = validate_input(["c_ip"=>"string", "c_mode"=>"string", "c_reason"=>"string", "c_expires"=>"optional,date"]); - send_event(new AddIPBanEvent($input['c_ip'], $input['c_mode'], $input['c_reason'], $input['c_expires'])); - flash_message("Ban for {$input['c_ip']} added"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("ip_ban/list")); + $user->ensure_authed(); + $input = validate_input(["c_ip"=>"string", "c_mode"=>"string", "c_reason"=>"string", "c_expires"=>"optional,date"]); + send_event(new AddIPBanEvent($input['c_ip'], $input['c_mode'], $input['c_reason'], $input['c_expires'])); + flash_message("Ban for {$input['c_ip']} added"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("ip_ban/list")); } elseif ($event->get_arg(0) == "delete") { - $user->ensure_authed(); - $input = validate_input(["d_id"=>"int"]); - send_event(new RemoveIPBanEvent($input['d_id'])); - flash_message("Ban removed"); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("ip_ban/list")); + $user->ensure_authed(); + $input = validate_input(["d_id"=>"int"]); + send_event(new RemoveIPBanEvent($input['d_id'])); + flash_message("Ban removed"); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("ip_ban/list")); } elseif ($event->get_arg(0) == "list") { - $_GET['c_banner'] = $user->name; - $_GET['c_added'] = date('Y-m-d'); + $_GET['c_banner'] = $user->name; + $_GET['c_added'] = date('Y-m-d'); $t = new IPBanTable($database->raw_db()); $t->token = $user->get_auth_token(); $t->inputs = $_GET; diff --git a/ext/user/main.php b/ext/user/main.php index 9ac332e9..78e6e84e 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -397,7 +397,12 @@ class UserPage extends Extension private function page_create() { - global $config, $page; + global $config, $page, $user; + if ($user->can(Permissions::CREATE_USER)) { + $this->theme->display_error(403, "Account creation blocked", "Account creation is currently disabled"); + return; + } + if (!$config->get_bool("login_signup_enabled")) { $this->theme->display_signups_disabled($page); } elseif (!isset($_POST['name'])) { diff --git a/ext/user/theme.php b/ext/user/theme.php index 3c41641d..b17ea247 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -167,7 +167,7 @@ class UserPageTheme extends Themelet public function display_login_block(Page $page) { - global $config; + global $config, $user; $html = ' '.make_form(make_link("user_admin/login"))." @@ -187,7 +187,7 @@ class UserPageTheme extends Themelet
"; - if ($config->get_bool("login_signup_enabled")) { + if ($config->get_bool("login_signup_enabled") && $user->can(Permissions::CREATE_USER)) { $html .= "Create Account"; } $page->add_block(new Block("Login", $html, "left", 90));